I am using Elastic Beanstalk on AWS to host a single-tenant application with Amazon Linux 2 + Nginx server.
Is there any way to automatically generate a HTTPS certificate without recurring to a Load Balancer?
Question posted in Amazon Web Sevices
The official Amazon Web Services documentation can be found here.
The official Amazon Web Services documentation can be found here.
2
Answers
A solution would be to create an AWS Linux 2 + Nginx image based on your Elastic Beanstalk image with Certbot (application needed to generate the certificates) preinstalled and roll out this image to your instances. Then, with a .posthook script Certbot can be called to renew the certificate each time the server is started or updated (restart/new version upload)
For the first step you can create an AWS Beanstalk environment through the wizard : the instance will be made available on your EC2 tab. Then, you can access your EC2 instance through SSH (there is a tutorial at this link : Putty is a good choice of a SSH client on Windows) and run the following commands to install Certbot:
After that you can go to the EC2 tab, find your instance and create an image based on your EC2 Elastic Beanstalk instance:
With the image created, it can be reused on several instances by inserting the newly created AMI on the Instance Traffic and Scaling menu on the Elastic Beanstalk Configuration tab.
The next step is to assign a DOMAIN environment variable to your EB environment. This variable corresponds to the domain that has been assigned to your server IP through DNS.
Lastly, a script should be placed in the .zip /.jar file or docker image that is uploaded on Beanstalk. The file should be located on:
The file content is:
The --email parameter should be replaced with a real e-mail and could also be set up as an environment variable.
The sleep command waits for the server IP to correspond to the Elastic IP : if Certbot is called before that the certificate will not be generated.
Also note that this command instructs Nginx to redirect traffic from port 80 (HTTP) to 443 (HTTPS), so this port should be enabled on your EC2 instance:
This solution should be resilient to an Application server / Nginx server restart and to the upload of new application versions.
Yes, there are ways to automatically generate HTTPS certificates without using a Load Balancer on AWS Elastic Beanstalk. One such method is using Let’s Encrypt, a free, automated, and open Certificate Authority (CA) which provides you with a free SSL certificate.
Solution 1
Here’s a rough guide on how you can generate an SSL certificate for your Beanstalk environment using Let’s Encrypt. These steps assume that you are running a Linux instance:
SSH into your EC2 Instance: Connect to your EC2 instance which is associated with your Beanstalk environment. You can get the instance ID from the Elastic Beanstalk dashboard and then use the EC2 dashboard to get your instance’s public DNS.
Install Certbot: Certbot is the client software for Let’s Encrypt. You can install it on Amazon Linux with the following command:
Generate Certificate: Run Certbot to generate your SSL certificate. Replace
example.com
with your domain name. If you have a www version, include that as well:This will create a challenge to verify that you control the domain, then create the certificate files. These files are generally stored in
/etc/letsencrypt/live/your_domain_name/
.Configure Nginx: Modify your Nginx configuration to use the SSL certificate. It will be somewhere like
/etc/nginx/nginx.conf
or/etc/nginx/sites-available/default
. Make sure you have the following inside the server block:Then restart Nginx:
Automatic Renewal: Let’s Encrypt certificates expire after 90 days, so you’ll want to set up automatic renewal. Edit your crontab with
sudo crontab -e
and add the following line:This will attempt to renew the certificate at 3:15 every day. If the certificate is due to expire in the next 30 days, it will renew it, then restart Nginx.
Please note that for the Let’s Encrypt certification generation to work, your domain needs to be publicly accessible, and port 80 must be open to complete the challenge.
The aforementioned manual setup would work, but it isn’t considered a best practice as it is not scalable and doesn’t make full use of AWS services.
Solution 2
Using AWS Certificate Manager (ACM) with a Load Balancer or CloudFront is generally considered best practice for managing SSL certificates in AWS, as these services are designed for scalability and automation. You should consider this manual setup as a workaround only if you have specific constraints that prevent you from using these services.
Using AWS Certificate Manager (ACM) with Elastic Load Balancer (ELB):
The typical approach to setup HTTPS for AWS Elastic Beanstalk is to use an AWS managed service like Elastic Load Balancer (ELB) in combination with AWS Certificate Manager (ACM). You can use ACM to easily create, manage, and deploy public and private SSL/TLS certificates. ACM certificates can secure singular domain names, multiple specific domain names, wildcard domains, or a combination. Here’s how you can set it up:
Request a Certificate: In the AWS Management Console, go to the ACM (AWS Certificate Manager) service. Request a new public certificate, enter your domain name, and validate that you own the domain. You can validate domain ownership via email or DNS. Once validated, AWS will issue the certificate.
Set up a Load Balancer: If you don’t already have one, you’ll need to set up an Elastic Load Balancer and assign it to your Elastic Beanstalk environment. To assign the load balancer to your environment, you may need to update the environment type from single instance to load balanced.
Assign the Certificate to the Load Balancer: In the Load Balancer listeners configuration, add an HTTPS listener. Select your newly issued certificate from the dropdown. The Load Balancer will now use your certificate to serve HTTPS traffic.
Update Security Groups: Make sure your load balancer’s security group allows inbound HTTPS (port 443) traffic.
The above setup will offload the SSL termination to the Load Balancer, meaning that the Load Balancer will be responsible for encrypting and decrypting the traffic, leaving your application to focus on its own logic.
Using AWS Certificate Manager (ACM) with CloudFront:
In addition to the aforementioned method, you can also use CloudFront with ACM to serve your Elastic Beanstalk app over HTTPS. Here’s how:
Request a Certificate: Follow the same procedure as above to request and validate a new public certificate from AWS Certificate Manager.
Create a CloudFront Distribution: Go to the CloudFront service in the AWS Management Console and create a new distribution.
Assign the Certificate to the Distribution: In the "SSL Certificate" section of the distribution settings, choose "Custom SSL Certificate" and select your newly issued certificate from the dropdown.
Set Origin Settings: In the "Origins and Origin Groups" section, add an origin that points to your Elastic Beanstalk environment’s URL (without the ‘https://’). You can get this URL from your environment’s dashboard in the Elastic Beanstalk service. Ensure that the "Origin Protocol Policy" is set to "HTTP Only".
Set Behavior Settings: In the "Behaviors" section, make sure that the "Viewer Protocol Policy" is set to "Redirect HTTP to HTTPS". This ensures that all traffic to your CloudFront distribution is served over HTTPS.
Update your DNS Records: Once your CloudFront distribution is deployed (this can take a while), you’ll get a CloudFront domain name (something like
d12345abcdefg.cloudfront.net
). Update your domain’s DNS records (in Route 53, or wherever your domain is registered) to create a CNAME record that points your domain to the CloudFront domain.This setup uses CloudFront as a CDN, which caches your app’s content in edge locations around the world, making your app faster for end users. Furthermore, it also handles SSL termination, meaning that the CloudFront service will manage the HTTPS encryption, instead of your Beanstalk environment.
Remember to allow some time for DNS changes to propagate, and for the CloudFront distribution to deploy. Also, be aware of additional costs associated with Load Balancer and CloudFront usage.
Solution 3
Here’s a sample runbook that you could use as a reference-
Case 1: Using AWS Certificate Manager (ACM) with Elastic Load Balancer (ELB)
Case 2: Using AWS Certificate Manager (ACM) with CloudFront
Please note, these runbooks are written in YAML for Ansible. If you are using different tools, you might need to adjust the syntax and command options.
As for Using AWS Certificate Manager (ACM) with CloudFront, there is an open-source project – Awesome-ClousOps-Automation on Github that has prebuild actions for creating certificates and renewing them. You could use those to create a new runbook.