SSL Certificates with Rails, AWS Elastic Beanstalk and Let’s Encrypt

Having recently worked on an App hosted in Elastic Beanstalk, I realised it was difficult to install an SSL Certificate, unless your environment was setup with a load balancer.

What is load balancing?

Load Balancing automatically distributes incoming requests/traffic across multiple targets, for example EC2 instances. This increases performance and reduces downtime, which is great, but if you’re still starting out, prototyping or setting up a staging site, it might be overkill.

As well as this, there’s the cost factor. Roughly speaking, if you configure Elastic Beanstalk to use load balancing, it’ll cost around £20-£30 per month, depending on how many instances you choose.

Obviously, nothing stops you from SSHing into your instance and installing the certificate manually, but if you’re not to experienced with linux or devops it can become a bit confusing.

Setting up your Rails App for SSL with Elastic Beanstalk

Firstly, we’re going to need to create a new directory within the root our Rails App (if it doesn’t exist already) .ebextensions and create a new file certbot.config. Within this file, any script and commands we write will be executed during deployment. Depending on what you want to achieve, you’re able to run commands at any stage of the deployment and build cycle. Please note the below config is only applicable for nginx servers, other servers may require slightly different configs.

Copy and paste the below snippet into your new file, ensure the spacing/indentation remains the same.

Let’s quickly breakdown what’s happening in this file.

First we add port 443, used for SSL connections, to the security group. Next, we create a custom nginx config file, containing the server’s configuration for port 443 and state the location of the SSL Certificate, as well as the location of our app on the server. Lastly, we run a suite of commands which installs certbot and requests a new certifcate for domain certdomain and saves them in the location stated in our SSL config.

Let’s Encrypt issued certificates tend to last around 3 months, but certbot will automatically check the renewal date and renew your certificate if it’s coming up to renewal.

I’ve personally had a few issues with this in the past and have setup a cron job to run on my eb instance every week checking for renewals. If you’re deploying regularly, it shouldn’t be an issue but I’d suggest keeping an eye on your certificate expiration date to see if certbot is renewing when it’s supposed to. You can do this quite easily in Chrome by clicking the padlock in the URL bar and then the Certificate button. A drop down will appear with info on your certificate and it’s expiration date.

Before running a new deployment you will be required to change line 58 to your email address. As well as this, you will need to set the environment variable certdomain equal to your domain, eg: example.com. The latter can be done on the Elastic Beanstalk Configuration Dashboard, under the Software Tab.

Once this is completed and your app has successfully deployed with all the updates, you should be able to visit your new https site. If this is still not working, you might need to reload ngnix. To do this, SSH into your instance and run:

#Your EB Instance
$ sudo service nginx reload
Reloading nginx: [ OK ]

All done! You’ve successfully installed an SSL certificate on a Single Instance Elastic Beanstalk App.

As always, thanks for reading, hit 👏 if you like what you read and be sure to follow to keep up to date with future posts.