- Add dkim_sync.yml: generates DKIM keys for all mail_domains, writes keys to stack config (group_vars/all/dkim.yml), and publishes mail._domainkey TXT records via dns.yml — replaces manual vault editing - Remove dkim_keys from vault.yml.setup (public keys don't need encryption) - Add hcloud_labels to config.yml.setup and apply to server + SSH key in provision role, enabling project-level tagging of Hetzner resources - Fix setup.sh next steps: add missing bootstrap step, replace manual DKIM instructions with dkim_sync.yml - Update CLAUDE.md and README.md accordingly Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
72 lines
2.9 KiB
YAML
72 lines
2.9 KiB
YAML
---
|
|
# Fetch DKIM public keys from the running mailserver and publish them to DNS.
|
|
#
|
|
# Safe to re-run — only generates keys for domains that don't have one yet.
|
|
# Run after the first mail deployment:
|
|
# ansible-playbook playbooks/dkim_sync.yml
|
|
#
|
|
# What it does:
|
|
# 1. Generates DKIM keys for any domain missing one (skips existing keys)
|
|
# 2. Discovers each domain's key file at runtime via find — the algorithm prefix
|
|
# (rsa-2048-..., ed25519-...) may vary across docker-mailserver versions,
|
|
# but the *<domain>.public.dns.txt suffix is stable
|
|
# 3. Writes $LINDERHOF_DIR/group_vars/all/dkim.yml (plain file — DKIM keys are public)
|
|
# 4. Runs dns.yml to create/update mail._domainkey TXT records for all domains
|
|
|
|
- name: Fetch DKIM keys from mailserver
|
|
hosts: all
|
|
gather_facts: false
|
|
|
|
tasks:
|
|
- name: Check for existing DKIM key files
|
|
# /srv/mail/config is the host-side mount of /tmp/docker-mailserver in the container
|
|
command: find /srv/mail/config/rspamd/dkim -name "*{{ item }}.public.dns.txt" -type f
|
|
loop: "{{ mail_domains }}"
|
|
register: dkim_existing
|
|
changed_when: false
|
|
failed_when: false
|
|
|
|
- name: Generate DKIM keys for domains without existing keys
|
|
command: docker exec mailserver setup config dkim
|
|
when: dkim_existing.results | selectattr('stdout', 'equalto', '') | list | length > 0
|
|
changed_when: true
|
|
|
|
- name: Find DKIM DNS TXT key file for each domain
|
|
command: find /srv/mail/config/rspamd/dkim -name "*{{ item }}.public.dns.txt" -type f
|
|
loop: "{{ mail_domains }}"
|
|
register: dkim_file_paths
|
|
changed_when: false
|
|
|
|
- name: Read DKIM public key for each domain
|
|
slurp:
|
|
src: "{{ item.stdout | trim }}"
|
|
loop: "{{ dkim_file_paths.results }}"
|
|
loop_control:
|
|
label: "{{ item.item }}"
|
|
register: dkim_keys_raw
|
|
|
|
- name: Build dkim_keys dict
|
|
set_fact:
|
|
dkim_keys_collected: >-
|
|
{{ dkim_keys_collected | default({}) | combine({item.item.item: item.content | b64decode | trim}) }}
|
|
loop: "{{ dkim_keys_raw.results }}"
|
|
loop_control:
|
|
label: "{{ item.item.item }}"
|
|
|
|
- name: Write dkim.yml to stack config directory
|
|
delegate_to: localhost
|
|
become: false
|
|
# Written to a separate dkim.yml rather than config.yml so this playbook can safely
|
|
# overwrite it without touching the hand-edited config. Ansible loads all files under
|
|
# group_vars/all/ automatically, so dkim_keys is available to all roles either way.
|
|
copy:
|
|
content: |
|
|
---
|
|
# DKIM public keys — written automatically by dkim_sync.yml, do not edit manually
|
|
dkim_keys:
|
|
{% for domain_name, key in dkim_keys_collected.items() %}
|
|
{{ domain_name }}: "{{ key }}"
|
|
{% endfor %}
|
|
dest: "{{ lookup('env', 'ANSIBLE_INVENTORY') | dirname }}/group_vars/all/dkim.yml"
|
|
|
|
- import_playbook: dns.yml
|