Skip to content

fix: make letsencrypt and mail recipes idempotent on redeploy#5

Draft
troglodyne wants to merge 1 commit into
masterfrom
koan.trogbot/fix-redeploy-idempotency
Draft

fix: make letsencrypt and mail recipes idempotent on redeploy#5
troglodyne wants to merge 1 commit into
masterfrom
koan.trogbot/fix-redeploy-idempotency

Conversation

@troglodyne

Copy link
Copy Markdown
Contributor

What

Fix 7 non-idempotent operations in letsencrypt.tt and mail.tt that cause failures or data loss when the provisioner is re-run against an existing system.

Why

Issue #1 calls out that provisioners need to be safe for shared-environment / existing-system deploys. Two of the most critical problems are explicitly named: letsencrypt deleting account credentials and mail stomping configs it already owns.

Re-running a provisioner is a normal operation (updating config, adding a domain). These bugs make it actively destructive.

How

letsencrypt.ttrm -rf /var/lib/dehydrated/accounts was unconditional. Replaced with: check if accounts is a real directory (not already a symlink), migrate contents to /etc/dehydrated/accounts, then remove and symlink. Idempotent on subsequent runs.

mail.tt — Six fixes:

  • mv /etc/opendkim.conf /etc/opendkim.conf.orig → guarded with [ -f .orig ] || so the original system file is preserved across redeployments, not overwritten with our last provisioned version
  • Same guard for opendmarc.conf and postfix/master.cf.orig
  • mkdir /var/spool/postfix/opendkimmkdir -p (fails without -p on second run)
  • Same for opendmarc spool dir
  • mv /etc/dovecot/conf.d /etc/dovecot/conf-available → guarded so redeploy doesn't nest our managed conf.d inside conf-available

Testing

No test suite in this project. Changes verified by diff review — all guards follow the same pattern already used in pdns.tt (line 37: mv ... ; /bin/true and mkdir -p) and matrix.tt (line 21: if [...]; then \ ... fi backslash-continuation pattern for multi-line shell in Make recipes).

letsencrypt.tt: Replace unconditional rm -rf of /var/lib/dehydrated/accounts
with a migration+symlink approach. On first run with a real directory, contents
are copied to /etc/dehydrated/accounts before removal. Subsequent runs detect
the symlink and skip entirely. Prevents losing LE account credentials on redeploy
which would force re-registration and risk hitting rate limits.

mail.tt: Fix six non-idempotent operations that fail or corrupt state on second run:
- Guard .orig backups for opendkim.conf, opendmarc.conf, postfix/master.cf
  so the original system file is preserved across redeployments
- Add -p to mkdir for postfix/opendkim and postfix/opendmarc spool dirs
- Guard dovecot conf.d → conf-available migration to avoid nesting on redeploy

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Comment thread templates/mail.tt
postconf -e -- "smtpd_relay_restrictions = permit_mynetworks, permit_sasl_authenticated, reject_unauth_destination"
# master.cf shenanigans
mv /etc/postfix/master.cf /etc/postfix/master.cf.orig
[ -f /etc/postfix/master.cf.orig ] || mv /etc/postfix/master.cf /etc/postfix/master.cf.orig

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe should timestamp these backups instead?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

agree. I wonder if there's a program that does this for us, e.g. backup $file. If not we may want one in $SCRIPT_DIR

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants