Add the compose_stack role, inventory and playbooks

One role that syncs a payload and brings the stack up, configured entirely
through stack_* variables, plus six playbooks that each demonstrate one part
of that contract. Every playbook runs standalone and is tagged with its
stack name, so site.yml --tags <stack> works.

Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
This commit is contained in:
Lucas Winther
2026-09-16 03:58:01 +02:00
co-authored by Claude Opus 5
parent 7cdf9b854b
commit 7b52e9af9e
16 changed files with 606 additions and 0 deletions
+45
View File
@@ -0,0 +1,45 @@
---
# The public entry point, and the stack every other stack depends on: it owns
# proxy-net and the generated vhost configuration, so site.yml runs it first.
#
# Demonstrates the two things a payload made of plain configuration files needs:
# bind-mount directories created before the container starts, and a reload after
# the payload changes.
- name: Deploy the reverse proxy
hosts: edge
gather_facts: false
tags: [reverse-proxy]
roles:
- role: compose_stack
vars:
stack_name: reverse-proxy
stack_networks:
- proxy-net
stack_dirs:
# Bind mounts the compose file declares but no payload provides. Docker
# would otherwise create them root-owned on first start, and html/ in
# particular has to be writable by the deploy user before banner.yml
# can put a file in it.
#
# No `mode` on any of them on purpose: the role only applies the
# attributes an entry actually sets, so a directory that already exists
# on the host keeps whatever permissions it has.
- path: "{{ stack_root }}/reverse-proxy/proxy-data/conf"
- path: "{{ stack_root }}/reverse-proxy/proxy-data/vhost"
- path: "{{ stack_root }}/reverse-proxy/proxy-data/html"
- path: "{{ stack_root }}/reverse-proxy/proxy-data/dhparam"
# certs/ and acme/ are deliberately absent. They hold live private keys
# and are managed by acme-companion; nothing here should touch their
# ownership or permissions.
post_tasks:
- name: Reload nginx so changed vhost and conf files take effect
# conf/ and vhost/ are bind mounts, so editing a file in them never causes
# Compose to recreate the container — this reload is the only thing that
# applies the change. compose_stack_synced is set by the role from the
# payload sync, so a run that changed nothing stays a genuine no-op.
ansible.builtin.command:
cmd: docker exec reverse-proxy nginx -s reload
when: compose_stack_synced | default(false)
changed_when: true