Cloud  /  AWS

AWS Amazon Web Services 61 guides · updated 2026

Hands-on guides to compute, storage, databases, networking, and serverless on the world's most widely adopted cloud platform.

AWS Elastic Beanstalk: Deploy Web Apps Without Thinking About Infrastructure

Elastic Beanstalk sits between raw EC2 and a fully managed PaaS. You upload application code, pick a runtime, and Beanstalk provisions the EC2 instances, load balancer, Auto Scaling group, and CloudWatch alarms. You retain full access to the underlying resources and can customise them — but the defaults are sensible and get you running in minutes.

It is not the right tool for every team or every stage of growth, but for developers who want AWS-quality infrastructure without hiring DevOps, it is a practical starting point.

What Beanstalk Manages For You

Your Code Upload (.zip or Git)
┌──────────────────────────────────────────────────────────┐
│ Elastic Beanstalk Environment │
│ │
│ Application Load Balancer │
│ │ │
│ Auto Scaling Group │
│ ├── EC2 Instance (your code running) │
│ ├── EC2 Instance (your code running) │
│ └── EC2 Instance (your code running) │
│ │
│ CloudWatch Alarms (CPU, request count) │
│ CloudWatch Logs (application output) │
│ EC2 Security Groups (auto-configured) │
│ IAM Instance Profile (auto-created) │
└──────────────────────────────────────────────────────────┘

Beanstalk creates all of this from a single eb create command or a console click.

Supported Platforms

Each Beanstalk platform is a combination of OS + runtime:

The Docker platform is the most flexible — if your app runs in a container, Beanstalk can run it regardless of the language.

Deploying Your First Application

Install the EB CLI:

Terminal window
pip install awsebcli

For a Python Flask application:

application.py
from flask import Flask, jsonify
application = Flask(__name__) # Must be named 'application' for Beanstalk
@application.route('/health')
def health():
return jsonify({'status': 'ok'})
@application.route('/')
def index():
return jsonify({'message': 'Hello from Elastic Beanstalk'})
if __name__ == '__main__':
application.run(port=8000)
requirements.txt
Flask==3.0.0
gunicorn==21.2.0
# Procfile (tells Beanstalk how to start the app)
web: gunicorn --bind 0.0.0.0:8000 application:application
Terminal window
# Initialise and deploy
eb init my-flask-app --platform python-3.12 --region us-east-1
eb create production --instance-type t3.small --min-instances 2 --max-instances 6

That creates a production-ready environment. Beanstalk provisions the load balancer and Auto Scaling group. Update the application:

Terminal window
# Deploy new code
eb deploy
# Or specify environment name
eb deploy production

Environment Tiers

Web Server Environment: Standard web application setup with an ALB in front of an ASG. The default and most common tier.

Worker Environment: Processes jobs from an SQS queue. Beanstalk provides a daemon process that polls SQS and POST requests to http://localhost/ for each message. Your application does not need SQS SDK code — it just handles HTTP POST requests. Useful for background processing without building a separate worker infrastructure.

Deployment Policies

Beanstalk supports multiple deployment strategies that control how it rolls out new versions:

ALL AT ONCE:
Old → New (all instances simultaneously)
Fastest, but causes downtime if deployment fails.
Use only for dev environments.
ROLLING:
[Old][Old][Old][Old]
[New][New][Old][Old]
[New][New][New][New]
No extra cost. Temporary reduced capacity.
ROLLING WITH ADDITIONAL BATCH:
[Old][Old][Old][Old]
[Old][Old][Old][Old][New] ← extra batch added
[New][New][New][Old]
[New][New][New][New]
Full capacity throughout. Costs extra for duration.
IMMUTABLE:
New ASG created alongside existing, tested, then swapped.
Safest. Full capacity. Can roll back by terminating new ASG.
TRAFFIC SPLITTING:
New version deployed to new instances.
% traffic shifted to new instances (canary release).
Monitors health, completes shift or rolls back.

For production, rolling with additional batch or immutable are the recommended choices. All At Once is never appropriate for production.

