Using cloud-init to automate the Let's Encrypt process on new Ubuntu/nginx droplets

Assuming you already have a top-level domain setup on DigitalOcean (e.g.: the script below will (for Ubuntu Droplets):

  1. Install nginx and Let’s Encrypt
  2. Create a DigitalOcean Floating IP pointing at the droplet.
  3. Update your top-level domain’s DNS record to point a new subdomain at the droplet, based on the droplet name.
  4. Use Let’s Encrypt (certbot) to generate SSL certs for the domain
  5. Setup a cron job to renew certs periodically.

Using cloud-config.

So if you paste this in to the User-Data section when creating a droplet named mydroplet and you have a domain, you’ll end up with a properly configured that gets an A on the SSLabs test.

The only thing you need to change in the script below is to set the DO_API_TOKEN env variable to your token, and DOMAIN to the top-level domain you already have setup in the DO control panel.

  - nginx
  #jq is a command-line json processor
  - jq
  - unattended-upgrades
  - export
  - export PUBLIC_IPV4=$(curl -s
  - export DROPLET_ID=$(curl -s
  - export DROPLET_NAME=$(curl -s
  # get the email for letsencrypt from do api
  - 'export EMAIL=$(curl -X GET -H "Content-Type: application/json" -H "Authorization: Bearer $DO_API_TOKEN"  | jq -r "")'
  # install certbot, update
  - add-apt-repository ppa:certbot/certbot -y
  - apt-get update
  - apt install python-certbot-nginx -y
  # add domain name to nginx config, restart it
  - sed -i 's/server_name _;/server_name '$DROPLET_NAME"."$DOMAIN';/' /etc/nginx/sites-available/default
  - systemctl restart nginx
  # create a floating ip
  - 'export FLOATING_IP=$(curl -X POST -H ''Content-Type: application/json'' -d ''{"droplet_id":"''"$DROPLET_ID"''"}'' -H "Authorization: Bearer $DO_API_TOKEN"  | jq -r ".floating_ip.ip")'
  # create a subdomain a-record for this droplet
  - 'curl -X POST -H "Content-Type: application/json" -H "Authorization: Bearer $DO_API_TOKEN" -d "{\"type\":\"A\", \"name\":\"$DROPLET_NAME\", \"data\":\"$FLOATING_IP\"}"$DOMAIN/records'
  - sleep 30s
  - certbot --nginx -n -d $DROPLET_NAME"."$DOMAIN --email $EMAIL --agree-tos --redirect --hsts
  - systemctl reboot
# add renewal cron
  - owner: root:root
    path: /etc/cron.d/letsencrypt_renew
    content: "15 3 * * * /usr/bin/certbot renew --quiet"
Show comments

Submit an answer

This textbox defaults to using Markdown to format your answer.

You can type !ref in this text area to quickly search our full set of tutorials, documentation & marketplace offerings and insert the link!

Sign In or Sign Up to Answer