From 883f31932e8271ce2033ddc48b1f563e173c446e Mon Sep 17 00:00:00 2001 From: Tiara Rodney Date: Sat, 14 Mar 2026 05:38:45 +0100 Subject: [PATCH] init --- .gitignore | 6 + .ssh.vault | 35 ++ .vault-pass-debug | 1 + CONTRIBUTING.md | 55 +++ DEVELOPMENT.md | 168 +++++++ NOTE-containerd-referrers.md | 60 +++ Pipfile | 16 + Pipfile.lock | 402 +++++++++++++++++ README.md | 107 +++++ ansible.cfg | 3 + ansible/README.md | 35 ++ .../debug/group_vars/all/secrets.yml | 27 ++ .../debug/group_vars/all/vault.yml | 54 +++ .../debug/group_vars/idp/firewall.yml | 4 + .../debug/group_vars/proxy/firewall.yml | 9 + .../debug/group_vars/wg_peers/wireguard.yml | 6 + ansible/inventories/debug/hosts.ini | 13 + .../inventories/prod/group_vars/all/vault.yml | 126 ++++++ .../prod/group_vars/idp/firewall.yml | 4 + .../prod/group_vars/proxy/firewall.yml | 9 + .../prod/group_vars/wg_peers/wireguard.yml | 10 + ansible/inventories/prod/hosts.ini | 13 + ansible/playbooks/backup.yml | 20 + ansible/playbooks/restore.yml | 28 ++ ansible/playbooks/setup.yml | 425 ++++++++++++++++++ ansible/requirements.yml | 4 + ansible/roles/apache/defaults/main.yml | 5 + ansible/roles/apache/handlers/main.yml | 6 + ansible/roles/apache/meta/main.yml | 2 + .../apache/tasks/deploy-reverse-proxy.yml | 18 + .../roles/apache/tasks/deploy-static-site.yml | 27 ++ ansible/roles/apache/tasks/install-apache.yml | 83 ++++ ansible/roles/apache/tasks/main.yml | 8 + .../templates/000-default-redirect.conf.j2 | 18 + .../templates/reverse-proxy-vhost.conf.j2 | 31 ++ .../templates/static-site-vhost.conf.j2 | 21 + ansible/roles/apache/vars/Debian.yml | 7 + ansible/roles/authentik/defaults/main.yml | 9 + .../roles/authentik/files/branding/.gitkeep | 0 ansible/roles/authentik/meta/main.yml | 4 + .../authentik/tasks/deploy-authentik.yml | 92 ++++ ansible/roles/authentik/tasks/main.yml | 4 + .../authentik/tasks/restore-authentik.yml | 46 ++ .../roles/authentik/templates/backup.sh.j2 | 7 + .../templates/blueprint-enrollment.yml.j2 | 326 ++++++++++++++ .../templates/blueprint-oauth2.yml.j2 | 67 +++ .../templates/blueprint-social-logins.yml.j2 | 35 ++ .../authentik/templates/docker-compose.yml.j2 | 51 +++ .../email/account-confirmation.html.j2 | 35 ++ .../templates/email/password-reset.html.j2 | 35 ++ ansible/roles/authentik/templates/env.j2 | 19 + ansible/roles/bugzilla/defaults/main.yml | 9 + ansible/roles/bugzilla/meta/main.yml | 6 + .../roles/bugzilla/tasks/deploy-bugzilla.yml | 160 +++++++ ansible/roles/bugzilla/tasks/main.yml | 4 + ansible/roles/bugzilla/tasks/restore.yml | 42 ++ .../bugzilla/templates/bugzilla-vhost.conf.j2 | 52 +++ .../bugzilla/templates/checksetup-answers.j2 | 4 + .../bugzilla/templates/docker-compose.yml.j2 | 15 + .../roles/bugzilla/templates/localconfig.j2 | 15 + ansible/roles/bugzilla/vars/Debian.yml | 31 ++ ansible/roles/comentario/defaults/main.yml | 5 + ansible/roles/comentario/meta/main.yml | 6 + .../comentario/tasks/deploy-comentario.yml | 52 +++ ansible/roles/comentario/tasks/main.yml | 4 + ansible/roles/comentario/tasks/restore.yml | 41 ++ .../templates/docker-compose.yml.j2 | 26 ++ .../comentario/templates/secrets.yaml.j2 | 27 ++ ansible/roles/conversejs/defaults/main.yml | 5 + ansible/roles/conversejs/meta/main.yml | 4 + .../conversejs/tasks/deploy-conversejs.yml | 49 ++ ansible/roles/conversejs/tasks/main.yml | 4 + .../roles/conversejs/templates/index.html.j2 | 195 ++++++++ .../roles/conversejs/templates/vhost.conf.j2 | 31 ++ ansible/roles/devpi/defaults/main.yml | 5 + ansible/roles/devpi/files/Dockerfile | 11 + ansible/roles/devpi/meta/main.yml | 6 + ansible/roles/devpi/tasks/deploy-devpi.yml | 51 +++ ansible/roles/devpi/tasks/main.yml | 4 + ansible/roles/devpi/tasks/restore.yml | 33 ++ .../devpi/templates/docker-compose.yml.j2 | 11 + ansible/roles/dnsmasq/defaults/main.yml | 7 + ansible/roles/dnsmasq/handlers/main.yml | 6 + ansible/roles/dnsmasq/tasks/main.yml | 20 + .../roles/dnsmasq/templates/dnsmasq.conf.j2 | 11 + ansible/roles/docker/handlers/main.yml | 11 + ansible/roles/docker/meta/main.yml | 2 + .../roles/docker/tasks/configure-mirror.yml | 29 ++ ansible/roles/docker/tasks/deploy-backup.yml | 7 + ansible/roles/docker/tasks/install-docker.yml | 34 ++ ansible/roles/docker/tasks/main.yml | 13 + ansible/roles/docker/tasks/start-compose.yml | 13 + .../templates/backup-docker-volumes.sh.j2 | 10 + ansible/roles/docker/vars/Debian.yml | 15 + .../roles/docker_registry/defaults/main.yml | 5 + .../roles/docker_registry/handlers/main.yml | 11 + .../docker_registry/tasks/deploy-registry.yml | 61 +++ ansible/roles/docker_registry/tasks/main.yml | 4 + .../tasks/restore-registry.yml | 22 + .../docker_registry/templates/config.yml.j2 | 13 + .../templates/docker-compose.yml.j2 | 12 + .../docker_registry/templates/vhost.conf.j2 | 28 ++ ansible/roles/host/defaults/main.yml | 3 + ansible/roles/host/handlers/main.yml | 11 + ansible/roles/host/meta/main.yml | 2 + ansible/roles/host/tasks/main.yml | 13 + ansible/roles/host/tasks/setup-admin.yml | 35 ++ ansible/roles/host/tasks/setup-base.yml | 69 +++ ansible/roles/host/tasks/setup-swap.yml | 37 ++ ansible/roles/host/tasks/setup-zram.yml | 37 ++ ansible/roles/host/vars/Debian.yml | 9 + ansible/roles/kellnr/defaults/main.yml | 5 + ansible/roles/kellnr/meta/main.yml | 6 + ansible/roles/kellnr/tasks/deploy-kellnr.yml | 44 ++ ansible/roles/kellnr/tasks/main.yml | 4 + ansible/roles/kellnr/tasks/restore.yml | 33 ++ .../kellnr/templates/docker-compose.yml.j2 | 16 + ansible/roles/prosody/defaults/main.yml | 10 + .../prosody/files/mod_auth_oauth_external.lua | 153 +++++++ .../files/mod_sasl_oauthbearer_only_bosh.lua | 35 ++ .../prosody/files/mod_session_timeout.lua | 16 + ansible/roles/prosody/meta/main.yml | 4 + .../roles/prosody/tasks/deploy-prosody.yml | 84 ++++ ansible/roles/prosody/tasks/main.yml | 4 + ansible/roles/prosody/tasks/restore.yml | 36 ++ .../prosody/templates/docker-compose.yml.j2 | 18 + .../templates/mod_default_contacts.lua.j2 | 40 ++ .../templates/mod_offline_email.lua.j2 | 144 ++++++ .../prosody/templates/prosody.cfg.lua.j2 | 111 +++++ ansible/roles/restic/defaults/main.yml | 8 + ansible/roles/restic/meta/main.yml | 2 + ansible/roles/restic/tasks/install-restic.yml | 57 +++ ansible/roles/restic/tasks/main.yml | 4 + ansible/roles/restic/tasks/restore-restic.yml | 20 + .../restic/templates/restic-backup.service.j2 | 9 + .../restic/templates/restic-backup.sh.j2 | 22 + .../restic/templates/restic-backup.timer.j2 | 10 + ansible/roles/wireguard/defaults/main.yml | 4 + ansible/roles/wireguard/handlers/main.yml | 6 + ansible/roles/wireguard/meta/main.yml | 2 + .../wireguard/tasks/deploy-wireguard.yml | 21 + .../roles/wireguard/tasks/generate-keys.yml | 45 ++ .../wireguard/tasks/install-wireguard.yml | 6 + ansible/roles/wireguard/tasks/main.yml | 8 + ansible/roles/wireguard/templates/wg.conf.j2 | 20 + ansible/roles/wireguard/vars/Debian.yml | 4 + scripts/deploy.sh | 69 +++ scripts/env.sh | 10 + scripts/local/setup-hosts.sh | 32 ++ scripts/local/setup-wireguard.sh | 49 ++ scripts/local/teardown-hosts.sh | 21 + scripts/local/teardown-wireguard.sh | 10 + scripts/prod-deploy.sh | 45 ++ scripts/provision.sh | 29 ++ scripts/reproduce-containerd-referrers.sh | 98 ++++ scripts/reset.sh | 12 + scripts/resume.sh | 6 + scripts/suspend.sh | 6 + scripts/teardown.sh | 15 + scripts/vm/create.sh | 48 ++ scripts/vm/destroy.sh | 13 + scripts/vm/env.sh | 47 ++ scripts/vm/restore.sh | 20 + scripts/vm/setup-network.sh | 12 + scripts/vm/setup-taps.sh | 7 + scripts/vm/snapshot.sh | 16 + scripts/vm/start.sh | 26 ++ scripts/vm/status.sh | 13 + scripts/vm/stop.sh | 7 + 169 files changed, 5676 insertions(+) create mode 100644 .gitignore create mode 100644 .ssh.vault create mode 100644 .vault-pass-debug create mode 100644 CONTRIBUTING.md create mode 100644 DEVELOPMENT.md create mode 100644 NOTE-containerd-referrers.md create mode 100644 Pipfile create mode 100644 Pipfile.lock create mode 100644 README.md create mode 100644 ansible.cfg create mode 100644 ansible/README.md create mode 100644 ansible/inventories/debug/group_vars/all/secrets.yml create mode 100644 ansible/inventories/debug/group_vars/all/vault.yml create mode 100644 ansible/inventories/debug/group_vars/idp/firewall.yml create mode 100644 ansible/inventories/debug/group_vars/proxy/firewall.yml create mode 100644 ansible/inventories/debug/group_vars/wg_peers/wireguard.yml create mode 100644 ansible/inventories/debug/hosts.ini create mode 100644 ansible/inventories/prod/group_vars/all/vault.yml create mode 100644 ansible/inventories/prod/group_vars/idp/firewall.yml create mode 100644 ansible/inventories/prod/group_vars/proxy/firewall.yml create mode 100644 ansible/inventories/prod/group_vars/wg_peers/wireguard.yml create mode 100644 ansible/inventories/prod/hosts.ini create mode 100644 ansible/playbooks/backup.yml create mode 100644 ansible/playbooks/restore.yml create mode 100644 ansible/playbooks/setup.yml create mode 100644 ansible/requirements.yml create mode 100644 ansible/roles/apache/defaults/main.yml create mode 100644 ansible/roles/apache/handlers/main.yml create mode 100644 ansible/roles/apache/meta/main.yml create mode 100644 ansible/roles/apache/tasks/deploy-reverse-proxy.yml create mode 100644 ansible/roles/apache/tasks/deploy-static-site.yml create mode 100644 ansible/roles/apache/tasks/install-apache.yml create mode 100644 ansible/roles/apache/tasks/main.yml create mode 100644 ansible/roles/apache/templates/000-default-redirect.conf.j2 create mode 100644 ansible/roles/apache/templates/reverse-proxy-vhost.conf.j2 create mode 100644 ansible/roles/apache/templates/static-site-vhost.conf.j2 create mode 100644 ansible/roles/apache/vars/Debian.yml create mode 100644 ansible/roles/authentik/defaults/main.yml create mode 100644 ansible/roles/authentik/files/branding/.gitkeep create mode 100644 ansible/roles/authentik/meta/main.yml create mode 100644 ansible/roles/authentik/tasks/deploy-authentik.yml create mode 100644 ansible/roles/authentik/tasks/main.yml create mode 100644 ansible/roles/authentik/tasks/restore-authentik.yml create mode 100644 ansible/roles/authentik/templates/backup.sh.j2 create mode 100644 ansible/roles/authentik/templates/blueprint-enrollment.yml.j2 create mode 100644 ansible/roles/authentik/templates/blueprint-oauth2.yml.j2 create mode 100644 ansible/roles/authentik/templates/blueprint-social-logins.yml.j2 create mode 100644 ansible/roles/authentik/templates/docker-compose.yml.j2 create mode 100644 ansible/roles/authentik/templates/email/account-confirmation.html.j2 create mode 100644 ansible/roles/authentik/templates/email/password-reset.html.j2 create mode 100644 ansible/roles/authentik/templates/env.j2 create mode 100644 ansible/roles/bugzilla/defaults/main.yml create mode 100644 ansible/roles/bugzilla/meta/main.yml create mode 100644 ansible/roles/bugzilla/tasks/deploy-bugzilla.yml create mode 100644 ansible/roles/bugzilla/tasks/main.yml create mode 100644 ansible/roles/bugzilla/tasks/restore.yml create mode 100644 ansible/roles/bugzilla/templates/bugzilla-vhost.conf.j2 create mode 100644 ansible/roles/bugzilla/templates/checksetup-answers.j2 create mode 100644 ansible/roles/bugzilla/templates/docker-compose.yml.j2 create mode 100644 ansible/roles/bugzilla/templates/localconfig.j2 create mode 100644 ansible/roles/bugzilla/vars/Debian.yml create mode 100644 ansible/roles/comentario/defaults/main.yml create mode 100644 ansible/roles/comentario/meta/main.yml create mode 100644 ansible/roles/comentario/tasks/deploy-comentario.yml create mode 100644 ansible/roles/comentario/tasks/main.yml create mode 100644 ansible/roles/comentario/tasks/restore.yml create mode 100644 ansible/roles/comentario/templates/docker-compose.yml.j2 create mode 100644 ansible/roles/comentario/templates/secrets.yaml.j2 create mode 100644 ansible/roles/conversejs/defaults/main.yml create mode 100644 ansible/roles/conversejs/meta/main.yml create mode 100644 ansible/roles/conversejs/tasks/deploy-conversejs.yml create mode 100644 ansible/roles/conversejs/tasks/main.yml create mode 100644 ansible/roles/conversejs/templates/index.html.j2 create mode 100644 ansible/roles/conversejs/templates/vhost.conf.j2 create mode 100644 ansible/roles/devpi/defaults/main.yml create mode 100644 ansible/roles/devpi/files/Dockerfile create mode 100644 ansible/roles/devpi/meta/main.yml create mode 100644 ansible/roles/devpi/tasks/deploy-devpi.yml create mode 100644 ansible/roles/devpi/tasks/main.yml create mode 100644 ansible/roles/devpi/tasks/restore.yml create mode 100644 ansible/roles/devpi/templates/docker-compose.yml.j2 create mode 100644 ansible/roles/dnsmasq/defaults/main.yml create mode 100644 ansible/roles/dnsmasq/handlers/main.yml create mode 100644 ansible/roles/dnsmasq/tasks/main.yml create mode 100644 ansible/roles/dnsmasq/templates/dnsmasq.conf.j2 create mode 100644 ansible/roles/docker/handlers/main.yml create mode 100644 ansible/roles/docker/meta/main.yml create mode 100644 ansible/roles/docker/tasks/configure-mirror.yml create mode 100644 ansible/roles/docker/tasks/deploy-backup.yml create mode 100644 ansible/roles/docker/tasks/install-docker.yml create mode 100644 ansible/roles/docker/tasks/main.yml create mode 100644 ansible/roles/docker/tasks/start-compose.yml create mode 100644 ansible/roles/docker/templates/backup-docker-volumes.sh.j2 create mode 100644 ansible/roles/docker/vars/Debian.yml create mode 100644 ansible/roles/docker_registry/defaults/main.yml create mode 100644 ansible/roles/docker_registry/handlers/main.yml create mode 100644 ansible/roles/docker_registry/tasks/deploy-registry.yml create mode 100644 ansible/roles/docker_registry/tasks/main.yml create mode 100644 ansible/roles/docker_registry/tasks/restore-registry.yml create mode 100644 ansible/roles/docker_registry/templates/config.yml.j2 create mode 100644 ansible/roles/docker_registry/templates/docker-compose.yml.j2 create mode 100644 ansible/roles/docker_registry/templates/vhost.conf.j2 create mode 100644 ansible/roles/host/defaults/main.yml create mode 100644 ansible/roles/host/handlers/main.yml create mode 100644 ansible/roles/host/meta/main.yml create mode 100644 ansible/roles/host/tasks/main.yml create mode 100644 ansible/roles/host/tasks/setup-admin.yml create mode 100644 ansible/roles/host/tasks/setup-base.yml create mode 100644 ansible/roles/host/tasks/setup-swap.yml create mode 100644 ansible/roles/host/tasks/setup-zram.yml create mode 100644 ansible/roles/host/vars/Debian.yml create mode 100644 ansible/roles/kellnr/defaults/main.yml create mode 100644 ansible/roles/kellnr/meta/main.yml create mode 100644 ansible/roles/kellnr/tasks/deploy-kellnr.yml create mode 100644 ansible/roles/kellnr/tasks/main.yml create mode 100644 ansible/roles/kellnr/tasks/restore.yml create mode 100644 ansible/roles/kellnr/templates/docker-compose.yml.j2 create mode 100644 ansible/roles/prosody/defaults/main.yml create mode 100644 ansible/roles/prosody/files/mod_auth_oauth_external.lua create mode 100644 ansible/roles/prosody/files/mod_sasl_oauthbearer_only_bosh.lua create mode 100644 ansible/roles/prosody/files/mod_session_timeout.lua create mode 100644 ansible/roles/prosody/meta/main.yml create mode 100644 ansible/roles/prosody/tasks/deploy-prosody.yml create mode 100644 ansible/roles/prosody/tasks/main.yml create mode 100644 ansible/roles/prosody/tasks/restore.yml create mode 100644 ansible/roles/prosody/templates/docker-compose.yml.j2 create mode 100644 ansible/roles/prosody/templates/mod_default_contacts.lua.j2 create mode 100644 ansible/roles/prosody/templates/mod_offline_email.lua.j2 create mode 100644 ansible/roles/prosody/templates/prosody.cfg.lua.j2 create mode 100644 ansible/roles/restic/defaults/main.yml create mode 100644 ansible/roles/restic/meta/main.yml create mode 100644 ansible/roles/restic/tasks/install-restic.yml create mode 100644 ansible/roles/restic/tasks/main.yml create mode 100644 ansible/roles/restic/tasks/restore-restic.yml create mode 100644 ansible/roles/restic/templates/restic-backup.service.j2 create mode 100644 ansible/roles/restic/templates/restic-backup.sh.j2 create mode 100644 ansible/roles/restic/templates/restic-backup.timer.j2 create mode 100644 ansible/roles/wireguard/defaults/main.yml create mode 100644 ansible/roles/wireguard/handlers/main.yml create mode 100644 ansible/roles/wireguard/meta/main.yml create mode 100644 ansible/roles/wireguard/tasks/deploy-wireguard.yml create mode 100644 ansible/roles/wireguard/tasks/generate-keys.yml create mode 100644 ansible/roles/wireguard/tasks/install-wireguard.yml create mode 100644 ansible/roles/wireguard/tasks/main.yml create mode 100644 ansible/roles/wireguard/templates/wg.conf.j2 create mode 100644 ansible/roles/wireguard/vars/Debian.yml create mode 100755 scripts/deploy.sh create mode 100644 scripts/env.sh create mode 100644 scripts/local/setup-hosts.sh create mode 100644 scripts/local/setup-wireguard.sh create mode 100644 scripts/local/teardown-hosts.sh create mode 100644 scripts/local/teardown-wireguard.sh create mode 100755 scripts/prod-deploy.sh create mode 100755 scripts/provision.sh create mode 100644 scripts/reproduce-containerd-referrers.sh create mode 100755 scripts/reset.sh create mode 100755 scripts/resume.sh create mode 100755 scripts/suspend.sh create mode 100644 scripts/teardown.sh create mode 100755 scripts/vm/create.sh create mode 100755 scripts/vm/destroy.sh create mode 100755 scripts/vm/env.sh create mode 100755 scripts/vm/restore.sh create mode 100755 scripts/vm/setup-network.sh create mode 100755 scripts/vm/setup-taps.sh create mode 100755 scripts/vm/snapshot.sh create mode 100755 scripts/vm/start.sh create mode 100755 scripts/vm/status.sh create mode 100755 scripts/vm/stop.sh diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..eef233f --- /dev/null +++ b/.gitignore @@ -0,0 +1,6 @@ +/letsencrypt/ +/.pytest_cache/ +/.ssh/ +/.local/ +/.tox/ +/.vault-pass diff --git a/.ssh.vault b/.ssh.vault new file mode 100644 index 0000000..f0298e0 --- /dev/null +++ b/.ssh.vault @@ -0,0 +1,35 @@ +$ANSIBLE_VAULT;1.1;AES256 +39316330396162386166363162646363343365343430393266666638356139383832353833326132 +6531356666643331363735373863323037303562393437620a303135613738303166346234663137 +65303562666362383266323161323832666165323237313033303961363935313561343731363934 +3632666365663637640a666666616336343362356164366239373065656239656237373331303166 +34343539666565636462343064666163333132373236343065323735333562616434323333386438 +38393137306438656463333135316539663264353736636233663035623131623835636534633336 +63306666343238656233653232663663323837666437346565616137633638613439393861306636 +38646663356237623765626237653732336362393739373835363431393963663065633535366632 +33383031303434396334373834663662653735353030336563646236313532656464333863636263 +34656262646233646230646335376565666237366138303733326339656166636133333433346432 +30616139393936383261393763636563386138393237343738613933303562343837353236626665 +37323635343535353032663866666238646635346138646666646562386433303063333862393761 +39346234633962326231333032653732393435336434616664663961633062353739383937383866 +61343030383530353235346561346531633832613634616533306136653930326634393530383730 +35316438636333313930333235316361393863303961666165616130616639356632356330383139 +39346335396532636334636336346434613934376131643165333438373630653732643033376537 +32383066623565643964623535333262376236316564356666336532613337653333613338613865 +34616561613533333636306163303131323834653934666661653866666562363638616630376566 +30643330393031613836353936636661653164353531303163623666666563643837346462376436 +39653665656164303135343738373436383265613363366664373466333963333532353335323436 +38633163656532356435356334376164373864383031366332633131316162336161643034653664 +61356538356563356232653964623165373239323664616339383263333365333633616564383138 +63343435343630353461376662626365626565616366373937306637346635313462393834393430 +35343962316630663238376262396332336639643136626434626336346437373438393963623863 +31623237336530376364626634653663313837306165376165346363306166343739393866623537 +30633735646434633762303065306231346363306339316636373066373464383764636634323163 +31356431333339653266393138353061643261306135336563303462343261393261376139613364 +31373861333065646237376535366138353438336463333363623464303431333135353133363461 +61646262343734343362643432633837623234646633336639336566623038346561393863303636 +36393861636631333363646438376133616461303834653262616565303362396634626630646137 +37616631383264656333383035396262656162613162653039366139623634393030656137656563 +65613135333364636437376163303230323435353834636262656539363964626331343465373038 +64333735643234326665653036303465646561646362626662653966303966623130356433313034 +3661666134663430643830613463663761333162393766636263 diff --git a/.vault-pass-debug b/.vault-pass-debug new file mode 100644 index 0000000..2f21015 --- /dev/null +++ b/.vault-pass-debug @@ -0,0 +1 @@ +&0geF%B46!H30#fnuY4ad8yCAxpM&C*! diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..aa12d53 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,55 @@ +# Contributing + +## Code style + +- YAML files use 4-space indentation, formatted with `yamlfix`. +- Jinja2 templates use the file extension `.j2`. +- Role names use snake_case (e.g., `docker_registry`). +- Task names are human-readable sentences (e.g., "Ensure SSL private keys are readable by containers"). + +## Role structure + +Each role follows the standard Ansible layout: + +``` +roles// +├── defaults/main.yml # Default variables +├── tasks/ +│ ├── main.yml # Entry point +│ └── *.yml # Additional task files (deploy, restore, etc.) +├── templates/ # Jinja2 templates (.j2) +├── files/ # Static files +└── meta/main.yml # Role dependencies +``` + +## Adding a new service + +1. Create a new role in `ansible/roles//`. +2. Add it to the proxy or IDP play in `ansible/playbooks/setup.yml` with a + `tags: []` annotation. +3. If the role depends on docker or apache, those roles handle themselves + internally — just declare the dependency in `meta/main.yml`. +## Testing changes + +Always test locally before deploying to production: + +```bash +# Run against local VMs +pipenv run ansible-playbook -i ansible/inventories/debug/hosts.ini ansible/playbooks/setup.yml \ + --tags +``` + +## Committing + +- Keep commits focused: one logical change per commit. +- Use conventional-ish commit messages: + - `feat: add offline email notifications to prosody` + - `fix: correct registry vhost name collision` + - `chore: migrate collection roles to local roles/` + +## Vault changes + +When adding new secrets, add them to the vault file and document the variable +name (but not the value) somewhere discoverable — either in the role's +`defaults/main.yml` as a commented placeholder or in the playbook next to the +role invocation. diff --git a/DEVELOPMENT.md b/DEVELOPMENT.md new file mode 100644 index 0000000..0e1dbc5 --- /dev/null +++ b/DEVELOPMENT.md @@ -0,0 +1,168 @@ +# Development + +## Prerequisites + +```bash +sudo apt install -y qemu-system-x86 libvirt-daemon-system libvirt-clients \ + genisoimage ovmf screen +sudo usermod -aG libvirt $(whoami) +sudo usermod -aG kvm $(whoami) +pipenv install --dev +pipenv run ansible-galaxy collection install -r ansible/requirements.yml +``` + +## Repository layout + +``` +servers/ +├── ansible/ +│ ├── inventories/ +│ │ ├── debug/ # Local VMs (vm-proxy, vm-idp) +│ │ └── prod/ # Production VPS hosts +│ ├── playbooks/ +│ │ ├── setup.yml # Main deployment playbook +│ │ ├── backup.yml # Backup playbook +│ │ └── restore.yml # Restore playbook +│ ├── roles/ # All roles (formerly a separate collection) +│ └── requirements.yml # Ansible Galaxy dependencies +├── scripts/ +│ ├── provision.sh # One-time: create VMs + full playbook + snapshot +│ ├── deploy.sh # Iterate: restore + deploy a single service +│ ├── reset.sh # Restore VMs to a snapshot +│ ├── prod-deploy.sh # Deploy to production +│ └── vm/ # Low-level VM lifecycle (wrapping qemu-vm) +├── letsencrypt/ # TLS certificates (not committed) +├── Pipfile # Python dependencies +└── ansible.cfg # Ansible config (roles_path, vault) +``` + +## Development workflow + +The workflow is: develop and test locally against VMs, then deploy to +production once changes are idempotent and working. + +All scripts are meant to be run inside `pipenv shell` or via `pipenv run`. + +### 1. Provision (once) + +Creates VMs, runs the full ansible playbook, and snapshots the result as +`provisioned`. Prompts for sudo to set up the bridge network: + +```bash +pipenv run scripts/provision.sh +``` + +This gives you two VMs: +- **vm-proxy** at `10.10.0.2` (screen session `vm-proxy`) +- **vm-idp** at `10.10.0.3` (screen session `vm-idp`) + +Attach to a VM's serial console with `screen -r vm-proxy`. + +### 2. Iterate on a service + +Deploy a single service to the local VMs: + +```bash +# Deploy bugzilla on top of current VM state +pipenv run scripts/deploy.sh bugzilla + +# Skip dependencies you know haven't changed +pipenv run scripts/deploy.sh bugzilla --skip docker,apache + +# Restore to clean state first, then deploy +pipenv run scripts/deploy.sh prosody --restore + +# Restore to a specific snapshot first +pipenv run scripts/deploy.sh authentik --restore initialized +``` + +### 3. Reset + +Go back to a known state without deploying anything: + +```bash +# Reset to bare VMs (pre-ansible) +pipenv run scripts/reset.sh + +# Reset to fully provisioned state +pipenv run scripts/reset.sh provisioned +``` + +### 4. Custom snapshots + +Save and restore intermediate states during development: + +```bash +# Save current state +pipenv run scripts/vm/snapshot.sh after-bugzilla + +# Restore it later +pipenv run scripts/reset.sh after-bugzilla +``` + +### 5. Destroy and recreate + +Start completely from scratch: + +```bash +pipenv run scripts/vm/destroy.sh +pipenv run scripts/provision.sh +``` + +### 6. Deploy to production + +Once your changes work locally and are idempotent: + +```bash +# Full deployment +pipenv run scripts/prod-deploy.sh + +# Targeted deployment +pipenv run scripts/prod-deploy.sh prosody + +# Skip dependencies +pipenv run scripts/prod-deploy.sh bugzilla --skip docker,apache +``` + +## Low-level VM management + +The `scripts/vm/` directory contains building-block scripts for direct +VM control: + +| Script | Purpose | +|--------|---------| +| `vm/start.sh` | Start VMs in screen sessions | +| `vm/stop.sh` | Stop VMs gracefully | +| `vm/status.sh` | Show instances, volumes, screen sessions | +| `vm/snapshot.sh