Automatically generating and renewing Let's Encrypt SSL certificates with the certbot client and Ansible
I just finished updating my ansible-django-stack project and added tasks to automatically issue a Let's Encrypt SSL certificate and set up a cron job to auto-renew the certificate.
We're now using it for all our Shopify apps which are built in Django. Let's Encrypt certificates are only valid for 90 days, so if you have a bunch of web apps like we do and have more planned in the future, automating this process now could save a lot of time down the line.
Let's Encrypt made automation easy with their certbot client. You can easily generate and renew SSL certificates with simple one-line commands.
This Ansible playbook is quite simple. It basically just downloads the certbot script and executes a command with non-interactive options to generate the cert. Then a cron job is scheduled to run daily and execute the renew command.
A few things to note before using this playbook:
- A DNS "A" or "CNAME" record must exist for the host you're issuing the certificate to. Let's Encrypt uses this to validate you own the domain.
- The --standalone option is used, which uses a "standalone" web server which binds to port 80 or 443, so these ports must not be in use. The playbook takes care of this automatically by first checking if Nginx is installed and stopping the service automatically before generating the certificate, and then restarted again.
- The auto-renew cron job is scheduled to run daily and also configured to automatically stop and start Nginx. The command will actually not do anything unless the certificate is due for renewal (i.e. expiring in less than 30 days), so it's ok to run this frequently without worrying about Nginx restarting every time.
Here's the link again to the playbook: https://github.com/jcalazan/ansible-django-stack