From 411200884b06bb68978665a6d23935a5794cbf38 Mon Sep 17 00:00:00 2001 From: June Date: Wed, 20 May 2026 18:54:45 +0200 Subject: [PATCH 1/2] docs: overhaul SOPS documentation for better structure and readability --- README.md | 2 +- docs/concepts-and-configurations/sops.md | 18 ++++++ docs/guides/create-new-web-service-vm.md | 2 +- ...ng_up_secrets_using_sops_for_a_new_host.md | 33 ----------- docs/guides/sops-new-host.md | 58 +++++++++++++++++++ docs/guides/sops-storing-secrets.md | 29 ++++++++++ 6 files changed, 107 insertions(+), 35 deletions(-) create mode 100644 docs/concepts-and-configurations/sops.md delete mode 100644 docs/guides/setting_up_secrets_using_sops_for_a_new_host.md create mode 100644 docs/guides/sops-new-host.md create mode 100644 docs/guides/sops-storing-secrets.md diff --git a/README.md b/README.md index 741eeb3..a2f2214 100644 --- a/README.md +++ b/README.md @@ -27,7 +27,7 @@ Generally all secrets get encrypted for all GPG-keys of all members of the infra Ansible then has access to the secrets with the help of the [`community.sops.sops` vars plugin](https://docs.ansible.com/ansible/latest/collections/community/sops/docsite/guide.html#working-with-encrypted-variables), which is configured in this repository. A local Ansible run then uses the locally available GPG-key to decrypt the secrets. -For a tutorial on how to set up secrets using SOPS for a new host, see [Setting Up Secrets Using SOPS for a New Host](./docs/setting_up_secrets_using_sops_for_a_new_host.md). +For a tutorial on how to set up SOPS for a new host, see [SOPS: New Host](./docs/guides/sops-new-host.md). ### Updating SOPS files after swapping out a GPG key diff --git a/docs/concepts-and-configurations/sops.md b/docs/concepts-and-configurations/sops.md new file mode 100644 index 0000000..e4519e5 --- /dev/null +++ b/docs/concepts-and-configurations/sops.md @@ -0,0 +1,18 @@ +--- +title: SOPS +--- + +# SOPS + +We're using [SOPS](https://github.com/getsops/sops) for secret management together with the `community.sops.sops` vars plugin for Ansible. + +## GPG Keys + +In order to edit encrypted files, you need all the GPG public keys imported into your GPG Keychain. You should be able to find the necessary public keys in [infra-secrets](https://git.hamburg.ccc.de/CCCHH/infra-secrets). + +## Guides + +See the following pages for guidance on how to use SOPS: + +- [SOPS: New Host](../guides/sops-new-host.md) +- [SOPS: Storing Secrets](../guides/sops-storing-secrets.md) diff --git a/docs/guides/create-new-web-service-vm.md b/docs/guides/create-new-web-service-vm.md index bf7d65b..ed0974b 100644 --- a/docs/guides/create-new-web-service-vm.md +++ b/docs/guides/create-new-web-service-vm.md @@ -57,7 +57,7 @@ As the first step, we need to make the host known to Ansible. ## Ansible-Pull Configuration -Since you added your host to the `ansible_pull_hosts`, you also need to follow [Setting Up Secrets Using SOPS for a New Host](/docs/setting_up_secrets_using_sops_for_a_new_host.md) before continuing. +Since you added your host to the `ansible_pull_hosts`, you also need to follow [SOPS: New Host](./sops-new-host.md) before continuing. ## Service-specific config diff --git a/docs/guides/setting_up_secrets_using_sops_for_a_new_host.md b/docs/guides/setting_up_secrets_using_sops_for_a_new_host.md deleted file mode 100644 index a0e8935..0000000 --- a/docs/guides/setting_up_secrets_using_sops_for_a_new_host.md +++ /dev/null @@ -1,33 +0,0 @@ -# Setting Up Secrets Using SOPS for a New Host - -Because we're using the `community.sops.sops` vars plugin, the SOPS-encrypted secrets get stored in the inventory. - -1. Create a new age key for Ansible pull on the host. - ``` - age-keygen - ``` - Then add the public key part under `keys.hosts.chaosknoten.age` in [.sops.yaml](../.sops.yaml). -2. Add a new creation rule for the hosts `host_vars` file in the sops config at `.sops.yaml`. - It should probably hold all admin keys plus the host entry you just added. - You can use existing creation rules as a reference. -3. Re-encrypt existing files with the new key (manly `group_var/all.sops.yaml`): `find inventories -name "*.sops.*" | xargs sops updatekeys --yes`. - - If GPG yells at you, follow the instructions in our [password-store](https://git.hamburg.ccc.de/CCCHH/password-store). -4. Create a SOPS secrets file in the `host_vars` subdirectory of the relevant inventory. - The name of the file should be in the format `[HOSTNAME].sops.yaml` to get picked up by the vars plugin and to match the previously created creation rule. - This can be accomplished with a command similar to this: - ``` - sops inventories/[chaosknoten|z9]/host_vars/[HOSTNAME].sops.yaml - ``` -5. With the editor now open, add the secrets you want to store. - Because we're using the `community.sops.sops` vars plugin, the stored secrets will be exposed as Ansible variables. - Also note that SOPS only encrypts the values, not the keys. - When now creating entries, try to adhere to the following variable naming convention: - - Make sure to put the prive age key in here under `ansible_pull__age_private_key`. - - Prefix variable names with `secret__`, if they are intended to be used in a template file or similar. (e.g. `secret__netbox_secret_key: secret_value`) - - Otherwise, if the variable is directly consumed by a role or similar, directly set the variable. (e.g. `netbox__db_password: secret_value`) -6. Now that the secrets are stored, they are exposed as variables and can simply be used like any other variable. - -## GPG Keys - -In order to edit encrypted files, you need all the GPG public keys imported into your GPG Keychain. You should be able to find the necessary public keys in https://git.hamburg.ccc.de/CCCHH/password-store. diff --git a/docs/guides/sops-new-host.md b/docs/guides/sops-new-host.md new file mode 100644 index 0000000..c786e96 --- /dev/null +++ b/docs/guides/sops-new-host.md @@ -0,0 +1,58 @@ +--- +title: "SOPS: New Host" +summary: How to Setup SOPS for a New Host +--- + +# SOPS: New Host + +The following outlines the steps to take for setting up [SOPS](../concepts-and-configurations/sops.md) for a new host (`myservice`). +Every host needs a SOPS configuration as every host should be set up to run ansible-pull. + +1. Create a new age key for ansible-pull for the host: + ``` + age-keygen + ``` +2. Add the public key part to the [`.sops.yaml`](https://git.hamburg.ccc.de/CCCHH/ansible-infra/src/branch/main/.sops.yaml) under: + ```yaml + keys: + # ... + hosts: + chaosknoten: + age: &host_chaosknoten_age_keys + # ... + - &host_myservice_ansible_pull_age_key + ``` + You can use the existing configuration as guidance. + For VMs not on Chaosknoten, choose the appropriate section. +3. Add a new creation rule for the hosts `host_vars` file to the [`.sops.yaml`](https://git.hamburg.ccc.de/CCCHH/ansible-infra/src/branch/main/.sops.yaml). + It should most likely hold all admin keys plus the host entry you just added and look something like this: + ```yaml + creation_rules: + # ... + ## host vars + # chaosknoten hosts + # ... + - path_regex: "inventories/chaosknoten/host_vars/myservice\\.sops\\..+" + key_groups: + - pgp: + *admin_gpg_keys + age: + - *host_myservice_ansible_pull_age_key + ``` + You can use existing creation rules as a reference. + For VMs not on Chaosknoten, choose the appropriate section. +4. Re-encrypt for the newly added key (mainly `group_vars/all.sops.yaml`): + ```bash + find inventories -name "*.sops.*" | xargs sops updatekeys --yes + ``` + If GPG yells at you, follow the instructions in [infra-secrets](https://git.hamburg.ccc.de/CCCHH/infra-secrets). +5. Create a SOPS secrets file in the `host_vars` subdirectory of the relevant inventory. The name of the file should be of the format `.sops.yaml` to get picked up by the vars plugin and to match the previously created creation rule. + For this example the following command accomplishes this: + ``` + sops inventories/chaosknoten/host_vars/myservice.sops.yaml + ``` + - With the editor now open, delete the example content and add the previously generated age private key like this: + ```yaml + ansible_pull__age_private_key: + ``` + Note that SOPS only encrypts the values, not the keys. diff --git a/docs/guides/sops-storing-secrets.md b/docs/guides/sops-storing-secrets.md new file mode 100644 index 0000000..2020837 --- /dev/null +++ b/docs/guides/sops-storing-secrets.md @@ -0,0 +1,29 @@ +--- +title: "SOPS: Storing Secrets" +summary: How to Store Secrets Using SOPS +--- + +# SOPS: Storing Secrets + +Some guidance on how to store secrets using [SOPS](../concepts-and-configurations/sops.md). For a guide on how to setup SOPS for a new host, see [SOPS: New Host](./sops-new-host.md). + +1. For storing host-specific secrets, open the host-specific SOPS file: + ``` + sops inventories//host_vars/.sops.yaml + ``` + For inventory-wide secrets, open the inventories `all` group SOPS file: + ``` + sops inventories//group_vars/all.sops.yaml + ``` +2. Now the secrets can be added to the opened file. Because we're using the `community.sops.sops` vars plugin, the stored secrets will then be exposed as Ansible variables. + Note that SOPS only encrypts the values, not the keys. + When creating entries, try to adhere to the following variable naming conventions: + - Prefix variable names with `secret__`, if they are intended to be used in a template file or similar, e.g.: + ```yaml + secret__netbox_secret_key: secret_value + ``` + - Otherwise, if the variable is directly consumed by a role or similar, directly set the variable, e.g.: + ```yaml + netbox__db_password: secret_value + ``` +3. After closing the editor, the secrets are stored. In Ansible they are exposed as variables and can simply be used like any other variable. From 45b3da6ad0c61a277b2459703b3c4c68d19fec9b Mon Sep 17 00:00:00 2001 From: Renovate Date: Wed, 20 May 2026 17:00:46 +0000 Subject: [PATCH 2/2] Update all stable non-major dependencies --- .forgejo/workflows/lint.yaml | 2 +- inventories/chaosknoten/host_vars/cloud.yaml | 2 +- inventories/chaosknoten/host_vars/netbox.yaml | 2 +- .../chaosknoten/acmedns/docker_compose/compose.yaml.j2 | 2 +- .../chaosknoten/grafana/docker_compose/compose.yaml.j2 | 8 ++++---- .../chaosknoten/keycloak/docker_compose/compose.yaml.j2 | 2 +- resources/chaosknoten/ntfy/docker_compose/compose.yaml.j2 | 2 +- .../chaosknoten/onlyoffice/docker_compose/compose.yaml.j2 | 2 +- .../chaosknoten/pretalx/docker_compose/compose.yaml.j2 | 4 ++-- .../chaosknoten/tickets/docker_compose/compose.yaml.j2 | 2 +- resources/external/status/docker_compose/compose.yaml.j2 | 4 ++-- 11 files changed, 16 insertions(+), 16 deletions(-) diff --git a/.forgejo/workflows/lint.yaml b/.forgejo/workflows/lint.yaml index bdd53f5..600d044 100644 --- a/.forgejo/workflows/lint.yaml +++ b/.forgejo/workflows/lint.yaml @@ -24,7 +24,7 @@ jobs: # work in our environmnet. # Rather manually setup python (pip) before instead. - name: Run ansible-lint - uses: https://github.com/ansible/ansible-lint@v26.3.0 + uses: https://github.com/ansible/ansible-lint@v26.4.0 with: setup_python: "false" requirements_file: "requirements.yml" diff --git a/inventories/chaosknoten/host_vars/cloud.yaml b/inventories/chaosknoten/host_vars/cloud.yaml index 9c28d58..1cf8b4f 100644 --- a/inventories/chaosknoten/host_vars/cloud.yaml +++ b/inventories/chaosknoten/host_vars/cloud.yaml @@ -1,7 +1,7 @@ # renovate: datasource=docker depName=git.hamburg.ccc.de/ccchh/oci-images/nextcloud nextcloud__version: 32 # renovate: datasource=docker depName=docker.io/library/postgres -nextcloud__postgres_version: 15.17 +nextcloud__postgres_version: 15.18 nextcloud__fqdn: cloud.hamburg.ccc.de nextcloud__data_dir: /data/nextcloud nextcloud__extra_configuration: "{{ lookup('ansible.builtin.template', 'resources/chaosknoten/cloud/nextcloud/extra_configuration.config.php.j2') }}" diff --git a/inventories/chaosknoten/host_vars/netbox.yaml b/inventories/chaosknoten/host_vars/netbox.yaml index f28d193..7aaff28 100644 --- a/inventories/chaosknoten/host_vars/netbox.yaml +++ b/inventories/chaosknoten/host_vars/netbox.yaml @@ -1,5 +1,5 @@ # renovate: datasource=github-releases depName=netbox packageName=netbox-community/netbox -netbox__version: "v4.5.5" +netbox__version: "v4.6.1" netbox__config: "{{ lookup('ansible.builtin.template', 'resources/chaosknoten/netbox/netbox/configuration.py.j2') }}" netbox__custom_pipeline_oidc_group_and_role_mapping: true diff --git a/resources/chaosknoten/acmedns/docker_compose/compose.yaml.j2 b/resources/chaosknoten/acmedns/docker_compose/compose.yaml.j2 index 3fcd8c6..c68973f 100644 --- a/resources/chaosknoten/acmedns/docker_compose/compose.yaml.j2 +++ b/resources/chaosknoten/acmedns/docker_compose/compose.yaml.j2 @@ -2,7 +2,7 @@ services: oauth2-proxy: container_name: oauth2-proxy - image: quay.io/oauth2-proxy/oauth2-proxy:v7.15.1 + image: quay.io/oauth2-proxy/oauth2-proxy:v7.15.2 command: --config /oauth2-proxy.cfg hostname: oauth2-proxy volumes: diff --git a/resources/chaosknoten/grafana/docker_compose/compose.yaml.j2 b/resources/chaosknoten/grafana/docker_compose/compose.yaml.j2 index 1f6c42f..44dfa20 100644 --- a/resources/chaosknoten/grafana/docker_compose/compose.yaml.j2 +++ b/resources/chaosknoten/grafana/docker_compose/compose.yaml.j2 @@ -2,7 +2,7 @@ services: prometheus: - image: docker.io/prom/prometheus:v3.10.0 + image: docker.io/prom/prometheus:v3.11.3 container_name: prometheus command: - '--config.file=/etc/prometheus/prometheus.yml' @@ -19,7 +19,7 @@ services: - prom_data:/prometheus alertmanager: - image: docker.io/prom/alertmanager:v0.31.1 + image: docker.io/prom/alertmanager:v0.32.1 container_name: alertmanager command: - '--config.file=/etc/alertmanager/alertmanager.yaml' @@ -46,7 +46,7 @@ services: - graf_data:/var/lib/grafana pve-exporter: - image: docker.io/prompve/prometheus-pve-exporter:3.8.2 + image: docker.io/prompve/prometheus-pve-exporter:3.9.0 container_name: pve-exporter ports: - 9221:9221 @@ -59,7 +59,7 @@ services: - /dev/null:/etc/prometheus/pve.yml loki: - image: docker.io/grafana/loki:3.7.1 + image: docker.io/grafana/loki:3.7.2 container_name: loki ports: - 13100:3100 diff --git a/resources/chaosknoten/keycloak/docker_compose/compose.yaml.j2 b/resources/chaosknoten/keycloak/docker_compose/compose.yaml.j2 index d239bb4..8db3526 100644 --- a/resources/chaosknoten/keycloak/docker_compose/compose.yaml.j2 +++ b/resources/chaosknoten/keycloak/docker_compose/compose.yaml.j2 @@ -22,7 +22,7 @@ services: keycloak: - image: git.hamburg.ccc.de/ccchh/oci-images/keycloak:26.5.7 + image: git.hamburg.ccc.de/ccchh/oci-images/keycloak:26.6.0 pull_policy: always restart: unless-stopped command: start --optimized diff --git a/resources/chaosknoten/ntfy/docker_compose/compose.yaml.j2 b/resources/chaosknoten/ntfy/docker_compose/compose.yaml.j2 index af1b531..cadfa54 100644 --- a/resources/chaosknoten/ntfy/docker_compose/compose.yaml.j2 +++ b/resources/chaosknoten/ntfy/docker_compose/compose.yaml.j2 @@ -1,7 +1,7 @@ --- services: ntfy: - image: docker.io/binwiederhier/ntfy:v2.20.1 + image: docker.io/binwiederhier/ntfy:v2.23.0 container_name: ntfy command: - serve diff --git a/resources/chaosknoten/onlyoffice/docker_compose/compose.yaml.j2 b/resources/chaosknoten/onlyoffice/docker_compose/compose.yaml.j2 index 77f1395..58dddb2 100644 --- a/resources/chaosknoten/onlyoffice/docker_compose/compose.yaml.j2 +++ b/resources/chaosknoten/onlyoffice/docker_compose/compose.yaml.j2 @@ -4,7 +4,7 @@ services: onlyoffice: - image: docker.io/onlyoffice/documentserver:9.3.1 + image: docker.io/onlyoffice/documentserver:9.4.0 restart: unless-stopped volumes: - "./onlyoffice/DocumentServer/logs:/var/log/onlyoffice" diff --git a/resources/chaosknoten/pretalx/docker_compose/compose.yaml.j2 b/resources/chaosknoten/pretalx/docker_compose/compose.yaml.j2 index 0bbfcb8..226b21d 100644 --- a/resources/chaosknoten/pretalx/docker_compose/compose.yaml.j2 +++ b/resources/chaosknoten/pretalx/docker_compose/compose.yaml.j2 @@ -15,7 +15,7 @@ services: - pretalx_net redis: - image: docker.io/library/redis:8.6.2 + image: docker.io/library/redis:8.6.3 restart: unless-stopped volumes: - redis:/data @@ -23,7 +23,7 @@ services: - pretalx_net static: - image: docker.io/library/nginx:1.29.7 + image: docker.io/library/nginx:1.31.0 restart: unless-stopped volumes: - public:/usr/share/nginx/html diff --git a/resources/chaosknoten/tickets/docker_compose/compose.yaml.j2 b/resources/chaosknoten/tickets/docker_compose/compose.yaml.j2 index b8a4cf2..11593ce 100644 --- a/resources/chaosknoten/tickets/docker_compose/compose.yaml.j2 +++ b/resources/chaosknoten/tickets/docker_compose/compose.yaml.j2 @@ -13,7 +13,7 @@ services: restart: unless-stopped redis: - image: docker.io/library/redis:8.6.2 + image: docker.io/library/redis:8.6.3 ports: - "6379:6379" volumes: diff --git a/resources/external/status/docker_compose/compose.yaml.j2 b/resources/external/status/docker_compose/compose.yaml.j2 index 58abefa..638ebbe 100644 --- a/resources/external/status/docker_compose/compose.yaml.j2 +++ b/resources/external/status/docker_compose/compose.yaml.j2 @@ -4,7 +4,7 @@ services: database: - image: docker.io/library/postgres:18.3 + image: docker.io/library/postgres:18.4 restart: always volumes: - ./database:/var/lib/postgresql @@ -16,7 +16,7 @@ services: - gatus gatus: - image: ghcr.io/twin/gatus:v5.35.0 + image: ghcr.io/twin/gatus:v5.36.0 restart: always ports: - "8080:8080"