Overview
- This post will cover how to set up HTTPS on AWS Elastic Beanstalk Environment (EBS) that is running only a single instance, as opposed to an load balanced environment which can scale up the instances based on load.
- While you can easily set up HTTPS using Amazon Certificate Manager (ACM) if you are using an AWS load balancer with your EBS environment, this is not a method you can use if you choose to use a single instance environment, which does not allow load balancers to be used.
- This post will cover how to set up and use Let’s Encrypt certificates for HTTPS using certbot, which is completely free.
Use Case
The main use case for using this method of setting up HTTPS this way is when you are setting up a small project that requires HTTPS (e.g. You have a domain that requires HTTPS like .dev), but you are not willing to fork out extra cash for multiple EC2 instances and/or you are not willing to pay extra for a load balancer.
Prerequisites
- You have already set up the necessary records in Route 53 for your project to be accessible at your desired domain
- You have set up a single instance EBS Environment1
Process
-
As per the instructions on the AWS support documentation2, create the following directory and file to allow HTTPS connections to your environment
.ebextensions/01_https-instance-securitygroup.configResources: sslSecurityGroupIngress: Type: AWS::EC2::SecurityGroupIngress Properties: GroupId: {"Fn::GetAtt" : ["AWSEBSecurityGroup", "GroupId"]} IpProtocol: tcp ToPort: 443 FromPort: 443 CidrIp: 0.0.0.0/0 -
Create the following directory and file to create a hook to install EPEL3 (required for installing certbot) in the prebuild phase4.
.platform/hooks/prebuild/01_install_epel.sh#!/bin/bash sudo amazon-linux-extras install epel -y -
Create the following file in the same directory to install certbot. Note the “
02_“prepended to the file name. The files in the.platform/hooks/prebuildfolder are executed in alphanumerical order, so this will cause this script to be run after01_install_epels.shis run..platform/hooks/prebuild/02_install_certbot.sh#!/bin/bash sudo yum install -y certbot-nginxThis script will install certbot with the nginx plugin, as EBS uses the nginx web server under the hood.
-
Set the following environment properties (variables) for you EBS environment:
- DOMAIN_1
- This will be the same as the domain or subdomain you’ve set in Route 53 to reach your application, (e.g.
www.example.com)
- This will be the same as the domain or subdomain you’ve set in Route 53 to reach your application, (e.g.
- EMAIL
- This is the email used when using certbot to generate certificates

You may notice that I have a
DOMAIN_2set as well. That is only needed if you have another domain and/or a subdomain linked to the application. - DOMAIN_1
-
Create the following directory and file.
.platform/hooks/postdeploy/01_execute_certbot.sh#!/bin/bash sudo certbot --nginx --non-interactive --agree-tos -m ${EMAIL} -d ${DOMAIN_1}This will create a hook in the postdeploy phase and run certbot to generate the necessary certificates required for HTTPS connections for the listed domains. It will also use the nginx plugin to reconfigure and reload it’s configuration as needed.
In case you have multiple domains and
DOMAIN_2was set in the environment properties in the previous step, you would include the second domain like this:.platform/hooks/postdeploy/01_execute_certbot.sh#!/bin/bash sudo certbot --nginx --non-interactive --agree-tos -m ${EMAIL} -d ${DOMAIN_1} -d ${DOMAIN_2} -
(Optional) To configure auto renewal of certificates, you can setup a cron job to automatically run the certbot renew command by creating the following file in the
.ebextensionsdirectory..ebextensions/02_certbot_renewal.configfiles: "/etc/cron.d/certbot": mode: "000644" owner: root group: root content: | 0 12 * * * root /usr/bin/certbot renew commands: remove_old_cron: command: "rm -f /etc/cron.d/certbot.bak"This file will do 2 things:
- Create a cron job to run the certbot renew command every day at 12:00,
- Although the command is run every day, the certificates themselves will not be renewed unless they are within 30 days of expiry.
- Run the
rm -f /etc/cron.d/certbot.bakcommand before the application and webserver are setup to remove the old cron job, in case it exists
- Create a cron job to run the certbot renew command every day at 12:00,
-
To summarise, by the end, you should have a directory structure which looks something like this:
Project Tree View. ├───.ebextensions │ 01_https-instance-securitygroup.config │ 02_certbot_renewal.config │ └───.platform └───hooks ├───postdeploy │ 01_execute_certbot.sh │ └───prebuild 01_install_epel.sh 02_install_certbot.shMake sure that every file is in the right place, and their contents are correct. Note this is the view from the root project directory. When you zip your project and upload it to AWS Elastic Beanstalk, both the
.ebextensionsand.platformdirectories should be located in the root directory, alongside the rest of your project files.
Conclusion
No one wants to fork out huge sums of cash every time we setup a small project on the web. So us poor folks gotta find ways around it but still get what we want. At any rate, this post summarises my method of setting up HTTPS on AWS EBS without load balancers. I’m sure there are better ways of doing it, especially in terms of “best practice”, but for now, this works for me in my small personal projects. Although if you are looking for a more professional solution, this likely won’t meet your requirements, but then again, a professional wouldn’t be looking at a blog like this, haha.
Footnotes
- AWS Documentation to change environment types: https://docs.aws.amazon.com/elasticbeanstalk/latest/dg/using-features-managing-env-types.html#using-features.managing.changetype ↩︎
- AWS documentation to open port 443 in a single instance environment: https://docs.aws.amazon.com/elasticbeanstalk/latest/dg/https-singleinstance.html ↩︎
- Extra Packages for Enterprise Linux (EPEL) ↩︎
- For more information on the Elastic Beanstalk deployment phases, see the documentation here: https://docs.aws.amazon.com/elasticbeanstalk/latest/dg/platforms-linux-extend.html ↩︎