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
# lays down the HAProxy config in front of the backend-api +
# stream-server pools.
# HAProxy playbook — provisions the SHARED edge container
# `veza-haproxy` (one per R720, serves staging+prod+forgejo+talas
# 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-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
become: true
gather_facts: true
tasks:
- name: Launch haproxy container
- name: Launch veza-haproxy container if absent
ansible.builtin.shell:
cmd: |
set -e
if ! incus info haproxy >/dev/null 2>&1; then
incus launch images:ubuntu/22.04 haproxy
for _ in $(seq 1 30); do
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
if incus info veza-haproxy >/dev/null 2>&1; then
echo "veza-haproxy already exists"
exit 0
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
register: provision_result
changed_when: "'incus launch' in provision_result.stdout"
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
- name: Apply common baseline
- name: Apply common baseline (SSH hardening, fail2ban, node_exporter)
hosts: haproxy
become: true
gather_facts: true
roles:
- common
- name: Install + configure HAProxy
- name: Install + configure HAProxy + dehydrated/Let's Encrypt
hosts: haproxy
become: 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:
- haproxy