2016-01-22

A cron job to (re-)issue server certificate of Let's Encrypt and update ELB's certificate on Amazon Linux

See ymkjp/elb_update_cert if you prefer source code but not messy human document :p

Updated at 2016-01-23: Amazon launched AWS Certificate Manager. It should be the easiest way to use certificate on ELB. See more detail at New – AWS Certificate Manager – Deploy SSL/TLS-Based Apps on AWS | AWS Official Blog.

Step 0: Create AWS environment


Omitting description to set up VPC, EC2, ELB...


Step 1: Create new policy for the batch script


Firstly, go to https://console.aws.amazon.com/iam/home.

Select Policies > Create Policy > Create Your Own Policy > Set Permissions.

Let's name the policy whatever you want, for example letsencrypt-aws, and fill following JSON to "Policy Document":

{
    "Version": "2016-01-20",
    "Statement": [
        {
            "Sid": "",
            "Effect": "Allow",
            "Action": [
                "elasticloadbalancing:DescribeLoadBalancers",
                "elasticloadbalancing:SetLoadBalancerListenerSSLCertificate"
            ],
            "Resource": [
                "*"
            ]
        },
        {
            "Sid": "",
            "Effect": "Allow",
            "Action": [
                "iam:ListServerCertificates",
                "iam:UploadServerCertificate",
                "iam:DeleteServerCertificate"
            ],
            "Resource": [
                "*"
            ]
        }
    ]
}


Step 2: Create new user to execute script


Create new user at Users > Create New Users.

Do not forget to download the user's credentials.

Then attach the policy letsencrypt-aws which you just created at step #1 to the user.

Can't find the policy? Try filtering policies by "Filter: Customer Managed Policies".

IAM Users letsencrypt-aws


Step 3: Install packages


Login to the host, and install required packages.

sudo yum update
sudo yum install -y git nginx libffi-devel puppet libffi-devel puppet httpd24 jq
sudo /etc/init.d/nginx start
sudo chkconfig nginx on


Step 4: Set up Nginx


Edit nginx.conf to add a location directive for Let's Encrypt.

vi /etc/nginx/nginx.conf

server {
    listen       80;
    server_name  localhost;
    root         /usr/share/nginx/html;

    # ...

    # For Let's Encrypt
    location ^~ /.well-known/acme-challenge {
        root /var/www/letsencrypt;
        access_log /var/log/nginx/access_letsencrypt.log;
        error_log /var/log/nginx/error_letsencrypt.log;
    }
}

Restart Nginx proceess to apply the new configuration.

sudo service nginx restart


Step 5: Let's try executing


Execute commands below:

cd /home/ec2-user/
git clone https://github.com/ymkjp/elb_update_cert.git
git clone https://github.com/letsencrypt/letsencrypt
vi /home/ec2-user/elb_update_cert/elb_update_cert.sh  # Edit as yours
sudo aws configure --profile elb_update_cert  # Add the user you set up
sudo bash elb_update_cert.sh

Working well?
Move on to the next step.


Step 6: Add cron job


Congrats. This is the final step!

sudo cp /home/ec2-user/elb_update_cert/etc/cron.d/elb_update_cert /etc/cron.d

All done!
This cron job is going to refresh your domain's certificate on ELB every month.

High five!


Any questions?


Comment to this article, or create "New issue" at https://github.com/ymkjp/elb_update_cert/issues.


Further work


  • Create Docker image for step #3 to #6
  • Create template by AWS CloudFormation

Hope this helps you.

Cheers!

Author: @ymkjp