For systems using nginx, HAProxy, or similar software that needs a local certificate, automating certificate management for your DNS provider is crucial. Let’s take a look at how to set up Certbot with AWS Route53 for domain validation and certificate renewal.
Certbot saves the renewal settings at issuance, so the current version relies on that saved configuration instead of rebuilding the command in every scheduled run.
Install Packaged Components
On current Debian or Ubuntu releases I install Certbot and its plugin from the same package source:
sudo apt update
sudo apt install certbot python3-certbot-dns-route53
This avoids the mixed apt/pip environment from my original setup. Certbot lists the DNS plugins and their installation paths in its official instructions.
Give Route53 Access
On EC2 I prefer an instance profile/IAM role. Elsewhere I use a dedicated IAM principal and a root-only AWS credentials file:
sudo install -d -m 700 /root/.aws
sudoedit /root/.aws/credentials
sudo chmod 600 /root/.aws/credentials
[default]
aws_access_key_id=REPLACE_ME
aws_secret_access_key=REPLACE_ME
These credentials can change DNS. I scope them to the required hosted zone and keep them readable only by root; an IAM role avoids a long-lived file entirely.
The minimal actions are listing hosted zones plus changing and inspecting record sets. I restrict the change action to the hosted-zone ARN and, where practical, to _acme-challenge TXT records using IAM condition keys. AWS documents the exact required permissions in the Certbot Route53 plugin and Route53 IAM condition-key reference.
Issue Once
sudo certbot certonly --dns-route53 \
--cert-name example.com \
-d example.com -d '*.example.com' \
-m admin@example.com --agree-tos --no-eff-email
Certbot saves the authenticator and domains in /etc/letsencrypt/renewal/example.com.conf, so normal renewal does not need the issuance flags repeated.
If the service needs a reload after a successful renewal, I use a deploy hook. It runs only after a certificate was actually renewed:
sudo install -d -m 755 /etc/letsencrypt/renewal-hooks/deploy
sudoedit /etc/letsencrypt/renewal-hooks/deploy/reload-nginx
sudo chmod 755 /etc/letsencrypt/renewal-hooks/deploy/reload-nginx
#!/usr/bin/env sh
systemctl reload nginx
Test and Automate Renewal
sudo certbot renew --dry-run
systemctl list-timers 'certbot*'
systemctl status certbot.timer
Packaged Certbot normally provides a systemd timer; I use that instead of choosing my own 89-day interval. Let’s Encrypt recommends checking at least daily because Certbot itself renews only certificates that are due. Certbot renewal
For a system without systemd, the small cron fallback is:
17 3 * * * root certbot renew --quiet
The non-round minute avoids everyone hitting the service at midnight. The saved renewal configuration selects Route53, and the deploy hook reloads nginx only on success.
Buy Me a Coffee