Terminal window
# Deploy with immutable strategy
aws elasticbeanstalk update-environment \
--environment-name production \
--option-settings Namespace=aws:elasticbeanstalk:command,OptionName=DeploymentPolicy,Value=Immutable

Customising with .ebextensions

.ebextensions is a directory in your application bundle with YAML configuration files. These run during environment provisioning and deployment, giving you control over OS packages, files, commands, and AWS resource configuration.

.ebextensions/01-packages.config
packages:
yum:
git: []
postgresql-devel: []
commands:
01-set-timezone:
command: "timedatectl set-timezone UTC"
test: "[ \"$(timedatectl | grep 'Time zone' | awk '{print $3}')\" != 'UTC' ]"
.ebextensions/02-environment.config
option_settings:
aws:autoscaling:asg:
MinSize: 2
MaxSize: 8
aws:ec2:instances:
InstanceTypes: t3.small,t3.medium
aws:elasticbeanstalk:environment:proxy:
ProxyServer: nginx
aws:elasticbeanstalk:environment:proxy:staticfiles:
/static: static
.ebextensions/03-cloudwatch.config
files:
"/opt/elasticbeanstalk/tasks/taillogs.d/app-logs.conf":
mode: "000644"
content: |
/var/log/app/application.log

The staticfiles setting tells nginx to serve /static/ files directly without proxying to your application, which reduces load on the app server.

Environment Variables and Secrets

Set environment properties in the Beanstalk console, CLI, or .ebextensions:

Terminal window
aws elasticbeanstalk update-environment \
--environment-name production \
--option-settings \
Namespace=aws:elasticbeanstalk:application:environment,OptionName=DATABASE_URL,Value=postgres://... \
Namespace=aws:elasticbeanstalk:application:environment,OptionName=NODE_ENV,Value=production

For sensitive values, do not put secrets in option settings (they appear in the console). Instead, reference Secrets Manager from your application code and grant the Beanstalk instance profile permission to read the secret.

Database Integration

Beanstalk can create an RDS database as part of the environment. This is convenient for development but problematic for production — the database lifecycle is tied to the environment. Deleting the environment deletes the database.

For production:

  1. Create RDS outside of Beanstalk in a separate VPC stack
  2. Put the database URL in Beanstalk environment properties (or better, Secrets Manager)
  3. Configure the Beanstalk environment’s VPC and security groups to allow the instance profile to reach the database
Terminal window
# Create environment with existing VPC/RDS
aws elasticbeanstalk create-environment \
--application-name my-app \
--environment-name production \
--solution-stack-name "64bit Amazon Linux 2023 v4.0.0 running Python 3.12" \
--option-settings \
Namespace=aws:ec2:vpc,OptionName=VPCId,Value=vpc-0a1b2c \
Namespace=aws:ec2:vpc,OptionName=Subnets,Value="subnet-0a1b2c,subnet-0d4e5f" \
Namespace=aws:ec2:vpc,OptionName=ELBSubnets,Value="subnet-elb-0a1b2c,subnet-elb-0d4e5f"

When to Move Beyond Beanstalk

Beanstalk is an excellent starting point, but teams outgrow it:

The typical path is: Beanstalk for early-stage startup → ECS when the team grows and needs more control → EKS when Kubernetes features or portability become necessary.

Common Interview Questions

Q: Does Elastic Beanstalk cost anything? Beanstalk itself is free — you pay only for the underlying resources (EC2, load balancer, RDS). The same EC2 instances cost the same whether deployed by Beanstalk or manually. The premium is time savings, not dollars.

Q: What is the difference between All At Once and Rolling deployments? All At Once deploys to every instance simultaneously, causing brief downtime. Rolling deploys to a batch at a time, keeping remaining instances serving traffic. All At Once is faster; Rolling avoids downtime at the cost of temporary reduced capacity.

Q: How do you run database migrations with Beanstalk deployments? Use a .ebextensions container command with leader_only: true to run the migration on one instance:

container_commands:
01-migrate:
command: "python manage.py migrate"
leader_only: true

Q: Can you run multiple applications in one Beanstalk environment? No, each environment runs a single application version. For multiple services, create separate environments or consider ECS with multiple services.