Elastic Beanstalk
A comprehensive deep dive into AWS Elastic Beanstalk — environment types, deployment policies, .ebextensions, Procfile, platform hooks, environment tiers, configuration options, Docker support, blue/green deployments, and DVA-C02 exam essentials.
What is Elastic Beanstalk?
Elastic Beanstalk is a Platform-as-a-Service (PaaS) that provisions and manages the infrastructure for your web application — EC2 instances, Auto Scaling Group, Load Balancer, security groups, and CloudWatch monitoring — while you focus only on your code.
Core mental model: You upload a ZIP or Docker image, choose a platform (Node.js, Python, Java, Go, .NET, Ruby, PHP, Docker), and Beanstalk handles everything else. You retain full access to the underlying resources — Beanstalk doesn't hide them, it just automates their creation.
Application Hierarchy
| Concept | Description |
|---|---|
| Application | Top-level container — groups environments and versions |
| Application Version | Specific deployable artifact (ZIP stored in S3) |
| Environment | Running instance of a version (Web Server or Worker) |
| Environment Tier | Web Server (ALB-facing) or Worker (SQS-facing) |
Environment Tiers
Web Server Environment
Handles HTTP/HTTPS traffic:
Components created automatically:
- ALB (Application Load Balancer) or Classic LB
- Auto Scaling Group with health-check-based replacement
- EC2 instances with Beanstalk agent (
eb-engine) - Security groups
- CloudWatch alarms for CPU scaling
Worker Environment
Processes background jobs from an SQS queue:
- Beanstalk installs an SQS daemon on each worker instance
- Daemon polls SQS and POSTs each message to
http://localhost/(or your configured path) - Your app responds with HTTP 200 to acknowledge; non-200 leaves the message in the queue
- cron.yaml enables scheduled tasks (daemon creates/sends messages on schedule)
1# cron.yaml — scheduled tasks for Worker environment
2version: 1
3cron:
4 - name: "DailyReport"
5 url: "/tasks/daily-report"
6 schedule: "0 8 * * *" # 8 AM UTC daily
7 - name: "HourlySync"
8 url: "/tasks/sync"
9 schedule: "0 * * * *" # every hourDeployment Policies
| Policy | Downtime | Extra Cost | Speed | Rollback |
|---|---|---|---|---|
| All at Once | Yes | No | Fastest | Re-deploy old version |
| Rolling | No (reduced capacity) | No | Medium | Re-deploy old version |
| Rolling with additional batch | No (full capacity) | Yes (temp extra instances) | Medium | Re-deploy old version |
| Immutable | No | Yes (doubles fleet temporarily) | Slow | Terminate new ASG |
| Traffic Splitting (Canary) | No | Yes (temp extra instances) | Medium | Shift traffic back |
| Blue/Green | No | Yes (second environment) | Slow | Swap URLs back |
All at Once
Deploys to all instances simultaneously. Fastest but causes downtime — only for dev/test.
Rolling
Deploys to a batch of instances at a time. Batch size is configurable (fixed or %). Running capacity is reduced during deployment.
Rolling with Additional Batch
Launches an extra batch of instances first, so capacity never drops below 100%.
Immutable
Safest update strategy. New instances are launched in a separate ASG. If health checks fail, terminate the new ASG — original instances untouched.
Traffic Splitting (Canary)
Routes a configurable % of traffic to new version instances. Monitor for errors during evaluation period, then shift 100% or roll back.
Blue/Green (Manual — not a native Beanstalk policy)
- Clone the production environment (or create a new one)
- Deploy new version to the green environment
- Test thoroughly
- Swap Environment URLs — instant DNS switch, zero downtime
- Rollback: swap URLs back
1# Swap environment URLs (Blue/Green cutover)
2aws elasticbeanstalk swap-environment-cnames --source-environment-name myapp-prod --destination-environment-name myapp-green.ebextensions
.ebextensions/ is a directory of YAML/JSON config files in your application bundle. Beanstalk processes them alphabetically before starting your application.
1myapp.zip
2├── .ebextensions/
3│ ├── 01-packages.config
4│ ├── 02-environment.config
5│ └── 03-commands.config
6├── src/
7└── package.jsonInstall packages and run commands
1# .ebextensions/01-packages.config
2packages:
3 yum:
4 git: []
5 nginx: []
6
7commands:
8 01_create_dir:
9 command: "mkdir -p /var/app/logs"
10 ignoreErrors: false
11
12 02_set_permissions:
13 command: "chmod 755 /var/app/logs"
14
15container_commands:
16 # Runs AFTER app source is extracted but BEFORE app starts
17 # Has access to app source in /var/app/staging/
18 01_migrate_db:
19 command: "npm run migrate"
20 leader_only: true # only runs on one instance (leader election)
21 env:
22 NODE_ENV: productionEnvironment configuration
1# .ebextensions/02-environment.config
2option_settings:
3 aws:elasticbeanstalk:application:environment:
4 NODE_ENV: production
5 LOG_LEVEL: info
6
7 aws:autoscaling:asg:
8 MinSize: 2
9 MaxSize: 10
10
11 aws:elasticbeanstalk:environment:proxy:
12 ProxyServer: nginx
13
14 aws:elb:loadbalancer:
15 CrossZone: trueAdd files to the instance
1# .ebextensions/03-files.config
2files:
3 "/etc/nginx/conf.d/proxy.conf":
4 mode: "000644"
5 owner: root
6 group: root
7 content: |
8 client_max_body_size 20M;
9 proxy_read_timeout 300;
10
11 "/opt/elasticbeanstalk/hooks/appdeploy/post/99_restart.sh":
12 mode: "000755"
13 owner: root
14 group: root
15 content: |
16 #!/bin/bash
17 echo "Post-deploy hook: $(date)" >> /var/log/deploy.logcommands vs container_commands
| commands | container_commands | |
|---|---|---|
| When runs | Before app source is extracted | After app source extracted, before app starts |
| Working directory | / | /var/app/staging |
| leader_only option | ❌ | ✅ (run on one instance only) |
| Use case | OS setup, package install | DB migrations, asset compilation |
Platform Hooks
Newer Beanstalk platform versions support platform hooks — scripts dropped into well-known directories:
1.platform/
2├── hooks/
3│ ├── prebuild/ # before build phase
4│ ├── build/ # during build
5│ ├── predeploy/ # after build, before new app starts
6│ └── postdeploy/ # after new app is running
7├── nginx/
8│ └── conf.d/
9│ └── custom.conf # extra nginx config
10└── confighooks/
11 └── predeploy/ # runs on config-only changes1# .platform/hooks/predeploy/01_set_env.sh
2#!/bin/bash
3set -e
4export SECRET=$(aws ssm get-parameter --name /myapp/prod/secret --with-decryption --query Parameter.Value --output text)
5echo "SECRET=$SECRET" >> /etc/environmentEnvironment Configuration Options
1# View all configuration options for an environment
2aws elasticbeanstalk describe-configuration-options --environment-name myapp-prod
3
4# Update a setting without redeploying code
5aws elasticbeanstalk update-environment --environment-name myapp-prod --option-settings Namespace=aws:autoscaling:asg,OptionName=MaxSize,Value=20
6
7# Saved configurations — snapshot an environment's settings
8aws elasticbeanstalk create-configuration-template --application-name myapp --template-name prod-baseline --environment-id e-abc123
9
10# Apply saved configuration to new environment
11aws elasticbeanstalk create-environment --application-name myapp --environment-name myapp-prod-v2 --template-name prod-baselineDocker on Elastic Beanstalk
Single Container
1{
2 "AWSEBDockerrunVersion": "1",
3 "Image": {
4 "Name": "123456789012.dkr.ecr.us-east-1.amazonaws.com/myapp:latest",
5 "Update": "true"
6 },
7 "Ports": [{ "ContainerPort": 8080, "HostPort": 80 }],
8 "Volumes": [{ "HostDirectory": "/var/app/logs", "ContainerDirectory": "/app/logs" }]
9}Multi-Container (ECS-backed)
Beanstalk creates an ECS cluster under the hood when you use the Multi-Container Docker platform:
1{
2 "AWSEBDockerrunVersion": 2,
3 "containerDefinitions": [
4 {
5 "name": "app",
6 "image": "123456789012.dkr.ecr.us-east-1.amazonaws.com/myapp:latest",
7 "memory": 512,
8 "portMappings": [{ "hostPort": 80, "containerPort": 8080 }],
9 "essential": true,
10 "links": ["redis"]
11 },
12 {
13 "name": "redis",
14 "image": "redis:7-alpine",
15 "memory": 128,
16 "essential": false
17 }
18 ]
19}EB CLI Workflow
1# Initialize a project
2eb init myapp --region us-east-1 --platform "Node.js 20"
3
4# Create environments
5eb create myapp-prod --elb-type application --scale 2
6eb create myapp-staging
7
8# Deploy current code
9eb deploy myapp-prod
10
11# Deploy specific version
12eb deploy myapp-prod --version v1.2.3
13
14# Open environment URL in browser
15eb open
16
17# SSH into an instance
18eb ssh myapp-prod
19
20# View recent logs
21eb logs --all
22
23# Check environment health
24eb health myapp-prod --refresh
25
26# Terminate environment (keeps application + versions)
27eb terminate myapp-prodManaged Platform Updates
Beanstalk can automatically apply OS and runtime patches in a configurable maintenance window:
1# .ebextensions/managed-updates.config
2option_settings:
3 aws:elasticbeanstalk:managedactions:
4 ManagedActionsEnabled: true
5 PreferredStartTime: "Sun:03:00" # UTC
6
7 aws:elasticbeanstalk:managedactions:platformupdate:
8 UpdateLevel: minor # patch | minor
9 InstanceRefreshEnabled: true| Update Level | What it includes |
|---|---|
patch | Security patches only |
minor | Minor version updates (e.g., Node.js 20.x → 20.y) |
DVA-C02 Quick Reference
| Topic | Key Fact |
|---|---|
| Beanstalk infrastructure | CloudFormation stack under the hood |
| Web Server tier components | ALB + EC2 + ASG |
| Worker tier components | SQS + EC2 + SQS daemon |
| Worker message delivery | Daemon POSTs to localhost endpoint |
| cron.yaml purpose | Scheduled tasks in Worker environment |
| All at Once downtime | Yes — fastest, dev/test only |
| Immutable update safety | Safest — new ASG, original untouched |
| Blue/Green cutover | Swap Environment URLs (DNS swap) |
| .ebextensions processed order | Alphabetically |
| commands vs container_commands | container_commands: after extract, has leader_only |
| leader_only purpose | Run command on one instance only (e.g., DB migrate) |
| Platform hooks location | .platform/hooks/predeploy/ etc. |
| Saved configuration | Snapshot of environment settings, reusable |
| Managed updates maintenance | Configurable maintenance window (day + time) |
| Rolling with additional batch | Full capacity maintained — no capacity reduction |
| Traffic Splitting | Canary — configurable % to new version |
| EB CLI deploy command | eb deploy |
| Multi-container Docker | Uses ECS cluster under the hood |
Practice Questions3
Q1. A developer deploys a web app on AWS Elastic Beanstalk. They want to deploy a new version with zero downtime, while keeping the same number of instances running. Which deployment policy should they choose?
Select one answer before revealing.
Q2. A developer uses Elastic Beanstalk and needs to run a custom script to install a library on EC2 instances before the application starts. Where should this script be placed?
Select one answer before revealing.
Q3. After deploying a new Elastic Beanstalk application version, a developer discovers a critical bug. They need to immediately restore the previous working version. What should the developer do?
Select one answer before revealing.