Configless Certbot Timer

Replace opaque LetsEncrypt certbot system configuration with a single timer commandline.

The setup of Certbot – i.e., for updating Let’s Encrypt certificates – can be considered quite opaque and tailored towards apparent simplicity. Configuration files or accounts that store interactive wizard results or the last state might be convenient but lack deployment reproducability and are not “declarative”. Also, so-called plugins (such as --nginx) implicitly replace webserver configuration files. Luckily, the whole certificate retrieval/update process can be replaced with a single one-shot command instead.

For example, a local nginx setup could be configured like:

root /var/www/html; # contains .well-known directory
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;

The default /usr/lib/systemd/system/certbot.service simply runs certbot -q renew, which relies on external state. With the drop-in /etc/systemd/system/certbot.service.d/certonly.conf, all needed flags can be provided in a standalone commandline instead:

[Service]
ExecStart=
ExecStart=/usr/bin/certbot certonly \
    --text --non-interactive --max-log-backups 0 \
    --no-self-upgrade --agree-tos \
    --keep-until-expiring --expand \
    --rsa-key-size 4096 \
    --no-directory-hooks \
    --webroot -w /var/www/html \
    --email nobody@example.com \
    --cert-name example.com \
    -d example.com -d www.example.com
ExecStartPost=-/bin/systemctl try-restart nginx.service

Optionally, a drop-in /etc/systemd/system/certbot.timer.d/weekly.conf can reduce the daily checks and webserver restarts to weekly:

[Timer]
OnCalendar=
OnCalendar=weekly

This systemd-drop-in approach preserves existing configuration and can be considered relatively “ansible friendly”.