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 Questions5
Q1. A developer wants to deploy a long-running Node.js web application to AWS quickly, without manually configuring EC2 instances, load balancers, or Auto Scaling — but still needs the ability to access and customize those underlying resources later. Which service best fits?
Select one answer before revealing.
Q2. When you deploy an application with Elastic Beanstalk, who manages the underlying EC2 instances, load balancer, and Auto Scaling group?
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.
Q4. 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.
Q5. 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.