aha
By:
aha

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

July 27, 2017 456 views
Let's Encrypt Nginx Ubuntu

Assuming you already have a top-level domain setup on DigitalOcean (e.g.: mysite.com) 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 mysite.com, you'll end up with a properly configured https://mydroplet.mysite.com that gets an A on the SSLabs test.

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

#cloud-config
packages:
  - nginx
  #jq is a command-line json processor https://stedolan.github.io/jq/
  - jq
  - unattended-upgrades
runcmd:
  - export DOMAIN=your_domain_here.com
  - export DO_API_TOKEN=PASTE_YOUR_DIGITALOCEAN_API_TOKEN_HERE
  - export PUBLIC_IPV4=$(curl -s http://169.254.169.254/metadata/v1/interfaces/public/0/ipv4/address)
  - export DROPLET_ID=$(curl -s http://169.254.169.254/metadata/v1/id)
  - export DROPLET_NAME=$(curl -s http://169.254.169.254/metadata/v1/hostname)
  # get the email for letsencrypt from do api
  - 'export EMAIL=$(curl -X GET -H "Content-Type: application/json" -H "Authorization: Bearer $DO_API_TOKEN"  https://api.digitalocean.com/v2/account  | jq -r ".account.email")'
  # 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"  https://api.digitalocean.com/v2/floating_ips  | 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\"}" https://api.digitalocean.com/v2/domains/$DOMAIN/records'
  - sleep 30s
  - certbot --nginx -n -d $DROPLET_NAME"."$DOMAIN --email $EMAIL --agree-tos --redirect --hsts
  - sudo openssl dhparam -out /etc/ssl/certs/dhparam.pem 2048
  # write ssl_dhparam directive to nginx config
  - sed -i 's/server_name/ssl_dhparam \/etc\/ssl\/certs\/dhparam.pem;\n\tserver_name/' /etc/nginx/sites-available/default
  - systemctl reboot
# add renewal cron
write_files:
  - owner: root:root
    path: /etc/cron.d/letsencrypt_renew
    content: "15 3 * * * /usr/bin/certbot renew --quiet"
Be the first one to answer this question.