From 465cfa76d26f464ce2bc59015e40aa8c527551e6 Mon Sep 17 00:00:00 2001 From: Erich Blume Date: Sun, 25 Jan 2026 09:31:25 -0800 Subject: [PATCH] Fix Caddy DNS plugin syntax and add wrapper script - Use correct Gandi DNS syntax: dns gandi {env.VAR} (not nested block) - Add wrapper script to load token from file into environment variable - Update LaunchAgent to use wrapper script Caddy now successfully obtains Let's Encrypt wildcard certs via DNS-01. Co-Authored-By: Claude Opus 4.5 --- ansible/roles/caddy/tasks/main.yml | 7 +++++++ ansible/roles/caddy/templates/Caddyfile.j2 | 13 ++----------- ansible/roles/caddy/templates/caddy-wrapper.sh.j2 | 6 ++++++ ansible/roles/caddy/templates/caddy.plist.j2 | 5 +---- 4 files changed, 16 insertions(+), 15 deletions(-) create mode 100644 ansible/roles/caddy/templates/caddy-wrapper.sh.j2 diff --git a/ansible/roles/caddy/tasks/main.yml b/ansible/roles/caddy/tasks/main.yml index 3ca986d..456474c 100644 --- a/ansible/roles/caddy/tasks/main.yml +++ b/ansible/roles/caddy/tasks/main.yml @@ -52,6 +52,13 @@ mode: "0644" notify: Restart caddy +- name: Deploy caddy wrapper script + ansible.builtin.template: + src: caddy-wrapper.sh.j2 + dest: "{{ caddy_config_dir }}/caddy-wrapper.sh" + mode: "0755" + notify: Restart caddy + - name: Deploy caddy LaunchAgent plist ansible.builtin.template: src: caddy.plist.j2 diff --git a/ansible/roles/caddy/templates/Caddyfile.j2 b/ansible/roles/caddy/templates/Caddyfile.j2 index 2af6e28..455b49c 100644 --- a/ansible/roles/caddy/templates/Caddyfile.j2 +++ b/ansible/roles/caddy/templates/Caddyfile.j2 @@ -7,19 +7,12 @@ { # Global options admin off - - # Use ACME DNS-01 challenge with Gandi - acme_dns gandi { - api_token {file.{{ caddy_gandi_token_file }}} - } } # Wildcard certificate for all services *.{{ caddy_domain }}:{{ caddy_https_port }} { tls { - dns gandi { - api_token {file.{{ caddy_gandi_token_file }}} - } + dns gandi {env.GANDI_BEARER_TOKEN} } {% for service in caddy_services %} @@ -38,9 +31,7 @@ # Base domain (ops.eblu.me) {{ caddy_domain }}:{{ caddy_https_port }} { tls { - dns gandi { - api_token {file.{{ caddy_gandi_token_file }}} - } + dns gandi {env.GANDI_BEARER_TOKEN} } respond "blumeops services - use a subdomain (e.g., forge.{{ caddy_domain }})" diff --git a/ansible/roles/caddy/templates/caddy-wrapper.sh.j2 b/ansible/roles/caddy/templates/caddy-wrapper.sh.j2 new file mode 100644 index 0000000..72308f2 --- /dev/null +++ b/ansible/roles/caddy/templates/caddy-wrapper.sh.j2 @@ -0,0 +1,6 @@ +#!/bin/bash +# Wrapper script for Caddy that loads the Gandi token from file +# Managed by ansible - do not edit manually + +export GANDI_BEARER_TOKEN=$(cat {{ caddy_gandi_token_file }}) +exec {{ caddy_binary }} run --config {{ caddy_config_dir }}/Caddyfile diff --git a/ansible/roles/caddy/templates/caddy.plist.j2 b/ansible/roles/caddy/templates/caddy.plist.j2 index e28ae10..ec36c9e 100644 --- a/ansible/roles/caddy/templates/caddy.plist.j2 +++ b/ansible/roles/caddy/templates/caddy.plist.j2 @@ -7,10 +7,7 @@ ProgramArguments - {{ caddy_binary }} - run - --config - {{ caddy_config_dir }}/Caddyfile + {{ caddy_config_dir }}/caddy-wrapper.sh WorkingDirectory