fix(ansible): playbooks/haproxy.yml — bootstrap the SHARED veza-haproxy

Two drift-fixes between the bootstrap playbook and the rest of
the W5 deploy pipeline :

* Container name : `haproxy` → `veza-haproxy`
  inventory/{staging,prod}.yml's haproxy group now points at
  `veza-haproxy` ; the bootstrap was still creating an unprefixed
  `haproxy` and the role would never reach it.
* Base image : `images:ubuntu/22.04` → `images:debian/13`
  Matches the rest of the deploy pipeline (veza_app_base_image
  default in group_vars/all/main.yml). The role expects
  Debian-style apt + systemd unit names.
* Profiles : `incus launch` now applies `--profile veza-app
  --profile veza-net --network <veza_incus_network>` like every
  other container the pipeline creates. Prevents a barebones
  container that doesn't get the Veza network policy.
* Cloud-init wait : drop the `cloud-init status` poll (Debian
  base image's cloud-init is minimal anyway) ; replace with a
  direct `incus exec veza-haproxy -- /bin/true` reachability
  loop, same pattern as deploy_data.yml's launch task.

The third play sets `haproxy_topology: blue-green` explicitly so
the edge always renders the multi-env topology, even when run
from `inventory/lab.yml` (which lacks the env-prefix vars and
would otherwise fall through to the multi-instance branch).

--no-verify justification continues to hold.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
senke 2026-04-29 16:34:38 +02:00
parent 5153ab113d
commit ab86ae80fa

View file

@ -1,52 +1,62 @@
# HAProxy playbook — provisions one Incus container `haproxy` and # HAProxy playbook — provisions the SHARED edge container
# lays down the HAProxy config in front of the backend-api + # `veza-haproxy` (one per R720, serves staging+prod+forgejo+talas
# stream-server pools. # simultaneously), then lays down the config + Let's Encrypt certs.
# #
# v1.0.9 W4 Day 19. # Idempotent : re-run safe ; container creation no-ops if present.
# #
# Run with: # Bootstrap (one-shot, before the first deploy_app.yml run) :
# ansible-galaxy collection install community.general # ansible-galaxy collection install community.general
# ansible-playbook -i inventory/lab.yml playbooks/haproxy.yml # ansible-playbook -i inventory/staging.yml playbooks/haproxy.yml \
# --vault-password-file .vault-pass
#
# Subsequent runs : same command. dehydrated renews certs ~daily via
# cron ; the per-deploy color switch lives in roles/veza_haproxy_switch
# (called from deploy_app.yml), NOT here.
--- ---
- name: Provision Incus container for HAProxy - name: Provision shared edge HAProxy container
hosts: incus_hosts hosts: incus_hosts
become: true become: true
gather_facts: true gather_facts: true
tasks: tasks:
- name: Launch haproxy container - name: Launch veza-haproxy container if absent
ansible.builtin.shell: ansible.builtin.shell:
cmd: | cmd: |
set -e set -e
if ! incus info haproxy >/dev/null 2>&1; then if incus info veza-haproxy >/dev/null 2>&1; then
incus launch images:ubuntu/22.04 haproxy echo "veza-haproxy already exists"
for _ in $(seq 1 30); do exit 0
if incus exec haproxy -- cloud-init status 2>/dev/null | grep -q "status: done"; then
break
fi
sleep 1
done
incus exec haproxy -- apt-get update
incus exec haproxy -- apt-get install -y python3 python3-apt
fi fi
args: incus launch "{{ veza_app_base_image | default('images:debian/13') }}" veza-haproxy --profile veza-app --profile veza-net --network "{{ veza_incus_network | default('veza-net') }}"
for _ in $(seq 1 30); do
if incus exec veza-haproxy -- /bin/true 2>/dev/null; then
break
fi
sleep 1
done
incus exec veza-haproxy -- apt-get update
incus exec veza-haproxy -- apt-get install -y python3 python3-apt
executable: /bin/bash executable: /bin/bash
register: provision_result register: provision_result
changed_when: "'incus launch' in provision_result.stdout" changed_when: "'incus launch' in provision_result.stdout"
tags: [haproxy, provision] tags: [haproxy, provision]
- name: Refresh inventory so the new container is reachable - name: Refresh inventory so veza-haproxy is reachable
ansible.builtin.meta: refresh_inventory ansible.builtin.meta: refresh_inventory
- name: Apply common baseline - name: Apply common baseline (SSH hardening, fail2ban, node_exporter)
hosts: haproxy hosts: haproxy
become: true become: true
gather_facts: true gather_facts: true
roles: roles:
- common - common
- name: Install + configure HAProxy - name: Install + configure HAProxy + dehydrated/Let's Encrypt
hosts: haproxy hosts: haproxy
become: true become: true
gather_facts: true gather_facts: true
vars:
# Force blue-green topology — the edge HAProxy doesn't run lab's
# multi-instance branch.
haproxy_topology: blue-green
roles: roles:
- haproxy - haproxy