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

apt_upgrade: true
- nginx
- add-apt-repository ppa:certbot/certbot -y
- apt-get update
- apt install python-certbot-nginx -y
# add renewal cron
- 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;


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.

Mercurial SSH with TeamCity on Ubuntu

When running TeamCity in docker, I recently had to setup ssh with Mercurial on Bitbucket.org which isn’t built in to TeamCity.

This is so I don’t forgot how I did it! Ideally you could do this with your own container – which is a better option!

  • SSH to the TeamCity Server
  • Type sudo docker ps
  • Type sudo docker exec -it xxx (your container id) /bin/bash
  • Type apt-get install vim
  • Type cd ~/.ssh
  • Type touch teamcity
  • Type vim teamcity
  • Add the private ssh key – using the Open-SSH key format – that you want to communicate with Mercurial – you should add the public key to Bitbucket.org.
  • Save the file
  • Type touch config
    Add the following:
    Host bitbucket.org
    IdentityFile ~/.ssh/teamcity
  • Save the file
  • Type chmod 400 ~/.ssh/teamcity
  • Type ssh hg@bitbucket.org
  • Accept the thumbprint – you should see that you can connect
  • Type exit

You should be able to connect via ssh to your Mercurial repository from TeamCity now!

TeamCity should have the following in the
Pull Changes From url: ssh://bitbucket.org/repository
Username: hg