Update onboard-nodes.yml to target physical_servers and add ai-p410 to hosts.ini so onboarding limits no longer skip that host.

This commit is contained in:
Nathan 2026-04-21 11:44:00 -04:00
parent 92c8125981
commit 9a749a8c97
19 changed files with 3 additions and 810 deletions

View File

@ -1,42 +0,0 @@
---
# Proxmox API settings (credentials come from vault variables)
openapply_pve_api_host: "{{ vault_proxmox_api_host | default('10.0.0.201') }}"
openapply_pve_api_user: "{{ vault_proxmox_api_user | default('root@pam') }}"
openapply_pve_api_token_id: "{{ vault_proxmox_api_token_id | default('automation', true) }}"
openapply_pve_api_token_secret: "{{ vault_proxmox_api_token_secret | default('') }}"
openapply_proxmox_validate_certs: false
# Proxmox target and LXC specification
openapply_pve_node: pve01
openapply_lxc_vmid: 105
openapply_lxc_hostname: openapply-prod
openapply_lxc_template: local:vztmpl/ubuntu-24.04-standard_24.04-2_amd64.tar.zst
openapply_lxc_storage: local-lvm
openapply_lxc_cores: 2
openapply_lxc_memory_mb: 4096
openapply_lxc_swap_mb: 512
openapply_lxc_unprivileged: true
openapply_lxc_onboot: true
openapply_lxc_features:
- nesting=1
# LXC networking
openapply_lxc_bridge: vmbr0
openapply_lxc_ip_cidr: 10.0.0.105/24
openapply_lxc_gateway: 10.0.0.2
openapply_lxc_management_ip: 10.0.0.105
openapply_lxc_ssh_user: root
openapply_lxc_ssh_port: 22
openapply_lxc_nic_firewall: true
openapply_use_proxmox_nic: false
# LXC credentials (from vault)
openapply_lxc_password: "{{ vault_openapply_lxc_root_password | default(vault_proxmox_root_password | default('')) }}"
# Controller runtime preflight
openapply_validate_controller_python_deps: true
# Application runtime toggles for first deployment
openapply_app_install_firebase_cli: false
openapply_app_repo_version: master
openapply_app_force_rebuild: true

View File

@ -31,6 +31,7 @@ pve01 ansible_host=10.0.0.201 ansible_user=root
[physical_servers] [physical_servers]
heimdall ansible_host=10.0.0.151 ansible_user=chester heimdall ansible_host=10.0.0.151 ansible_user=chester
waldorf ansible_host=10.0.0.251 ansible_user=chester waldorf ansible_host=10.0.0.251 ansible_user=chester
ai-p410 ansible_host=10.0.0.202 ansible_user=chester
[raspberry_pi] [raspberry_pi]
watchtower ansible_host=10.0.0.200 ansible_user=chester watchtower ansible_host=10.0.0.200 ansible_user=chester
@ -41,6 +42,7 @@ watchtower ansible_host=10.0.0.200 ansible_user=chester
[nfs_clients] [nfs_clients]
heimdall ansible_host=10.0.0.151 ansible_user=chester heimdall ansible_host=10.0.0.151 ansible_user=chester
waldorf ansible_host=10.0.0.251 ansible_user=chester waldorf ansible_host=10.0.0.251 ansible_user=chester
ai-p410 ansible_host=10.0.0.202 ansible_user=chester
# ============================================================================= # =============================================================================
# Group Variables # Group Variables

View File

