Enforce HTTPS For Elastic Beanstalk Load Balancers.
More Info:
Ensure that HTTPS is enabled for the load balancer associated with your Amazon Elastic Beanstalk application environment in order to handle encrypted web traffic. By default, the load balancer handles unencrypted traffic requests (HTTP) through port 80. To enable HTTPS traffic over port 443, you must create and configure an HTTPS listener for the associated load balancer.
Risk Level
High
Address
Security
Compliance Standards
SOC2,GDPR,PCIDSS,NIST,HITRUST,NISTCSF
Remediation
How to ensure that HTTPS is enabled for EC2 ElasticBeanstalk Load Balancer
Using AWS Console
- Log in to the AWS Management Console using your AWS account credentials.
- Navigate to the Elastic Beanstalk service by selecting "Elastic Beanstalk" from the services menu.
- In the Elastic Beanstalk dashboard, select the appropriate environment that you want to configure for HTTPS.
- In the environment details page, click on the "Configuration" tab in the left navigation pane.
- Scroll down to the "Load Balancer" section and click on the "Edit" button next to "Load balancer settings".
- In the "Secure listener port" field, ensure that the value is set to 443. This is the default port for HTTPS.
- In the "SSL certificate ID" field, select or upload the appropriate SSL certificate for your domain. If you haven't already uploaded the SSL certificate to AWS Certificate Manager (ACM), you can do so by clicking on the "Upload" button and following the instructions.
- Optionally, you can choose to enable "HTTP to HTTPS redirection" by checking the box next to it. This will automatically redirect HTTP traffic to HTTPS.
- Click on the "Apply" button to save the changes and update the environment configuration.
- Wait for the environment update to complete. This may take a few minutes.
- Once the update is complete, your Elastic Beanstalk environment's load balancer should be configured to use HTTPS.
- Test the HTTPS connectivity by accessing your application using the HTTPS protocol (e.g., https://your-domain.com). Ensure that the SSL certificate is valid and the connection is secure.
Triage and Remediation
- Remediation
Remediation
Using Console
Below are console-only steps to enforce HTTPS for an Elastic Beanstalk (EC2) environment load balancer.
1. Get/Validate an SSL Certificate in ACM
- Go to AWS Management Console → Certificate Manager (ACM).
- Choose Request a certificate → Request a public certificate.
- Enter your domain(s), e.g.
example.comandwww.example.com. - Choose validation method:
- DNS validation (recommended): ACM gives you CNAME records to add to your DNS (e.g., Route 53 or external).
- Or Email validation if DNS isn’t an option.
- Complete validation. Wait until status is Issued.
Keep the ARN of this certificate handy (you’ll select it in Elastic Beanstalk).
2. Confirm Your EB Environment Uses a Load Balancer
- Go to Elastic Beanstalk → select your Application → select your Environment.
- In the Environment overview, check the Environment type:
- Must be Load balanced (either ALB or Classic ELB).
- If it’s Single instance, you’ll need to create a new Load balanced environment (you can clone config).
3. Attach the SSL Certificate & Add HTTPS Listener
For an Application Load Balancer (ALB) environment (most newer EB envs)
- In your environment page, choose Configuration from the left menu.
- Under Load balancer, click Edit.
- Look at the Listeners section:
- You should see a listener on Port 80, Protocol HTTP.
- Add HTTPS listener:
- Click Add listener (or equivalent).
- Set:
- Port:
443 - Protocol:
HTTPS
- Port:
- Under SSL certificate, choose:
- Choose from ACM → select the certificate you created (ARN).
- Under Default rules / Target group, select the existing target group that your HTTP listener uses (so 443 forwards to the same instances/targets as 80).
- Save the configuration (e.g., Apply or Save on the page).
- Wait for Elastic Beanstalk to update the environment.
For a Classic Load Balancer environment (older EB envs)
- From your EB environment Configuration page → under Load balancer, click Edit.
- Under Listeners, check existing:
- You should see a listener
HTTP : 80 → HTTP : 80(front-end to back-end).
- You should see a listener
- Add HTTPS listener:
- Add a new listener with:
- Load Balancer Protocol:
HTTPS - Load Balancer Port:
443 - Instance Protocol:
HTTP - Instance Port:
80
- Load Balancer Protocol:
- For SSL Certificate, select your ACM certificate.
- Add a new listener with:
- Save and let EB update the environment.
4. Redirect HTTP (80) to HTTPS (443)
You’ve now enabled HTTPS, but you should force redirect all HTTP traffic to HTTPS.
Option A – At application level (simplest, recommended)
Redirect in your app code / web server configuration:
-
For a typical Node.js / Express app, add middleware:
app.use((req, res, next) => {if (req.headers['x-forwarded-proto'] !== 'https') {return res.redirect(301, 'https://' + req.headers.host + req.url);}next();}); -
For Apache (PHP, etc.) in
.htaccess:RewriteEngine OnRewriteCond %{HTTP:X-Forwarded-Proto} !httpsRewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301] -
For Nginx in a config file in
.ebextensions(if you control Nginx):.ebextensions/https-redirect.config:files:"/etc/nginx/conf.d/https_redirect.conf":mode: "000644"owner: rootgroup: rootcontent: |server {listen 80;return 301 https://$host$request_uri;}
Deploy the updated application to EB.
Option B – ALB listener rule (if using ALB)
- From the environment’s Configuration → Load balancer → find the HTTP:80 listener.
- Open View rules or Edit rules for the HTTP listener.
- Add a rule before the default:
- Condition:
If(e.g.,Pathis/or/*– or no condition if you want all). - Action: Redirect:
- Protocol:
HTTPS - Port:
443 - Status code:
HTTP_301.
- Protocol:
- Condition:
- Save the rules.
5. Test
- Browse to:
http://your-domain.com. - Confirm:
- It redirects to
https://your-domain.com. - The browser shows a valid padlock/secure connection.
- It redirects to
- Also test direct
https://your-domain.com.
This fully enforces HTTPS for your Elastic Beanstalk EC2 environment using the AWS console.
Using CLI
Below are concise, CLI‑only steps to enforce HTTPS on an Elastic Beanstalk environment fronted by an Elastic Load Balancer (ALB / CLB) on EC2.
1. Get your environment & region info
ENV_NAME="my-eb-env"
REGION="us-east-1"
Verify:
aws elasticbeanstalk describe-environments \
--region "$REGION" \
--environment-names "$ENV_NAME"
2. Get / create an ACM certificate
DOMAIN_NAME="app.example.com"
Request a public certificate (DNS validation):
aws acm request-certificate \
--region "$REGION" \
--domain-name "$DOMAIN_NAME" \
--validation-method DNS \
--idempotency-token "eb-https-$ENV_NAME"
Note the CertificateArn from the output. Wait until its status is ISSUED:
CERT_ARN="arn:aws:acm:REGION:ACCOUNT:certificate/xxxx"
aws acm describe-certificate \
--region "$REGION" \
--certificate-arn "$CERT_ARN" \
--query "Certificate.Status"
3. Identify whether your EB environment uses ALB or Classic ELB
aws elasticbeanstalk describe-configuration-settings \
--region "$REGION" \
--environment-name "$ENV_NAME" \
--query "ConfigurationSettings[0].OptionSettings[?Namespace=='aws:elasticbeanstalk:environment'].Value"
Or simply:
aws elasticbeanstalk describe-configuration-settings \
--region "$REGION" \
--environment-name "$ENV_NAME" \
--output json > config.json
Look inside for:
aws:elasticbeanstalk:environment→LoadBalancerType = application→ ALB- Or no such setting / default → usually Classic.
4A. For ALB (recommended): enforce HTTPS + redirect HTTP
Use Elastic Beanstalk option settings to:
- Configure HTTPS listener (443) with your ACM certificate
- Keep HTTP (80) but redirect it to HTTPS
Create a JSON file alb-https-config.json:
[
{
"Namespace": "aws:elbv2:listener:443",
"OptionName": "ListenerEnabled",
"Value": "true"
},
{
"Namespace": "aws:elbv2:listener:443",
"OptionName": "Protocol",
"Value": "HTTPS"
},
{
"Namespace": "aws:elbv2:listener:443",
"OptionName": "SSLCertificateArns",
"Value": "CERT_ARN_REPLACE_ME"
},
{
"Namespace": "aws:elbv2:listener:80",
"OptionName": "ListenerEnabled",
"Value": "true"
},
{
"Namespace": "aws:elbv2:listener:80",
"OptionName": "Protocol",
"Value": "HTTP"
},
{
"Namespace": "aws:elbv2:listener:80",
"OptionName": "DefaultProcess",
"Value": "default"
},
{
"Namespace": "aws:elbv2:listener:80",
"OptionName": "Rules",
"Value": "RedirectToHTTPS"
},
{
"Namespace": "aws:elbv2:listener-rule:RedirectToHTTPS",
"OptionName": "PathPatterns",
"Value": "/*"
},
{
"Namespace": "aws:elbv2:listener-rule:RedirectToHTTPS",
"OptionName": "Priority",
"Value": "1"
},
{
"Namespace": "aws:elbv2:listener-rule:RedirectToHTTPS",
"OptionName": "Actions",
"Value": "redirect"
},
{
"Namespace": "aws:elbv2:listener-rule:RedirectToHTTPS",
"OptionName": "RedirectConfig",
"Value": "{\"Protocol\":\"HTTPS\",\"Port\":\"443\",\"StatusCode\":\"HTTP_301\"}"
}
]
Replace:
sed -i "s|CERT_ARN_REPLACE_ME|$CERT_ARN|" alb-https-config.json
Apply to the environment:
aws elasticbeanstalk update-environment \
--region "$REGION" \
--environment-name "$ENV_NAME" \
--option-settings file://alb-https-config.json
Wait for the environment to finish updating, then test:
http://app.example.com→ should 301 redirect tohttps://app.example.comhttps://app.example.com→ should work with a valid cert
4B. For Classic Load Balancer: HTTPS listener + (optional) HTTP→HTTPS
4B.1 Get the underlying ELB name
From EB:
aws elasticbeanstalk describe-environment-resources \
--region "$REGION" \
--environment-name "$ENV_NAME" \
--query "EnvironmentResources.LoadBalancers[0].Name" \
--output text
ELB_NAME="output-from-above"
4B.2 Create/modify HTTPS listener on Classic ELB
Add HTTPS (443) listener using your ACM cert (same region):
aws elb create-load-balancer-listeners \
--region "$REGION" \
--load-balancer-name "$ELB_NAME" \
--listeners "Protocol=HTTPS,LoadBalancerPort=443,InstanceProtocol=HTTP,InstancePort=80,SSLCertificateId=$CERT_ARN"
If HTTPS already exists, you can update the cert:
aws elb set-load-balancer-listener-ssl-certificate \
--region "$REGION" \
--load-balancer-name "$ELB_NAME" \
--load-balancer-port 443 \
--ssl-certificate-id "$CERT_ARN"
4B.3 (Optional but recommended) Redirect HTTP→HTTPS at the app
Classic ELB does not support redirect rules; so either:
- Keep port 80 listener and configure your app/web server to redirect to HTTPS, or
- Remove the HTTP listener (forcing HTTPS only):
aws elb delete-load-balancer-listeners \
--region "$REGION" \
--load-balancer-name "$ELB_NAME" \
--load-balancer-ports 80
5. Confirm security group allows 443 and (optionally) restricts 80
Get the LB’s security group(s):
aws elb describe-load-balancers \
--region "$REGION" \
--load-balancer-names "$ELB_NAME" \
--query "LoadBalancerDescriptions[0].SecurityGroups" \
--output text
SG_ID="sg-xxxxx"
Allow HTTPS from the internet:
aws ec2 authorize-security-group-ingress \
--region "$REGION" \
--group-id "$SG_ID" \
--ip-permissions IpProtocol=tcp,FromPort=443,ToPort=443,IpRanges='[{\"CidrIp\":\"0.0.0.0/0\"}]'
Optionally remove HTTP (80) if you’re not using it:
aws ec2 revoke-security-group-ingress \
--region "$REGION" \
--group-id "$SG_ID" \
--protocol tcp \
--port 80 \
--cidr 0.0.0.0/0
If you tell me whether your EB environment is using ALB or Classic ELB, I can trim this down to only the exact commands you need.
Using Python
Below are practical, step‑by‑step instructions to enforce HTTPS for an Elastic Beanstalk environment (EC2) and a minimal Python (boto3) example to apply it programmatically.
1. Prerequisites
- Elastic Beanstalk environment already running (Web Server, EC2).
- Application Load Balancer (ALB) or Classic ELB created by EB.
- ACM certificate in the same region as your Beanstalk environment:
- Request via console: ACM → Request a certificate → Public → add domain → validate.
- Note the certificate ARN, e.g.:
arn:aws:acm:us-east-1:123456789012:certificate/...
2. Enforce HTTPS via Elastic Beanstalk configuration
Option A – Configuration files (.ebextensions / .platform)
For ALB (most modern EB environments):
Create .ebextensions/https-alb.config in your app root:
option_settings:
aws:elbv2:listener:443:
ListenerEnabled: 'true'
Protocol: HTTPS
SSLCertificateArns: arn:aws:acm:us-east-1:123456789012:certificate/your-cert-id
aws:elbv2:listener:80:
ListenerEnabled: 'true'
Protocol: HTTP
DefaultProcess: default
aws:elasticbeanstalk:environment:process:default:
Port: '80'
Protocol: HTTP
Then add an HTTP→HTTPS redirect via ALB rules. For EB’s new ALB model, use a platform hook:
Create .platform/hooks/postdeploy/01-redirect-http-to-https.sh:
#!/bin/bash
set -e
# Get environment name and region
ENV_NAME=$(curl -s http://169.254.169.254/latest/meta-data/tags/instance/elasticbeanstalk:environment-name)
REGION=$(curl -s http://169.254.169.254/latest/dynamic/instance-identity/document | jq -r .region)
# Get load balancer ARN
LB_ARN=$(aws elasticbeanstalk describe-environment-resources \
--environment-name "$ENV_NAME" \
--region "$REGION" \
--query "EnvironmentResources.LoadBalancers[0].Name" \
--output text | xargs -I{} aws elbv2 describe-load-balancers \
--names {} \
--region "$REGION" \
--query "LoadBalancers[0].LoadBalancerArn" \
--output text)
# Get HTTP listener ARN (port 80)
HTTP_LISTENER_ARN=$(aws elbv2 describe-listeners \
--load-balancer-arn "$LB_ARN" \
--region "$REGION" \
--query "Listeners[?Port==\`80\`].ListenerArn" \
--output text)
# Get HTTPS listener ARN (port 443)
HTTPS_LISTENER_ARN=$(aws elbv2 describe-listeners \
--load-balancer-arn "$LB_ARN" \
--region "$REGION" \
--query "Listeners[?Port==\`443\`].ListenerArn" \
--output text)
# Overwrite HTTP listener rule to redirect to HTTPS
aws elbv2 modify-listener \
--listener-arn "$HTTP_LISTENER_ARN" \
--region "$REGION" \
--default-actions Type=redirect,RedirectConfig="{Protocol=https,Port=443,StatusCode=HTTP_301}"
Make it executable:
chmod +x .platform/hooks/postdeploy/01-redirect-http-to-https.sh
Deploy the app (eb deploy); EB will:
- Enable HTTPS listener 443 with your cert.
- Keep HTTP listener 80 only for redirection.
- Install redirect rule via the hook script.
3. Python (boto3) – Programmatically enforce HTTPS
Below is an example to:
- Find the ALB used by your EB environment.
- Ensure HTTPS listener (443) exists with your ACM cert.
- Modify HTTP (80) listener to always redirect to HTTPS.
import boto3
REGION = "us-east-1"
ENV_NAME = "my-beanstalk-env"
ACM_CERT_ARN = "arn:aws:acm:us-east-1:123456789012:certificate/your-cert-id"
eb = boto3.client("elasticbeanstalk", region_name=REGION)
elbv2 = boto3.client("elbv2", region_name=REGION)
def get_alb_arn_for_env(env_name: str) -> str:
# Get ELB name from EB
res = eb.describe_environment_resources(EnvironmentName=env_name)
lbs = res["EnvironmentResources"].get("LoadBalancers", [])
if not lbs:
raise RuntimeError("No load balancer found for environment")
lb_name = lbs[0]["Name"]
# Map name to ALB ARN
res2 = elbv2.describe_load_balancers(Names=[lb_name])
return res2["LoadBalancers"][0]["LoadBalancerArn"]
def ensure_https_and_redirect(lb_arn: str):
listeners = elbv2.describe_listeners(LoadBalancerArn=lb_arn)["Listeners"]
http_listener_arn = None
https_listener_arn = None
for l in listeners:
if l["Port"] == 80 and l["Protocol"] == "HTTP":
http_listener_arn = l["ListenerArn"]
if l["Port"] == 443 and l["Protocol"] == "HTTPS":
https_listener_arn = l["ListenerArn"]
# 1) Create HTTPS listener if missing
if not https_listener_arn:
print("Creating HTTPS listener on 443...")
# Use same default target group as HTTP
default_actions = []
if http_listener_arn:
http_details = elbv2.describe_listeners(ListenerArns=[http_listener_arn])[
"Listeners"
][0]
default_actions = http_details["DefaultActions"]
else:
raise RuntimeError("No HTTP listener found to copy target group from")
resp = elbv2.create_listener(
LoadBalancerArn=lb_arn,
Protocol="HTTPS",
Port=443,
Certificates=[{"CertificateArn": ACM_CERT_ARN}],
DefaultActions=default_actions,
)
https_listener_arn = resp["Listeners"][0]["ListenerArn"]
print("Created HTTPS listener:", https_listener_arn)
# 2) Force HTTP → HTTPS redirect on port 80
if not http_listener_arn:
print("No HTTP listener found on port 80; creating one for redirect...")
resp = elbv2.create_listener(
LoadBalancerArn=lb_arn,
Protocol="HTTP",
Port=80,
DefaultActions=[
{
"Type": "redirect",
"RedirectConfig": {
"Protocol": "HTTPS",
"Port": "443",
"StatusCode": "HTTP_301",
},
}
],
)
http_listener_arn = resp["Listeners"][0]["ListenerArn"]
else:
print("Updating HTTP listener to redirect to HTTPS...")
elbv2.modify_listener(
ListenerArn=http_listener_arn,
DefaultActions=[
{
"Type": "redirect",
"RedirectConfig": {
"Protocol": "HTTPS",
"Port": "443",
"StatusCode": "HTTP_301",
},
}
],
)
print("HTTPS enforced for load balancer.")
if __name__ == "__main__":
lb_arn = get_alb_arn_for_env(ENV_NAME)
ensure_https_and_redirect(lb_arn)
Run this from a machine/CI with:
- IAM permissions for
elasticbeanstalk:*,elasticloadbalancingv2:*,acm:ListCertificates(or at least describe/modify for ALB and EB). - Credentials configured (env vars,
~/.aws/credentials, or instance role).
4. Security group check (optional but recommended)
Ensure the load balancer security group:
- Allows inbound 80/tcp (only if you need redirect) and 443/tcp from the internet.
- Your EC2 instances’ security group allows inbound from the LB SG on port 80 (if your app listens on 80).
If you tell me your environment type (ALB vs Classic) and platform (e.g., Python 3.12 on AL2), I can adjust the config snippets exactly to that.
Using Terraform
# Application Load Balancer in front of your Elastic Beanstalk EC2 instances
resource "aws_lb" "app_alb" {
name = "APP_ALB_NAME" # replace with your ALB name
load_balancer_type = "application"
subnets = [SUBNET_ID_1, SUBNET_ID_2] # replace with your subnet IDs
security_groups = [ALB_SECURITY_GROUP_ID] # replace with SG that allows 80/443
}
# Target group for your Elastic Beanstalk EC2 instances
resource "aws_lb_target_group" "app_tg" {
name = "APP_TG_NAME" # replace with your target group name
port = 80
protocol = "HTTP"
vpc_id = VPC_ID # replace with your VPC ID
}
# HTTP listener: redirects all HTTP requests to HTTPS (enforce HTTPS)
resource "aws_lb_listener" "http_redirect" {
load_balancer_arn = aws_lb.app_alb.arn
port = 80
protocol = "HTTP"
default_action {
type = "redirect"
redirect {
port = "443"
protocol = "HTTPS"
status_code = "HTTP_301"
}
}
}
# HTTPS listener: terminates TLS and forwards to the target group
resource "aws_lb_listener" "https" {
load_balancer_arn = aws_lb.app_alb.arn
port = 443
protocol = "HTTPS"
ssl_policy = "ELBSecurityPolicy-2016-08" # or another approved policy
certificate_arn = ACM_CERTIFICATE_ARN # replace with your ACM certificate ARN
default_action {
type = "forward"
target_group_arn = aws_lb_target_group.app_tg.arn
}
}
This change does not force replacement of the load balancer itself, but adding/modifying listeners momentarily affects how traffic on those ports is handled; plan and apply during a maintenance window if your environment is sensitive.
For verification, terraform plan should show:
- creation (or update) of an HTTP listener on port 80 whose
default_actionis aredirectto HTTPS on port 443 with statusHTTP_301. - creation (or confirmation) of an HTTPS listener on port 443 with a valid
certificate_arnthat forwards to your target group.