--- # One stack, both hosts, one payload. # # Demonstrates three things: # - stack_src pointing outside the per-host convention, so two hosts share a # single payload instead of keeping duplicate copies in step by hand; # - a per-host variable map, which is how a play covers hosts that differ # without growing a second playbook or a `when:` on every task; # - stack_dirs entries that set ownership, and ones that only set a mode. - name: Deploy metrics hosts: - edge - app gather_facts: false tags: [metrics] vars: # Only the app host runs anything worth proxying a dashboard to, so only it # joins the private backend network. Keyed by inventory_hostname and looked # up below — adding a host means adding a line here, not a branch. metrics_networks: edge: - proxy-net app: - proxy-net - backend metrics_dirs: # The Grafana image runs as uid 472 and this is a bind mount, so the # directory has to be owned by that uid on the host. `recurse: true` with # no `mode`: recursing a mode here would rewrite the permissions of # Grafana's SQLite database, which holds hashed credentials and datasource # secrets. # # This belongs in stack_dirs rather than a pre_tasks chown. pre_tasks run # before the role creates the stack directory, and an escalated # ansible.builtin.file on a child stamps its owner onto every parent it # creates on the way down — which would leave the payload sync, running as # the deploy user, unable to write into the stack's own directory on a host # where metrics has never been deployed. - path: "{{ stack_root }}/metrics/grafana-data" owner: "472" group: "472" recurse: true # Written by the prometheus container, which runs as nobody (65534). A mode # rather than an owner because the uid is not stable across image versions. # Narrow this to an owner once you have confirmed the uid on your hosts. - path: "{{ stack_root }}/metrics/prometheus-data" mode: "0777" roles: - role: compose_stack vars: stack_name: metrics # Both hosts run the same thing, so the payload lives under server/shared/ # rather than being copied into server/edge/ and server/app/. stack_src: "{{ repo_root }}/server/shared/metrics" stack_networks: "{{ metrics_networks[inventory_hostname] }}" stack_dirs: "{{ metrics_dirs }}" post_tasks: - name: Reload prometheus so a changed scrape configuration takes effect # prometheus.yml is bind-mounted, so Compose never recreates the container # for a change to it. Prometheus re-reads its configuration on SIGHUP. ansible.builtin.command: cmd: docker kill --signal=SIGHUP prometheus when: compose_stack_synced | default(false) changed_when: true