Based on the DVA-C02 exam guideReport an error
The typical scene when a startup first adopts AWS: two developers, code in Flask or Express, "We have to launch this somehow, but what's ALB, what's ASG, what's IAM Role?" To solve this situation, AWS launched Elastic Beanstalk in January 2011. The promise: "Just zip and upload your code, we'll automatically create EC2, ELB, ASG, CloudWatch — everything."
On DVA-C02, Beanstalk joins ECS, Lambda, App Runner as a "when to choose which compute" scenario axis. Especially the six deployment strategies' trade-offs, .ebextensions vs .platform distinction, and the RDS-inside-environment trap are consistent high-frequency exam points. This article begins from Beanstalk's internal structure — actually CloudFormation abstraction on top — through how each deployment strategy actually works.
Beanstalk launched in 2011 when Heroku (2007 startup, 2010 Salesforce acquisition) was setting PaaS market standards. git push heroku main deploying code to production in one line was revolutionary then. AWS brought that experience to its platform while claiming "deeper AWS infrastructure access than Heroku" as differentiation.
Beanstalk's promise in one line: "Mind your code only, EC2/ALB/ASG/CloudWatch/VPC we handle." But that promise's trade-off is the key — when abstraction leaks (special nginx tuning, specific OS package needed), Beanstalk suddenly feels limiting.
💡 Related theory: Whether PaaS abstraction truly works relates directly to "Joel Spolsky's Law of Leaky Abstractions" (2002). "Every nontrivial abstraction leaks somewhat," the thesis goes. Beanstalk hides EC2/ALB complexity, but mid-operation when special needs emerge, you must touch underlying layers and the abstraction breaks.
.ebextensionsand.platformare precisely "escape hatches" filling abstraction cracks.
🔍 Going deeper: Internally, Beanstalk creates CloudFormation stacks. One
eb creategenerates CloudFormation template defining EC2, ALB, ASG, Security Group, IAM Role, CloudWatch Alarm — that template deploys. Beanstalk environment = CloudFormation stack's friendly UI. This fact explains ① what deletes when environment dies ② why drift detection works ③ why Beanstalk resources import into CFN.
Beanstalk environments come in two kinds. Both exist in same application, usually together.
[Route 53 or Beanstalk DNS]
│
▼
[Application Load Balancer]
│
├── [EC2-1 (web)] ┐
├── [EC2-2 (web)] ├── Auto Scaling Group
└── [EC2-N (web)] ┘
│
▼
[RDS (separate recommended)]
[SQS Queue]
│ (message arrives)
▼
[SQS Daemon on EC2]
│ (converts message to HTTP POST)
▼
[Application container (port 80)]
🔍 Going deeper: Worker environment's magic is a separate process called SQS Daemon. Pre-installed on EC2, this daemon polls SQS queue, converts arriving message to application HTTP endpoint (default
/) as POST. Application is just HTTP server; no SQS SDK needed. Pattern unifies event and HTTP handling in same codebase. Heroku's worker dyno follows same philosophy.
# cron.yaml (Worker environment scheduled jobs)
version: 1
cron:
- name: "daily-report"
url: "/jobs/daily-report"
schedule: "0 0 * * *"
- name: "hourly-cleanup"
url: "/jobs/cleanup"
schedule: "0 * * * *"SQS Daemon reads cron.yaml, auto-creates schedule, at time inserts message into its queue. Message flows back to application HTTP for processing. Schedule work without external cron service — clean pattern.
⚠️ Trap: Worker has no ALB. SQS Daemon → EC2 local application direct HTTP call. External HTTP exposure needs separate Web Server Environment. When "Worker needs public endpoint" appears on exam, it's almost always a trap — needs separate Web environment.
Beanstalk's deployment strategy table appears on almost every exam. Memorizing each strategy's "downtime / deploy speed / cost / rollback speed" catches 70%+ of scenario problems.
| Strategy | Downtime | New Instances | Extra Cost | Rollback Time | Best For |
|---|---|---|---|---|---|
| All at once | Yes (minutes) | None | None | Redeploy (slow) | Dev/budget |
| Rolling | None | None | None | Redeploy | General production |
| Rolling with additional batch | None | Some | +Cost | Redeploy | Capacity maintenance |
| Immutable | None | New ASG entirely | 2x (temporary) | Fast (ASG delete) | Safe production |
| Traffic Splitting (Canary) | None | New ASG | 2x (temporary) | Auto (CloudWatch) | Gradual validation |
| Blue/Green (manual) | None | New environment | 2x | Instant (URL swap) | Complete separation |
💡 Scenario Quick Map:
- "Minimum cost + simple" → All at once
- "General production" → Rolling
- "Capacity never drops" → Rolling with additional batch
- "Production + instant rollback" → Immutable
- "10% first, auto-validate" → Traffic Splitting
- "Completely separated + one-swap" → Blue/Green
Initially: [Existing ASG]
[EC2 v1] [EC2 v1] [EC2 v1] ← 100% traffic
Step 1: [Existing ASG] [New Temp ASG]
[EC2 v1] [EC2 v1] [EC2 v1] [EC2 v2] (1) ← Await health check
Step 2: [Expand new ASG]
[EC2 v1]... [EC2 v2] [EC2 v2] [EC2 v2]
Step 3: [Temp → Permanent swap]
[EC2 v2] [EC2 v2] [EC2 v2] ← 100% traffic
Step 4: Delete existing ASG
[EC2 v2] [EC2 v2] [EC2 v2]
🔍 Going deeper: Immutable's core is "step 1: boot v2 instance(s) first, must pass health check before proceeding." If v2 fails startup, new ASG deletes immediately, existing untouched — production unaffected. Rolling's critical difference: stops existing first, new on same slot, if new fails that slot's capacity vanishes.
Initially: [ASG v1: 3 instances] 100% traffic
(weighted: v1 = 100%)
Step 1: [ASG v1: 3] [ASG v2: 3] v1 = 90%, v2 = 10%
(monitor metrics N minutes)
Success: [ASG v1: deleted]
[ASG v2: 3] 100% traffic
Failure: [ASG v2: deleted] Auto rollback
[ASG v1: 3] 100% traffic
⚠️ Trap: Traffic Splitting uses ALB weighted target group feature. This doesn't work with Classic Load Balancer or Network Load Balancer. When "Beanstalk + Traffic Splitting" appears on exam, ALB is implicit prerequisite.
Customizing EC2 inside Beanstalk environment has two ways. Recommended approach changed over time.
# .ebextensions/01_packages.config
packages:
yum:
git: []
jq: []
htop: []
files:
"/etc/nginx/conf.d/custom.conf":
mode: "000644"
owner: root
group: root
content: |
client_max_body_size 50M;
commands:
01_npm_install:
command: "npm install -g pm2"
container_commands:
01_migrate:
command: "python manage.py migrate"
leader_only: true # Run on one ASG instance only (DB migration etc.)
option_settings:
aws:elasticbeanstalk:application:environment:
DJANGO_SETTINGS: production
aws:autoscaling:asg:
MinSize: '2'
MaxSize: '10'🔍 Going deeper:
.ebextensionsfiles execute in alphabetical order. That's why01_xxx.config,02_xxx.configprefix enforces order.commandsrun before application code unpacked,container_commandsafter. DB migration requiring application code needscontainer_commands.
⚠️ Trap:
leader_only: trueguarantees exactly one ASG instance execution. Running DB migration simultaneously on all instances causes race condition —leader_onlyis mandatory. However, this option only applies at initial deploy; newly added instances (scale-out) don't run it.
my-app/
.platform/
nginx/
conf.d/
custom.conf # Add nginx config (doesn't overwrite base)
hooks/
prebuild/
01_install_pkg.sh # After code download, before build
predeploy/
01_run_migration.sh # After build, before deploy
postdeploy/
01_warm_cache.sh # After deploy
💡 Related theory: Post-Amazon Linux 2 (2017), AWS redesigned
.ebextensionsfunctionality via.platform/directory. Reasons: ① clearer hook timing separation ② standard shell script writing ③ append-only nginx config instead of full replacement..ebextensionsstill works, but.platform/is recommended for new projects. AL2 environments can use both.
Beanstalk console has "create RDS together with environment" option. Convenient-looking but almost always anti-pattern for production.
[Beanstalk Environment]
├── EC2 (web)
├── ALB
├── ASG
└── RDS ← Deletes when environment deletes!
Reason: Beanstalk includes RDS in environment's CloudFormation stack. eb terminate or console environment delete removes RDS too. Data vanishes.
⚠️ Trap: Exam often shows "Beanstalk environment deleted, production data gone" scenario — standard answer is this. Correct pattern: Create RDS separately outside Beanstalk, connect via environment variables only. Environment can redeploy many times; DB stays safe.
# .ebextensions connecting external RDS
option_settings:
aws:elasticbeanstalk:application:environment:
RDS_HOSTNAME: my-prod-db.cxxxx.ap-northeast-2.rds.amazonaws.com
RDS_PORT: '5432'
RDS_DB_NAME: myapp
# Passwords via Secrets Manager reference📚 Case study: AWS re:Invent customer talk, SaaS company separated staging/prod Beanstalk environments, created staging RDS together. During staging redeploy, RDS deleted. Fortunately auto-backup existed, 2-hour recovery took place. Policy changed: all RDS outside Beanstalk.
# Project initialization
eb init --platform "Python 3.11 running on 64bit Amazon Linux 2023" --region ap-northeast-2
# Create environment
eb create production-env --instance-type t3.medium --elb-type application
# Deploy new version (zips current directory, uploads)
eb deploy
# Set environment variables
eb setenv DB_HOST=mydb.com LOG_LEVEL=INFO
# View logs (last 100 lines from CloudWatch)
eb logs --all
# SSH access
eb ssh
# Blue/Green: URL swap
eb swap production-env --destination_name staging-env
# Delete environment (all resources including RDS if inside)
eb terminate production-env| Dimension | Beanstalk | Heroku | Google App Engine | Azure App Service |
|---|---|---|---|---|
| Hosting | User AWS account EC2 | Heroku multitenant | GCP multitenant (Standard) or GCE (Flexible) | Azure multitenant |
| Pricing | EC2/ALB/RDS standard rates | Per dyno hour | Per instance hour | Per plan hour |
| Infrastructure Access | Full (SSH possible) | Limited | Limited (Standard), Full (Flexible) | Limited |
| Auto-scaling | ASG integrated | Heroku autoscaler | Auto | Auto |
| Database | RDS external recommended | Heroku Postgres add-on | Cloud SQL separate | Azure SQL separate |
| Custom Runtime | Possible (.platform) | Buildpack | Possible (Flexible) | Possible (Custom Container) |
💡 Related theory: Biggest Heroku-Beanstalk difference is infrastructure access. Heroku: "don't look how instances work" — complete abstraction. Beanstalk: "SSH in, tweak nginx directly if needed" — escape hatch exists. This matters for production debugging — Heroku "why OOM?" is hard; Beanstalk
eb sshthentopanswers it.
| Scenario | Choice |
|---|---|
| Fast PoC, no time learning AWS depth | Beanstalk |
| Standard web app (Django, Express, Rails) + full infrastructure access | Beanstalk |
| Docker containers + microservices | ECS Fargate / EKS |
| Event-driven short-lived functions, zero cost idle | Lambda |
| Container + autoscaling without Kubernetes + automatic HTTPS | App Runner |
| HPC, GPU, special instances | EC2 direct |
🔍 Going deeper: 2021's AWS App Runner is Beanstalk's spiritual successor. "Container image or source code → auto build + deploy + autoscale + HTTPS" is App Runner's promise — simpler and container-native. Internally AWS treats Beanstalk as "not deprecated but not actively recommended"; new workloads steer toward App Runner or ECS Fargate.
Beanstalk is "AWS's most ambitious attempt to abstract all infrastructure complexity into one command." The promise mostly holds, but abstraction cracks needed .ebextensions/.platform escape hatches, and RDS lifecycle management remains user responsibility.
For DVA-C02 prep: six deployment strategies' trade-offs, Web vs Worker environment difference, "don't put RDS inside environment" trap — nail these three and 80% of Beanstalk questions solve themselves. Next article: this week's finale — CloudFormation's internals and SAM/CDK.
Click a choice to reveal the answer and explanation.
Question 1
Best Beanstalk deployment strategy for production with no downtime, fastest rollback possible?
Question 2
In .ebextensions, to run DB migration on one ASG instance only?
Question 3
Difference between Beanstalk Web Server and Worker Environment?
Question 4
When Beanstalk environment created with "Create new RDS DB" option in console, then eb terminate executed, what happens?
Question 5
Amazon Linux 2 Beanstalk, increase nginx client_max_body_size to 50MB. Recommended method?
Question 6
Beanstalk Traffic Splitting prerequisite?
Question 7
Beanstalk Immutable deployment, first new ASG instance fails health check, what happens?