124 lines
5.4 KiB
YAML
124 lines
5.4 KiB
YAML
---
|
|
# Installs one app (one loop iteration of `app` from playbooks/proxmox.yml)
|
|
# natively into a Proxmox LXC: merge portable + Proxmox config, fetch secrets
|
|
# from Vault, provision its database if it declares one, run the app's own
|
|
# install steps, then manage its systemd unit.
|
|
#
|
|
# The Proxmox counterpart to `compose_stack`. Everything up to "Run
|
|
# app-specific install steps" is deliberately the same shape as that role —
|
|
# same vars merge, same Vault lookup, same DB provisioning — so config lives
|
|
# in one place regardless of which platform an app lands on. What differs is
|
|
# the deployment primitive: a systemd service built from packages/binaries
|
|
# rather than `docker compose up -d`.
|
|
#
|
|
# UNPROVEN: `src/shared/postgres/` and `src/forgejo/` both ship an
|
|
# `ansible/proxmox/install.yml` now, but neither has been run end to end
|
|
# against a real LXC. The structure mirrors proven code; the details are not
|
|
# yet exercised.
|
|
|
|
- name: Set app facts
|
|
ansible.builtin.set_fact:
|
|
app_local_dir: "{{ repo_root }}/src/{{ app.src }}"
|
|
|
|
- name: Load portable app variables
|
|
ansible.builtin.include_vars:
|
|
file: "{{ app_local_dir }}/common/vars.yml"
|
|
name: app_common_vars
|
|
|
|
- name: Load Proxmox-specific app variables
|
|
ansible.builtin.include_vars:
|
|
file: "{{ app_local_dir }}/ansible/proxmox/vars.yml"
|
|
name: app_platform_vars
|
|
|
|
- name: Merge app configuration
|
|
ansible.builtin.set_fact:
|
|
# Portable values first, Proxmox-specific overrides on top. Available to
|
|
# the app's install.yml, alongside `vault_secrets` below.
|
|
app_config: >-
|
|
{{ (app_common_vars.env_defaults | default({}))
|
|
| combine(app_platform_vars.env_defaults | default({})) }}
|
|
|
|
- name: Look up app secrets from Vault
|
|
ansible.builtin.set_fact:
|
|
vault_secrets: >-
|
|
{{ lookup('community.hashi_vault.vault_kv2_get',
|
|
app.vault_path,
|
|
engine_mount_point=vault_kv_mount,
|
|
url=vault_addr,
|
|
auth_method=vault_auth_method,
|
|
role_id=vault_role_id | default(omit),
|
|
secret_id=vault_secret_id | default(omit)).secret }}
|
|
no_log: true
|
|
|
|
- name: Provision application database
|
|
when: app.db is defined
|
|
no_log: true
|
|
block:
|
|
- name: Look up Postgres superuser credentials from Vault
|
|
ansible.builtin.set_fact:
|
|
pg_admin_secrets: >-
|
|
{{ lookup('community.hashi_vault.vault_kv2_get',
|
|
app.db.admin_vault_path,
|
|
engine_mount_point=vault_kv_mount,
|
|
url=vault_addr,
|
|
auth_method=vault_auth_method,
|
|
role_id=vault_role_id | default(omit),
|
|
secret_id=vault_secret_id | default(omit)).secret }}
|
|
|
|
- name: Ensure application database role exists
|
|
community.postgresql.postgresql_user:
|
|
name: "{{ app.db.user }}"
|
|
password: "{{ vault_secrets[app.db.password_vault_key] }}"
|
|
login_host: "{{ app.db.provision_host }}"
|
|
login_port: "{{ app.db.provision_port }}"
|
|
login_user: "{{ pg_admin_secrets.POSTGRES_SUPERUSER }}"
|
|
login_password: "{{ pg_admin_secrets.POSTGRES_SUPERUSER_PASSWORD }}"
|
|
state: present
|
|
delegate_to: localhost
|
|
become: false
|
|
|
|
# Role first, then the database with `owner:` — the shape roles/k3s_app
|
|
# already uses, and not the `postgresql_user` + `priv: ALL` this role was
|
|
# written with. Two independent reasons it had to change:
|
|
#
|
|
# 1. `priv` was deprecated in community.postgresql 3.x and REMOVED in
|
|
# 4.0.0, so the old call is a hard "Unsupported parameters" failure
|
|
# on any current collection. requirements.yml asks for >=3.0.0,
|
|
# which installs 4.x.
|
|
# 2. On this instance it would have been wrong even if it still worked.
|
|
# `priv: ALL` grants database-level privileges (CONNECT, CREATE,
|
|
# TEMPORARY); since Postgres 15 the `public` schema no longer grants
|
|
# CREATE to PUBLIC, so a role holding all of those still cannot
|
|
# create a table. The Proxmox cluster is 17 (the Unraid one is 13,
|
|
# which is why the same code never failed that way there). Making
|
|
# the app role own the database covers it on both: on 15+ `public`
|
|
# is owned by `pg_database_owner`, which resolves to whoever owns
|
|
# the database.
|
|
#
|
|
# Ownership also makes a pg_dump restore land correctly, for the reason
|
|
# spelled out at the same tasks in roles/k3s_app.
|
|
- name: Ensure application database exists
|
|
community.postgresql.postgresql_db:
|
|
name: "{{ app.db.name }}"
|
|
owner: "{{ app.db.user }}"
|
|
login_host: "{{ app.db.provision_host }}"
|
|
login_port: "{{ app.db.provision_port }}"
|
|
login_user: "{{ pg_admin_secrets.POSTGRES_SUPERUSER }}"
|
|
login_password: "{{ pg_admin_secrets.POSTGRES_SUPERUSER_PASSWORD }}"
|
|
state: present
|
|
delegate_to: localhost
|
|
become: false
|
|
|
|
# Everything genuinely app-specific — fetching the binary or package, creating
|
|
# the service user, laying out data directories, rendering the app's own
|
|
# config file from `app_config` + `vault_secrets`, and installing a systemd
|
|
# unit — lives with the app, not here. See src/<app>/ansible/proxmox/.
|
|
- name: Run app-specific install steps
|
|
ansible.builtin.include_tasks: "{{ app_local_dir }}/ansible/proxmox/install.yml"
|
|
|
|
- name: Enable and start the service
|
|
ansible.builtin.systemd_service:
|
|
name: "{{ app.service_name | default(app.name) }}"
|
|
enabled: true
|
|
state: started
|
|
daemon_reload: true
|