LetsEncrypt with Nginx using Terraform & Azure

I’ve been doing quite a bit of work with Terraform & Azure recently.  One requirement is to use Nginx with SSL termination.  Rather than buy a certificate all the time I chose to use https://letsencrypt.org/ which plugs nicely in to nginx.

The full repository can be found here – https://github.com/datoon83/letsencrypt-terraform

I’ve used cloud init config to install nginx and certbot which essentially create & retrieves certificates from LetsEncrypt and updates the nginx config with the relevant entries.  There is also a cron.d job which runs to update the certificates whenever they are close to expiring, LetsEncrypt certificates expire in 90 days.

Below is the cloud init config that is used.

Cloud Init Config

#cloud-config
apt_upgrade: true
packages:
- nginx
runcmd:
- add-apt-repository ppa:certbot/certbot -y
- apt-get update
- apt install python-certbot-nginx -y
# add renewal cron
write_files:
- owner: root:root
path: /etc/cron.d/letsencrypt_renew
content: "15 3 * * * /usr/bin/certbot renew --quiet"

Nginx Config

We then need to create the nginx.conf setup for the site.  I’ve snipped the rest of the nginx.conf – the important bit is that we have the server_name to match the domain we are issuing the certificate to.

The full config can be found here – https://github.com/datoon83/letsencrypt-terraform/blob/master/files/nginx.conf:

server {
server_name dns-name.com;
location / {
proxy_pass http://${backend_ip}:80;
}
client_max_body_size 0;
}
}

Terraform

We then use Terraform to create our VM, and provision with the following:

provisioner "file" {
content = "${data.template_file.nginx_config.rendered}"
destination = "/tmp/nginx.conf"
}

provisioner "remote-exec" {
inline = [
"cloud-init status --wait",
"sudo mv -f /tmp/nginx.conf /etc/nginx/nginx.conf",
"sudo service nginx start",
"sudo service nginx reload",
"sleep 30s",
"sudo certbot --nginx -n -d dns-name.com --email your-email@test.com --agree-tos --redirect --hsts",
"(sleep 5 && reboot)&"
]}

  1. Waits for the cloud init config to run
  2. Moves the nginx.conf from the tmp folder to the nginx folder
    • You have to do this as, Terraform doesn’t have permissions to write to the nginx folder
  3. Start the service & reload with the relevant configuration
  4. Wait for nginx to start
  5. Then use certbot to create the certificates using LetsEncrypt
    • This will update the nginx.conf with the relevant certificate and download the certs
  6. Reboot the box

As you can see it’s pretty easy to setup, and now you have encrypted traffic to your Nginx box.

Leave a Reply

Your email address will not be published. Required fields are marked *