@ -1,128 +0,0 @@
# OpenApply Deployment - Vault Variables Reference
This document lists the encrypted variables that must be configured in `ansible/group_vars/all/vault.yml` before deploying OpenApply.
## Required Vault Variables
### Proxmox API Authentication
```yaml
# Proxmox API endpoint
vault_proxmox_api_host: "10.0.0.201"
# Proxmox API user (typically root@pam)
vault_proxmox_api_user: "root@pam"
# Proxmox API token ID
vault_proxmox_api_token_id: "automation"
# Proxmox API token secret (encrypted)
vault_proxmox_api_token_secret: !vault |
$ANSIBLE_VAULT;1.1;AES256
[encrypted token here]
```
### LXC Container Credentials
```yaml
# Root password for the OpenApply LXC container (encrypted)
vault_openapply_lxc_root_password: !vault |
$ANSIBLE_VAULT;1.1;AES256
[encrypted password here]
```
### Application Secrets (Optional)
```yaml
# Firebase deployment token (optional, encrypted)
vault_openapply_firebase_token: !vault |
$ANSIBLE_VAULT;1.1;AES256
[encrypted token here]
```
### SPA Firebase Configuration (Required for non-blank /app UI)
```yaml
# Public Firebase client config used at SPA build-time
vault_openapply_firebase_api_key: "AIza..."
vault_openapply_firebase_auth_domain: "your-project.firebaseapp.com"
vault_openapply_firebase_project_id: "your-project-id"
vault_openapply_firebase_storage_bucket: "your-project.appspot.com"
vault_openapply_firebase_messaging_sender_id: "1234567890"
vault_openapply_firebase_app_id: "1:1234567890:web:abcdef123456"
# Optional UX/admin metadata
vault_openapply_admin_email: "admin@your-domain.tld"
vault_openapply_support_email: "support@your-domain.tld"
```
## Creating/Editing Vault Variables
### First-time Setup
```bash
# Navigate to ansible directory
cd /home/chester/homelab/ansible
# Edit the encrypted vault file
ansible-vault edit group_vars/all/vault.yml
# Add the variables listed above
```
### Generating a Proxmox API Token
1. Log into Proxmox web UI (https://pve01:8006)
2. Navigate to: Datacenter → Permissions → API Tokens
3. Click "Add" button
4. User: `root@pam`
5. Token ID: `automation` (or custom name)
6. Privilege Separation: **Unchecked** (for full root@pam permissions)
7. Click "Add"
8. **Copy the secret immediately** (only shown once)
9. Add to vault file as shown above
### Required Permissions
If using privilege separation, the token needs:
- `VM.Allocate` - Create new containers
- `VM.Config.Network` - Configure networking
- `VM.PowerMgmt` - Start/stop containers
- `Datastore.AllocateSpace` - Allocate storage
### Security Best Practices
1. **Never commit unencrypted secrets** to Git
2. Rotate API tokens quarterly
3. Use separate tokens for different automation workflows
4. Audit Proxmox API access logs regularly
5. Verify vault encryption: `ansible-vault view group_vars/all/vault.yml`
## Validation
Test that vault variables are correctly configured:
```bash
# Verify vault can be decrypted
ansible-vault view group_vars/all/vault.yml
# Test variable resolution (without execution)
ansible-playbook playbooks/deploy-openapply.yml --check --diff
```
## Troubleshooting
### "vault_proxmox_api_token_secret is undefined"
Ensure the variable is present in `group_vars/all/vault.yml` and the file is properly encrypted.
### "Authentication failed"
1. Verify token ID matches Proxmox configuration
2. Confirm token is not expired
3. Check privilege separation settings
4. Regenerate token if necessary
### "Cannot decrypt vault"
Ensure `ansible/vault/.vault_pass` contains the correct vault password.

View File

@ -1,126 +0,0 @@
---
- name: Provision OpenApply LXC on Proxmox
hosts: localhost
gather_facts: false
connection: local
become: false
pre_tasks:
- name: Validate required infrastructure variables
ansible.builtin.assert:
that:
- openapply_pve_api_host | length > 0
- openapply_pve_api_user | length > 0
- openapply_pve_api_token_id | length > 0
- openapply_pve_api_token_secret | length > 0
- openapply_pve_node | length > 0
- openapply_lxc_vmid | int > 0
- openapply_lxc_hostname | length > 0
- openapply_lxc_template | length > 0
- openapply_lxc_storage | length > 0
- openapply_lxc_ip_cidr | length > 0
- openapply_lxc_gateway | length > 0
- openapply_lxc_management_ip | length > 0
- openapply_lxc_password | length > 0
fail_msg: >-
Required Proxmox/OpenApply LXC variables are missing. Check
group_vars/all/openapply.yml and vault variables.
- name: Validate Proxmox Python dependencies on controller
ansible.builtin.command: "{{ ansible_playbook_python }} -c 'import proxmoxer, requests'"
register: openapply_controller_python_deps
changed_when: false
failed_when: openapply_controller_python_deps.rc != 0
become: false
when: openapply_validate_controller_python_deps | bool
tasks:
- name: Ensure OpenApply LXC is present
community.proxmox.proxmox:
api_host: "{{ openapply_pve_api_host }}"
api_user: "{{ openapply_pve_api_user }}"
api_token_id: "{{ openapply_pve_api_token_id }}"
api_token_secret: "{{ openapply_pve_api_token_secret }}"
validate_certs: "{{ openapply_proxmox_validate_certs }}"
node: "{{ openapply_pve_node }}"
vmid: "{{ openapply_lxc_vmid }}"
hostname: "{{ openapply_lxc_hostname }}"
ostemplate: "{{ openapply_lxc_template }}"
storage: "{{ openapply_lxc_storage }}"
cores: "{{ openapply_lxc_cores }}"
memory: "{{ openapply_lxc_memory_mb }}"
swap: "{{ openapply_lxc_swap_mb }}"
password: "{{ openapply_lxc_password }}"
onboot: "{{ openapply_lxc_onboot }}"
unprivileged: "{{ openapply_lxc_unprivileged }}"
netif:
net0: "name=eth0,bridge={{ openapply_lxc_bridge }},ip={{ openapply_lxc_ip_cidr }},gw={{ openapply_lxc_gateway }}"
features: "{{ openapply_lxc_features }}"
state: present
register: openapply_lxc_status
- name: Ensure OpenApply LXC is started
community.proxmox.proxmox:
api_host: "{{ openapply_pve_api_host }}"
api_user: "{{ openapply_pve_api_user }}"
api_token_id: "{{ openapply_pve_api_token_id }}"
api_token_secret: "{{ openapply_pve_api_token_secret }}"
validate_certs: "{{ openapply_proxmox_validate_certs }}"
node: "{{ openapply_pve_node }}"
vmid: "{{ openapply_lxc_vmid }}"
state: started
- name: Reconcile LXC NIC configuration via Proxmox API
when: openapply_use_proxmox_nic | bool
block:
- name: Ensure net0 configuration through proxmox_nic
community.proxmox.proxmox_nic:
api_host: "{{ openapply_pve_api_host }}"
api_user: "{{ openapply_pve_api_user }}"
api_token_id: "{{ openapply_pve_api_token_id }}"
api_token_secret: "{{ openapply_pve_api_token_secret }}"
validate_certs: "{{ openapply_proxmox_validate_certs }}"
vmid: "{{ openapply_lxc_vmid }}"
name: "{{ openapply_lxc_hostname }}"
interface: net0
bridge: "{{ openapply_lxc_bridge }}"
firewall: "{{ openapply_lxc_nic_firewall }}"
state: present
rescue:
- name: Continue when proxmox_nic is unsupported for this target
ansible.builtin.debug:
msg: >-
proxmox_nic could not be applied to vmid {{ openapply_lxc_vmid }};
continuing with proxmox container network configuration only.
- name: Add OpenApply LXC to runtime inventory
ansible.builtin.add_host:
name: "{{ openapply_lxc_hostname }}"
ansible_host: "{{ openapply_lxc_management_ip }}"
ansible_user: "{{ openapply_lxc_ssh_user }}"
ansible_port: "{{ openapply_lxc_ssh_port }}"
ansible_password: "{{ openapply_lxc_password }}"
ansible_ssh_pass: "{{ openapply_lxc_password }}"
ansible_python_interpreter: /usr/bin/python3
groups: lxc_guests
- name: Display provisioning summary
ansible.builtin.debug:
msg:
- "LXC hostname: {{ openapply_lxc_hostname }}"
- "LXC management IP: {{ openapply_lxc_management_ip }}"
- "LXC vmid: {{ openapply_lxc_vmid }}"
- "LXC changed: {{ openapply_lxc_status.changed | default(false) }}"
- name: Configure OpenApply application inside guest
hosts: lxc_guests
gather_facts: true
become: true
pre_tasks:
- name: Wait for SSH connectivity to LXC guest
ansible.builtin.wait_for_connection:
timeout: 300
roles:
- role: openapply_app

View File

@ -5,7 +5,7 @@
# (-k prompts for SSH password, -K prompts for sudo password) # (-k prompts for SSH password, -K prompts for sudo password)
- name: Onboard new nodes to Ansible control - name: Onboard new nodes to Ansible control
hosts: heimdall,waldorf hosts: physical_servers
gather_facts: true gather_facts: true
become: false become: false
tasks: tasks:

View File

@ -1,98 +0,0 @@
# openapply_app
Ansible role to deploy the OpenApply application stack (Vue.js/Astro/Firebase) to an Ubuntu LXC guest.
## Description
This role configures an Ubuntu 22.04/24.04 LXC container to run the OpenApply web application in production mode. It handles:
- Node.js 20+ runtime installation via NodeSource
- pnpm package manager setup
- Firebase CLI installation (optional)
- UFW firewall configuration (production ports only: 22, 80, 443)
- Git-based source deployment
- Systemd service configuration and lifecycle management
- Application build process for Astro and SPA components
- HTTP health validation
## Requirements
- Target OS: Ubuntu 22.04 (Jammy) or 24.04 (Noble)
- Minimum Ansible: 2.16
- Collections:
- `community.general >= 8.0.0`
- `ansible.posix >= 1.5.0`
## Role Variables
### Application Settings
| Variable | Default | Description |
|----------|---------|-------------|
| `openapply_app_repo_url` | `https://github.com/sergeykhval/openapply.git` | Git repository URL |
| `openapply_app_repo_version` | `main` | Git branch/tag/commit |
| `openapply_app_root` | `/opt/openapply` | Application install path |
| `openapply_app_service_name` | `openapply` | Systemd service name |
| `openapply_app_service_user` | `openapply` | Service runtime user |
| `openapply_app_service_group` | `openapply` | Service runtime group |
| `openapply_app_service_port` | `80` | HTTP listen port |
### Runtime Configuration
| Variable | Default | Description |
|----------|---------|-------------|
| `openapply_app_node_major` | `"20"` | Node.js major version |
| `openapply_app_install_firebase_cli` | `true` | Install Firebase CLI globally |
| `openapply_app_build_subdirs` | `["astro", "spa"]` | Subdirectories to build |
| `openapply_app_force_rebuild` | `false` | Force rebuild on every run |
### Network & Security
| Variable | Default | Description |
|----------|---------|-------------|
| `openapply_app_enable_firewall` | `true` | Enable UFW firewall |
| `openapply_app_allowed_tcp_ports` | `[22, 80, 443]` | Allowed TCP ports |
### Secrets
| Variable | Default | Description |
|----------|---------|-------------|
| `openapply_app_firebase_token` | `{{ vault_openapply_firebase_token \| default('') }}` | Firebase deployment token |
## Dependencies
None.
## Example Playbook
```yaml
- name: Deploy OpenApply application
hosts: openapply_lxc_guest
become: true
roles:
- role: openapply_app
vars:
openapply_app_repo_version: "v1.2.3"
openapply_app_service_port: 8080
```
## Example with Proxmox Provisioning
See `playbooks/deploy-openapply.yml` for a complete two-tier workflow that:
1. Provisions an LXC container on Proxmox
2. Deploys and configures OpenApply inside the guest
## License
MIT
## Author
Created by FrankGPT for the homelab infrastructure automation project.
## Notes
- **Production-only mode**: Dev ports (3000, 5173) are not exposed by default
- **Git clone strategy**: Application code is cloned fresh on first run, then updated on subsequent runs
- **Build idempotency**: Builds are triggered only when repo changes or `openapply_app_force_rebuild` is set
- **Systemd lifecycle**: Service is managed via systemd with automatic restart on failure

View File

@ -1,52 +0,0 @@
---
openapply_app_repo_url: https://github.com/sergeykhval/openapply.git
openapply_app_repo_version: main
openapply_app_service_name: openapply
openapply_app_service_user: openapply
openapply_app_service_group: openapply
openapply_app_root: /opt/openapply
openapply_app_service_port: 80
openapply_app_node_major: "20"
openapply_app_install_firebase_cli: true
openapply_app_enable_firewall: true
openapply_app_allowed_tcp_ports:
- 22
- 80
- 443
openapply_app_build_subdirs:
- astro
- spa
openapply_app_force_rebuild: false
openapply_app_git_ssh_key_file: ""
openapply_app_start_command: >-
pnpm --dir {{ openapply_app_root }}/astro preview --host 0.0.0.0 --port {{ openapply_app_service_port }}
openapply_app_env:
NODE_ENV: production
PORT: "{{ openapply_app_service_port }}"
openapply_app_spa_env:
VITE_BASE_URL: /app
VITE_FIREBASE_API_KEY: "{{ vault_openapply_firebase_api_key | default('your-firebase-api-key') }}"
VITE_FIREBASE_AUTH_DOMAIN: "{{ vault_openapply_firebase_auth_domain | default('your-project.firebaseapp.com') }}"
VITE_FIREBASE_PROJECT_ID: "{{ vault_openapply_firebase_project_id | default('your-project-id') }}"
VITE_FIREBASE_STORAGE_BUCKET: "{{ vault_openapply_firebase_storage_bucket | default('your-project.appspot.com') }}"
VITE_FIREBASE_MESSAGING_SENDER_ID: "{{ vault_openapply_firebase_messaging_sender_id | default('your-sender-id') }}"
VITE_FIREBASE_APP_ID: "{{ vault_openapply_firebase_app_id | default('your-app-id') }}"
VITE_ADMIN_EMAIL: "{{ vault_openapply_admin_email | default('admin@example.com') }}"
VITE_SUPPORT_EMAIL: "{{ vault_openapply_support_email | default('support@example.com') }}"
openapply_app_require_real_firebase_config: true
openapply_app_firebase_token: "{{ vault_openapply_firebase_token | default('') }}"
openapply_app_verify_status_codes:
- 200
- 301
- 302

View File

@ -1,9 +0,0 @@
---
- name: Reload systemd
ansible.builtin.systemd:
daemon_reload: true
- name: Restart OpenApply service
ansible.builtin.systemd:
name: "{{ openapply_app_service_name }}"
state: restarted

View File

@ -1,27 +0,0 @@
---
galaxy_info:
role_name: openapply_app
namespace: homelab
author: FrankGPT
description: Deploy OpenApply application stack (Vue/Astro/Firebase) to Ubuntu LXC guest
license: MIT
min_ansible_version: "2.16"
platforms:
- name: Ubuntu
versions:
- jammy
- noble
galaxy_tags:
- web
- nodejs
- application
- deployment
- lxc
dependencies: []
collections:
- community.general
- ansible.posix

View File

@ -1,148 +0,0 @@
---
- name: Ensure OpenApply group exists
ansible.builtin.group:
name: "{{ openapply_app_service_group }}"
state: present
- name: Ensure OpenApply service user exists
ansible.builtin.user:
name: "{{ openapply_app_service_user }}"
group: "{{ openapply_app_service_group }}"
home: /home/{{ openapply_app_service_user }}
shell: /usr/sbin/nologin
create_home: true
system: true
state: present
- name: Ensure OpenApply root directory exists
ansible.builtin.file:
path: "{{ openapply_app_root }}"
state: directory
owner: "{{ openapply_app_service_user }}"
group: "{{ openapply_app_service_group }}"
mode: "0755"
- name: Check whether OpenApply directory is already a git repository
ansible.builtin.stat:
path: "{{ openapply_app_root }}/.git"
register: openapply_git_metadata
- name: Reset OpenApply directory when not a git repository
ansible.builtin.file:
path: "{{ openapply_app_root }}"
state: absent
when: not openapply_git_metadata.stat.exists
- name: Recreate OpenApply root directory after reset
ansible.builtin.file:
path: "{{ openapply_app_root }}"
state: directory
owner: "{{ openapply_app_service_user }}"
group: "{{ openapply_app_service_group }}"
mode: "0755"
when: not openapply_git_metadata.stat.exists
- name: Sync OpenApply source code
ansible.builtin.git:
repo: "{{ openapply_app_repo_url }}"
version: "{{ openapply_app_repo_version }}"
dest: "{{ openapply_app_root }}"
update: true
force: true
accept_hostkey: true
key_file: "{{ openapply_app_git_ssh_key_file | default(omit, true) }}"
become: true
become_user: "{{ openapply_app_service_user }}"
register: openapply_repo_checkout
- name: Render OpenApply environment file
ansible.builtin.template:
src: openapply.env.j2
dest: "{{ openapply_app_root }}/.env"
owner: "{{ openapply_app_service_user }}"
group: "{{ openapply_app_service_group }}"
mode: "0640"
- name: Render OpenApply SPA build environment file
ansible.builtin.template:
src: openapply.spa.env.j2
dest: "{{ openapply_app_root }}/spa/.env"
owner: "{{ openapply_app_service_user }}"
group: "{{ openapply_app_service_group }}"
mode: "0640"
- name: Check node_modules presence
ansible.builtin.stat:
path: "{{ openapply_app_root }}/node_modules"
register: openapply_node_modules
- name: Install OpenApply dependencies via pnpm
ansible.builtin.command:
cmd: pnpm install --frozen-lockfile
chdir: "{{ openapply_app_root }}"
become: true
become_user: "{{ openapply_app_service_user }}"
when:
- openapply_repo_checkout.changed or openapply_app_force_rebuild | bool or not openapply_node_modules.stat.exists
changed_when: true
- name: Check which build directories exist
ansible.builtin.stat:
path: "{{ openapply_app_root }}/{{ item }}"
register: openapply_build_dir_stats
loop: "{{ openapply_app_build_subdirs }}"
- name: Build OpenApply subprojects
ansible.builtin.command:
cmd: pnpm run build
chdir: "{{ openapply_app_root }}/{{ item.item }}"
become: true
become_user: "{{ openapply_app_service_user }}"
loop: "{{ openapply_build_dir_stats.results }}"
when:
- item.stat.exists
- openapply_repo_checkout.changed or openapply_app_force_rebuild | bool
changed_when: true
- name: Check Astro dist directory
ansible.builtin.stat:
path: "{{ openapply_app_root }}/astro/dist"
register: openapply_astro_dist
- name: Check SPA dist directory
ansible.builtin.stat:
path: "{{ openapply_app_root }}/spa/dist"
register: openapply_spa_dist
- name: Publish SPA build under /app path for Astro runtime
ansible.builtin.shell: |
rm -rf "{{ openapply_app_root }}/astro/dist/app"
mkdir -p "{{ openapply_app_root }}/astro/dist/app"
cp -a "{{ openapply_app_root }}/spa/dist/." "{{ openapply_app_root }}/astro/dist/app/"
args:
executable: /bin/bash
become: true
become_user: "{{ openapply_app_service_user }}"
when:
- openapply_astro_dist.stat.isdir | default(false)
- openapply_spa_dist.stat.isdir | default(false)
- openapply_repo_checkout.changed or openapply_app_force_rebuild | bool
changed_when: true
- name: Install OpenApply systemd unit
ansible.builtin.template:
src: openapply.service.j2
dest: "/etc/systemd/system/{{ openapply_app_service_name }}.service"
owner: root
group: root
mode: "0644"
notify:
- Reload systemd
- Restart OpenApply service
- name: Ensure OpenApply service is enabled and started
ansible.builtin.systemd:
name: "{{ openapply_app_service_name }}"
enabled: true
state: started
daemon_reload: true

View File

@ -1,15 +0,0 @@
---
- name: Validate role input
ansible.builtin.import_tasks: validate.yml
- name: Install base prerequisites
ansible.builtin.import_tasks: prereqs.yml
- name: Configure runtime dependencies
ansible.builtin.import_tasks: setup_env.yml
- name: Deploy and build OpenApply
ansible.builtin.import_tasks: deploy_code.yml
- name: Verify running service
ansible.builtin.import_tasks: verify.yml

View File

@ -1,37 +0,0 @@
---
- name: Install OpenApply prerequisite packages
ansible.builtin.apt:
name:
- ca-certificates
- curl
- git
- gnupg
- ufw
- build-essential
state: present
update_cache: true
cache_valid_time: 3600
- name: Configure UFW for production web access
when: openapply_app_enable_firewall | bool
block:
- name: Set default incoming firewall policy
community.general.ufw:
direction: incoming
default: deny
- name: Set default outgoing firewall policy
community.general.ufw:
direction: outgoing
default: allow
- name: Allow required TCP ports
community.general.ufw:
rule: allow
port: "{{ item }}"
proto: tcp
loop: "{{ openapply_app_allowed_tcp_ports }}"
- name: Enable UFW
community.general.ufw:
state: enabled

View File

@ -1,42 +0,0 @@
---
- name: Ensure apt keyrings directory exists
ansible.builtin.file:
path: /etc/apt/keyrings
state: directory
mode: "0755"
- name: Download NodeSource signing key
ansible.builtin.get_url:
url: https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key
dest: /tmp/nodesource.gpg.key
mode: "0644"
- name: Install NodeSource keyring
ansible.builtin.command:
cmd: gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg /tmp/nodesource.gpg.key
creates: /etc/apt/keyrings/nodesource.gpg
- name: Add NodeSource apt repository
ansible.builtin.apt_repository:
repo: "{{ openapply_app_nodesource_repo_map[ansible_os_family] }}"
filename: nodesource
state: present
- name: Install Node.js runtime
ansible.builtin.apt:
name: nodejs
state: present
update_cache: true
- name: Install pnpm globally
community.general.npm:
name: pnpm
global: true
state: present
- name: Install Firebase CLI globally
community.general.npm:
name: firebase-tools
global: true
state: present
when: openapply_app_install_firebase_cli | bool

View File

@ -1,31 +0,0 @@
---
- name: Ensure guest OS family is supported
ansible.builtin.assert:
that:
- ansible_os_family == "Debian"
fail_msg: "openapply_app currently supports Debian-family guests (Ubuntu 22.04/24.04)."
- name: Ensure required role variables are present
ansible.builtin.assert:
that:
- openapply_app_repo_url | length > 0
- openapply_app_repo_version | length > 0
- openapply_app_root | length > 0
- openapply_app_service_name | length > 0
- openapply_app_service_user | length > 0
- openapply_app_start_command | length > 0
fail_msg: "Required OpenApply role variables are missing."
- name: Ensure real Firebase SPA configuration is provided
ansible.builtin.assert:
that:
- openapply_app_spa_env.VITE_FIREBASE_API_KEY != 'your-firebase-api-key'
- openapply_app_spa_env.VITE_FIREBASE_AUTH_DOMAIN != 'your-project.firebaseapp.com'
- openapply_app_spa_env.VITE_FIREBASE_PROJECT_ID != 'your-project-id'
- openapply_app_spa_env.VITE_FIREBASE_STORAGE_BUCKET != 'your-project.appspot.com'
- openapply_app_spa_env.VITE_FIREBASE_MESSAGING_SENDER_ID != 'your-sender-id'
- openapply_app_spa_env.VITE_FIREBASE_APP_ID != 'your-app-id'
fail_msg: >-
OpenApply SPA is using placeholder Firebase values. Set vault_openapply_firebase_* variables
in group_vars/all/vault.yml, then redeploy.
when: openapply_app_require_real_firebase_config | bool

View File

@ -1,23 +0,0 @@
---
- name: Verify OpenApply service reaches active state
ansible.builtin.command:
cmd: "systemctl is-active {{ openapply_app_service_name }}"
register: openapply_service_state
changed_when: false
retries: 20
delay: 3
until: openapply_service_state.stdout | trim == 'active'
- name: Wait for OpenApply port to become reachable
ansible.builtin.wait_for:
host: 127.0.0.1
port: "{{ openapply_app_service_port }}"
timeout: 120
- name: Validate HTTP response from OpenApply endpoint
ansible.builtin.uri:
url: "http://127.0.0.1:{{ openapply_app_service_port }}/"
method: GET
status_code: "{{ openapply_app_verify_status_codes }}"
register: openapply_http_probe
changed_when: false

View File

@ -1,6 +0,0 @@
{% for key, value in openapply_app_env.items() %}
{{ key }}={{ value }}
{% endfor %}
{% if openapply_app_firebase_token | length > 0 %}
FIREBASE_TOKEN={{ openapply_app_firebase_token }}
{% endif %}

View File

@ -1,19 +0,0 @@
[Unit]
Description=OpenApply web service
Wants=network-online.target
After=network-online.target
[Service]
Type=simple
User={{ openapply_app_service_user }}
Group={{ openapply_app_service_group }}
WorkingDirectory={{ openapply_app_root }}
EnvironmentFile={{ openapply_app_root }}/.env
ExecStart={{ openapply_app_start_command }}
AmbientCapabilities=CAP_NET_BIND_SERVICE
CapabilityBoundingSet=CAP_NET_BIND_SERVICE
Restart=on-failure
RestartSec=3
[Install]
WantedBy=multi-user.target

View File

@ -1,3 +0,0 @@
{% for key, value in openapply_app_spa_env.items() %}
{{ key }}={{ value }}
{% endfor %}

View File

@ -1,3 +0,0 @@
---
openapply_app_nodesource_repo_map:
Debian: "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_{{ openapply_app_node_major }}.x nodistro main"