Using certbot with Ansible

Posted 08.11.2020 · 3 min read

I have been using acme-tiny and a custom shell script for renewal of my ssl certificates for a couple of years now. Over the years I have been adding more and more sites which has made the instability of this setup more and more apparent. This eventually got me to look into alternatives. According to Let's Encrypts getting started guide it is recommended to use certbot.

Certbot is pretty versatile tool in the way that it support multiple webservers and multiple verification options in various degrees of automation. I do want some level of control since I am running with nginx configs generated with Ansible. The issue here is that if certbot is allowed to do everything it would alter the nginx config of the different sites. This would in turn make the next deployment with Ansible overwrite certbots changes. Thus, I choose to use the certonly option in certbot.

Let's get started with the installation and main setup before diving into how to use it for a given site. The following Ansible tasks first installs certbot with pip. It is possible to use apt or other linux package managers, however, I found this to be working more nicely on arm based hardware like Raspberry Pis. The register task is to accept the terms of use of letsencrypt. It will also create the account private key used in the verification step. Furthermore, I add a file /etc/letsencrypt/.registered this is just to make sure ansible does not run this command every time. Finally, the cronjob for renewal is set up.

- name: Install certbot
pip:
name:
- certbot
- certbot-nginx
executable: pip3
tags:
- nginx
- certbot
- name: Register certbot
shell: |
certbot -n register --agree-tos --email [email protected]
touch /etc/letsencrypt/.registered
args:
creates: /etc/letsencrypt/.registered
tags:
- nginx
- certbot
- name: Setup cronjob for renewal
cron:
name: certbot-renewal
job: "/bin/bash -lc '/usr/local/bin/certbot -q renew'"
minute: "0"
hour: "14"
tags:
- nginx
- certbot

With this in place we can dive into how to get certificates for a given domain. The Ansible task below runs the command for getting a certificate verified with callback nginx, but without changing anything permanently. This means that the nginx config needs to be updated to use the certificates. The result of the command is certificates and keys stored inside the directory /etc/letsencrypt/live/{{ hostname }}.

- name: 'Get certificate'
command: '/usr/local/bin/certbot -n --nginx certonly -d {{ hostname }}'
args:
creates: '/etc/letsencrypt/live/{{ hostname }}'
ignore_errors: true
tags:
- nginx
- certbot

After this we can add the certificates to the nginx config. This part would be automatic if the task above did not include certonly.

ssl_certificate_key /etc/letsencrypt/live/{{ hostname }}/privkey.pem;
ssl_certificate /etc/letsencrypt/live/{{ hostname }}/fullchain.pem;

That is all that is needed to have an automated certificate setup with auto-renewal.