With all those different pages you could host on AWS, and the tons of guides out there, it gets pretty confusing if you want to get that green HTTPS in front of your domain name.
This is what we want
Here, I’m going to breakdown the step-by-step approaches to attaining HTTPS for each of the following cases. In general, the strategy consists of (a) getting a SSL certificate, (b) linking it to your domain, and optionally (c) directing all HTTP traffic to HTTPS.
Note that your domain name doesn’t necessarily need to be obtained through AWS (for example ‘.ai’ names aren’t supported), but you can always migrate your DNS server onto a AWS Route 53 Hosted Zone.
To get your SSL certificate, simply go to the AWS Certificate Manager (ACM), which issues them for free.
Register SSL certificate through ACM
On the first step, you enter in the domain name(s) you want to register. Subsequently, on the second step, it will ask you to validate that you are actually the owner of the domain. The 2 options are (1) DNS and (2) Email, just follow the instructions, and soon you’ll have your certificate (it may take up to 60 minutes). If your domain is already on an AWS Hosted Zone, I recommend the DNS route.
Next, you just have to link the certificate to the Load Balancer associated with your EB instance. Go to the EB page in your AWS console, and select your app. Click on ‘Configuration’ on the left menu, and find your Load Balancer under ‘Network Tier’.
Click on the settings icon
Click the settings icon and find your ACM SSL certificate that you just registered in the ‘SSL certificate ID’ dropdown.
Attach SSL certificate to EB Load Balancer
This step is by far the most annoying. I found it quite difficult due to the lack of documentation available, and the fact that all guides out there are either outdated, or only apply to specific cases. I’ll cover the general strategy, which should work for all cases, but the details here will be for Single-container Docker apps.
The general idea is that the server behind your EB app is another EC2 instance, which you can find in the EC2 section of your AWS console. You have to customize the Nginx configuration on this machine to redirect HTTP traffic (port 80) to HTTPS (port 443).
You might see a lot of guides telling you to use the .ebextensions
directory, but it’s much harder to know what to do there since things that work for others might not work for you. By working with Nginx, you’re setting up the routing at the base level. Learn more here:
So now SSH into the EC2 instance. If you already know how to do this, great. Otherwise, the easiest method is to get the EB CLI, and run eb ssh
.
Once you’re in, find the nginx config file, and open it.
$ sudo vim /etc/nginx/nginx.conf
Inside, you’ll see an include
statement pointing to the file where the routing is actually happening. In our case, its elasticbeanstalk-nginx-docker-proxy.conf
.
$ sudo vim /etc/nginx/sites-enabled/elasticbeanstalk-nginx-docker-proxy.conf
The machine will always listen on port 80, and you can see that it’s proxy-passing onto the Docker container. Right now, both HTTP and HTTPS get routed to Docker, with differentiation. Replace the server
section with the following code.
Essentially, because the request has to come through port 80, you just have to test if it is already HTTPS, in which case you proceed to route it to Docker. Otherwise, you redirect it to use HTTPS.
Now, restart Nginx, and we’re done!
$ sudo service nginx restart
Again, it’s best to use the free SSL certificates issued by AWS Certificate Manager. See section 1 for instructions.
To use your SSL certificate can get your S3 page onto HTTPS, we have to use a service called CloudFront. You can find it your AWS console. Click ‘Create Distribution’, and go through the fields — you can leave most of them as they are.
The important fields are Origin Settings, through which you link to your already existent S3 page. Additionally, lower down, you can select the respective SSL Certificate.
Create a CloudFront distribution
Once the distribution is created, you’ve basically got an outer layer wrapped around your page that can handle HTTPS.
How do you make your URL address actually point there? Go to the Route 53 manager in your AWS console. Now click ‘Hosted Zones’, select your domain, and ‘Create Record Set’. The goal here is to create an alias that links your domain to the CloudFront distribution you just made.
Create an alias in your Record Set
Choose your CloudFront distribution from the dropdown for ‘Alias Target’, and create. The changes may take a bit to propagate, but you’re done!
The strategy I use later on requires the actual key files of the SSL certificate, which you can’t get from ACM (whose certificates can only be applied to Load Balancers or S3).
Thus, we turn to an alternative, which is also quite easy: Certbot. SSH into your machine and follow the instructions on the site to get your SSL certificate files. The commands will download the SSL full chain and private key locally onto your machine in /etc/letsencrypt/
.
Once again, all the routing happens within NGINX. Without HTTPS, you’re likely just listening to port 80 and redirecting it to your app process. Now, we want to change the file to look something like this.
Note that now, we’re listening to ports 80 and 443. On port 443, when you get a HTTPS request, you utilize your SSL certificate to redirect it to your app.
The code above actually kills two birds with one stone. Lines 33–38 tell the server to also listen to port 80, and redirect it to use HTTPS. If you don’t want this functionality, simply get rid of those lines.
Hope this was helpful in summarizing the different techniques of setting up HTTPS on AWS! As always, open to feedback or comments if you have things to add.
If you’re wondering what camelot.ai is, our team is building a new way for content creators to monetize by giving fans a voice in their content or with them directly. You might recognize many of the gaming streamers already on the platform!
Our landing page