stack_secrets reads KV v2 on the target host and writes the stack's .env at 0600, failing loudly on a sealed vault, a bad token, a missing field or an unsafe value. Adds an example OpenBao stack on app and moves webapp onto it; metrics keeps a hand-placed .env. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
88 lines
3.7 KiB
YAML
88 lines
3.7 KiB
YAML
---
|
|
# The variable contract. Playbooks set these; nothing else should. Every entry is
|
|
# documented in AGENTS.md — keep the two in step.
|
|
|
|
# Required. Names the stack, and by default its payload and destination too.
|
|
stack_name: ""
|
|
|
|
# Payload directory in this repository, and where it lands on the host. Override
|
|
# stack_src to share one payload between hosts or between two instances of the
|
|
# same application; override stack_dest when the remote directory cannot be
|
|
# named after the stack.
|
|
stack_src: "{{ repo_root }}/server/{{ inventory_hostname }}/{{ stack_name }}"
|
|
stack_dest: "{{ stack_root | default('/srv/stacks') }}/{{ stack_name }}"
|
|
|
|
# Extra directories to create before the stack starts. Each entry needs a `path`;
|
|
# `mode`, `owner`, `group` and `recurse` are optional and applied only when
|
|
# given, so a directory that already exists on the host is never re-chmodded or
|
|
# re-chowned.
|
|
stack_dirs: []
|
|
|
|
# Extra environment for the compose invocation. PWD is always set to stack_dest;
|
|
# anything here is merged on top.
|
|
stack_env: {}
|
|
|
|
# External Docker networks the compose file expects to already exist.
|
|
stack_networks: []
|
|
|
|
# Compose files, relative to stack_dest, in the order `docker compose -f` wants.
|
|
stack_files:
|
|
- docker-compose.yml
|
|
|
|
# Never ship secrets to the host through the payload. Extend this list; do not
|
|
# replace it without understanding what you are letting through.
|
|
stack_exclude:
|
|
- .env
|
|
|
|
# Whether the sync removes host files that are no longer in the payload. Off by
|
|
# default: a stack's directory usually also holds data the payload knows nothing
|
|
# about (bind mounts, certificates, logs).
|
|
stack_prune: false
|
|
|
|
# present, absent, or restarted.
|
|
stack_state: present
|
|
|
|
# Image pull policy for this invocation. Defaults to the repo-wide `pull` flag so
|
|
# `-e pull=always` keeps working, but because it is a role variable a playbook
|
|
# can override it for a single call — for example to sync with the old images,
|
|
# run a database upgrade, and only then bring the stack up on the new ones.
|
|
stack_pull: "{{ pull | default('policy') }}"
|
|
|
|
# Compose build policy. `policy` builds only when the image is missing; stacks
|
|
# that build from a Dockerfile in their payload want `always` on an update run.
|
|
stack_build: policy
|
|
|
|
# Whether to start the stack at all. False syncs the payload, creates the
|
|
# directories and the networks, and stops before Compose — the shape a migration
|
|
# needs, where data has to be moved into a bind mount after the files land and
|
|
# before anything opens them. Defaults to the repo-wide `start` flag, so
|
|
# `-e start=false` works on every playbook without editing any of them.
|
|
stack_start: "{{ start | default(true) | bool }}"
|
|
|
|
# Secrets to fetch from the vault and render into the stack's .env before the
|
|
# stack starts. A map of environment variable name to the path and field that
|
|
# hold it:
|
|
#
|
|
# stack_secrets:
|
|
# SECRET_KEY:
|
|
# path: stacks/webapp
|
|
# field: secret_key
|
|
#
|
|
# Empty means the role never contacts a vault and never writes a .env, which is
|
|
# every stack that has not opted in. Those still read a .env placed on the host
|
|
# by hand, since stack_exclude keeps the sync away from it either way.
|
|
stack_secrets: {}
|
|
|
|
# Where the vault is, as seen from the target host. The read runs on the host,
|
|
# which is what lets the vault bind to loopback and be published nowhere. A host
|
|
# without its own vault can point vault_addr at one it can reach. See
|
|
# docs/secrets.md.
|
|
stack_vault_addr: "{{ vault_addr | default('http://127.0.0.1:8200') }}"
|
|
|
|
# KV v2 mount point.
|
|
stack_vault_mount: "{{ vault_kv_mount | default('kv') }}"
|
|
|
|
# Read on the control node, from the operator's shell or a CI secret. Never in
|
|
# this repository and never in the inventory.
|
|
stack_vault_token: "{{ lookup('env', 'VAULT_TOKEN') }}"
|