AWS Elastic Beanstalk โ
Platform as a Service
Deploy and scale web applications without managing infrastructure. Upload your code โ Beanstalk provisions EC2 instances, load balancers, auto scaling, and monitoring automatically.
โก Elastic Beanstalk in 30 Seconds
- PaaS for AWS โ upload your code, Beanstalk creates and manages the infrastructure
- Provisions EC2, Auto Scaling, ELB, CloudWatch, Security Groups automatically
- You retain full control โ you can SSH into instances, customize configs, pick instance types
- Supports Java, .NET, Node.js, Python, Ruby, Go, PHP, Docker โ and custom platforms
- No additional charge โ you pay only for the underlying AWS resources (EC2, RDS, ELB, etc.)
What is Elastic Beanstalk
Cloud computing offers different levels of control vs. convenience. At the lowest level, Infrastructure as a Service (IaaS) gives you raw servers โ you install the OS, configure networking, deploy your app. At the highest level, Software as a Service (SaaS) gives you a finished product โ Gmail, Slack. In between sits Platform as a Service (PaaS).
PaaS takes care of the platform layer: operating system, runtime, middleware, and scaling infrastructure. You focus only on your application code. You don't patch servers, configure load balancers, or set up monitoring โ the platform does it for you.
IaaS โ You Manage Most
- Raw EC2 instances
- You install OS, runtime
- You configure networking
- You set up monitoring
- Maximum control
PaaS โ Balanced
- Elastic Beanstalk, Heroku
- Platform manages servers
- You deploy code + config
- Auto scaling built in
- Control when you need it
Serverless โ Least Mgmt
- Lambda, Fargate
- No servers visible at all
- Pay per invocation/second
- Event-driven model
- Least operational overhead
๐ Key insight: Elastic Beanstalk is PaaS on top of IaaS. It uses EC2, Auto Scaling, ELB, and CloudWatch underneath. The difference is that Beanstalk creates and configures those resources automatically. You still own them โ you can inspect, customize, and SSH into them. Beanstalk is the convenience layer, not a black box.
Imagine you want to deploy a simple Node.js web app on AWS. Without Beanstalk, you would need to:
Manual Approach (EC2)
- Launch EC2 instances
- Install Node.js runtime
- Configure security groups
- Set up an ALB + target groups
- Create an Auto Scaling Group
- Configure CloudWatch alarms
- Set up deployment pipeline
- Manage OS patches & updates
~15 services, hours of setup
Beanstalk Approach
- Select "Node.js" platform
- Upload your ZIP/WAR
- Choose instance type (optional)
- Click "Create Environment"
- Done. Everything provisioned.
Same result: ALB + ASG + EC2 + CloudWatch โ created in minutes.
Beanstalk exists because most developers want to deploy code, not configure infrastructure. It bridges the gap between "I have a ZIP file" and "I have a production-grade, load-balanced, auto-scaling deployment."
The three most common AWS compute options for applications โ each with a different tradeoff between control and convenience:
| Feature | EC2 (IaaS) | Elastic Beanstalk (PaaS) | Lambda (Serverless) |
|---|---|---|---|
| What you deploy | AMI + config scripts | ZIP/WAR/Docker image | Function code |
| Server management | Full (you manage everything) | Automated (but accessible) | None (invisible) |
| Scaling | Manual ASG configuration | Auto (built-in ASG) | Automatic per-request |
| Load balancing | You create ALB | Auto (creates ALB for you) | API Gateway |
| OS access | Full SSH | SSH available | No OS access |
| Runtime | Any (you install) | Supported platforms | Supported runtimes |
| Execution model | Always running | Always running | Event-driven (on-demand) |
| Max execution time | Unlimited | Unlimited | 15 minutes |
| Pricing | Per instance-hour | Per underlying resources | Per request + duration |
| Best for | Full control, custom setups | Standard web apps, quick deploy | Short tasks, event handlers |
๐ Rule of thumb: Use EC2 when you need full control over the OS and custom configurations. Use Elastic Beanstalk when you want a standard web application deployed quickly with auto-scaling. Use Lambda when your workload is event-driven, short-lived, and you want zero server management.
Beanstalk IS
- An orchestration service โ it creates and manages other AWS services for you
- A free abstraction โ no charge for Beanstalk itself (you pay for EC2, ELB, etc.)
- An opinionated deployer โ provides best-practice defaults
- Transparent โ you can see and access everything it creates
- Built on CloudFormation under the hood
Beanstalk IS NOT
- A separate compute service โ it uses EC2 instances
- A black box โ you retain full access to all resources
- Serverless โ your instances run 24/7 (unlike Lambda)
- A container orchestrator โ use ECS/EKS for that
- Free infrastructure โ you pay for the underlying resources
Think of deploying your app like arriving at a hotel:
EC2 = Self-Parking
You drive your own car, find a spot, park it, lock it, remember where you parked. Full control โ but you do all the work.
Beanstalk = Valet Parking
You hand your keys to the valet. They park your car, but you can still go see it, move it yourself, or tell them which floor. Convenient + accessible.
Lambda = Taxi / Uber
You don't have a car at all. Someone drives you when you need it, and you pay per ride. No car to manage โ but you can't customize the vehicle.
Elastic Beanstalk = Valet Parking for your code.
- You provide the car (application code)
- The valet handles parking (EC2, ASG, ELB, CloudWatch)
- You can still access, inspect, and customize everything
- You pay for the parking spot โ not the valet service
When you create a Beanstalk environment, here is what happens behind the scenes:
You Provide
- Application code (ZIP, WAR, or Docker)
- Platform choice (Node.js, Java, Python, etc.)
- Optional: instance type, scaling rules, env vars
Beanstalk Creates
- EC2 instances with your platform runtime
- Auto Scaling Group for scaling
- Elastic Load Balancer for traffic distribution
- Security Groups for network access
- CloudWatch alarms for monitoring
- S3 bucket for version storage
Under the hood, Beanstalk generates a CloudFormation template that describes all these resources. When you update your code or change configuration, Beanstalk updates the CloudFormation stack. This is why Beanstalk is not magic โ it's automation on top of services you already know.
You provide code โ Beanstalk generates CloudFormation โ CloudFormation provisions EC2, ASG, ELB, CloudWatch, S3, SNS
Elastic Beanstalk is AWS's PaaS โ the fastest path from code to production.
- PaaS sits between IaaS (EC2) and Serverless (Lambda) โ you manage code, Beanstalk manages infrastructure
- Beanstalk creates real AWS resources โ EC2, ASG, ELB, CloudWatch, S3 โ you can see and access them all
- Built on CloudFormation under the hood โ every environment is an infra-as-code stack
- Free service โ you pay only for the underlying resources (EC2, ELB, etc.)
- Mental model: Valet Parking โ you hand over the keys, but you can always go check on your car
Core Concepts
Elastic Beanstalk organizes everything into a clear hierarchy. Understanding these five building blocks is essential before you deploy anything:
Application
The top-level container. An application is a logical collection โ it groups all environments, versions, and configurations for one project. Think of it as a folder label: "my-web-app."
One application can have multiple environments (dev, staging, prod) and multiple versions (v1, v2, v3).
Application Version
A specific, labeled release of your code. When you upload a ZIP/WAR, Beanstalk stores it in S3 and labels it as a version (e.g., "v1.2.3"). Versions are immutable โ once uploaded, they don't change.
You can deploy any version to any environment. Rollback = deploy a previous version.
Environment
A running instance of your application. Each environment is a collection of AWS resources (EC2, ELB, ASG) running one version of your code. You typically have separate environments for dev, staging, and production.
Environment Configuration
The settings that define how the environment behaves: instance type, scaling rules, environment variables, security groups, load balancer type. Saved as configuration templates for reuse.
Platform
The OS + runtime combination. Beanstalk provides managed platforms: "Python 3.11 on Amazon Linux 2023", "Node.js 18 on Amazon Linux 2023", "Docker on Amazon Linux 2023", etc.
๐ How they relate: An Application contains many Versions. You deploy one Version into an Environment. The Environment runs on a Platform and is configured via an Environment Configuration. Simple hierarchy โ Application โ Version โ Environment.
Beanstalk offers two environment types, each designed for a different workload pattern:
Web Server Environment
- Handles HTTP/HTTPS requests from users
- Creates an ELB (load balancer) + ASG (auto scaling)
- EC2 instances run a web server (Nginx/Apache) + your app
- ELB distributes traffic across instances
- Health checks ensure only healthy instances receive traffic
- Use case: APIs, websites, web applications
Worker Environment
- Processes background tasks from an SQS queue
- No load balancer โ not internet-facing
- Beanstalk creates an SQS queue automatically
- A daemon on each instance polls SQS and POSTs messages to
localhost - Auto scales based on queue depth
- Use case: Email sending, image processing, report generation
| Feature | Web Server Environment | Worker Environment |
|---|---|---|
| Traffic source | HTTP/HTTPS from internet | SQS messages |
| Load balancer | Yes (ALB, CLB, or NLB) | No |
| Auto scaling trigger | CPU, latency, requests | SQS queue depth |
| Entry point | ELB DNS endpoint | SQS queue URL |
| Daemon | Web server (Nginx) | SQS daemon โ POST to localhost |
| Typical use | APIs, websites | Background jobs, async tasks |
๐ Common pattern: Use a Web Server environment for your API (receives user requests) and a Worker environment for heavy processing. The web tier sends messages to SQS, the worker tier processes them. Decoupled, scalable, and each tier scales independently.
Beanstalk provides managed platforms โ pre-configured AMIs with the OS, runtime, and web server already installed. You don't need to install Node.js or configure Nginx โ the platform handles it.
Java
Corretto 8/11/17/21 with Tomcat or standalone JAR. Deploy WAR files or fat JARs.
Node.js
Node.js 16/18/20 with Nginx reverse proxy. Deploy ZIP with package.json.
Python
Python 3.8โ3.12 with WSGI (Gunicorn). Deploy ZIP with requirements.txt.
Ruby
Ruby 3.0โ3.2 with Puma. Deploy ZIP with Gemfile.
PHP
PHP 8.0โ8.3 with Apache/Nginx. Deploy ZIP with composer.json.
Go
Go 1.20+. Deploy a compiled binary or source with go.mod.
.NET
.NET 6/8 on Linux or Windows. Deploy ZIP or publish output.
Docker
Single or multi-container Docker. Deploy Dockerfile or docker-compose.yml. Most flexible option.
Custom Platform
Build your own AMI with Packer. Use any language or runtime Beanstalk doesn't natively support.
๐ Platform versions: Beanstalk supports Amazon Linux 2023 (current, recommended) and Amazon Linux 2 (maintenance mode). New environments should always use AL2023. Amazon Linux 1 (AL1) was retired December 31, 2023. If you have AL1 or AL2 environments, plan migration to AL2023 โ platform behavior, hook paths, and Nginx configuration differ between versions.
Web Server = internet-facing (ELB + ASG) ยท Worker = queue-driven (SQS + ASG, no ELB)
Beanstalk organizes resources into Application โ Versions โ Environments.
- Application โ top-level container. Version โ immutable code snapshot in S3. Environment โ running resources.
- Web Server Env = ELB + EC2 + ASG (HTTP traffic). Worker Env = SQS + EC2 + ASG (background tasks).
- Platforms are managed AMIs โ Java, Node.js, Python, Ruby, PHP, Go, .NET, Docker, or Custom.
- Decoupled pattern: Web tier โ SQS โ Worker tier. Each scales independently.
- Configuration templates allow reuse โ same settings across dev/staging/prod.
Deployment Models
When you push a new version of your application, how should Beanstalk update the running instances? Replace all at once? Replace them gradually? Spin up brand new ones? The choice affects downtime, risk, speed, and cost.
Beanstalk provides five deployment policies. Each makes a different tradeoff โ there is no "best" option, only the right one for your situation.
All at Once
Deploy the new version to all instances simultaneously. Every instance goes down, receives the update, and comes back up.
- Downtime: Yes โ all instances updating at the same time
- Deploy speed: Fastest
- Rollback: Re-deploy previous version (slow)
- Cost: No additional instances
- Best for: Dev/test environments where downtime is acceptable
Rolling
Update instances in batches. First batch goes down, gets updated, comes back healthy. Then the next batch. Capacity is temporarily reduced.
- Downtime: No (but reduced capacity during update)
- Deploy speed: Moderate โ depends on batch size
- Rollback: Re-deploy previous version (slow)
- Cost: No additional instances
- Best for: Cost-sensitive production where brief reduced capacity is fine
Rolling with Additional Batch
Like Rolling, but first launches new instances with the new version before taking any old ones out. Full capacity maintained throughout.
- Downtime: No (full capacity maintained)
- Deploy speed: Moderate (slower than Rolling โ must launch extra instances)
- Rollback: Re-deploy previous version (slow)
- Cost: Temporary extra instances during deploy
- Best for: Production where you can't afford reduced capacity
Immutable
Launch an entirely new set of instances in a new ASG with the new version. Once healthy, swap them in and terminate the old ones. Old instances are never modified.
- Downtime: No (full capacity + new instances running before swap)
- Deploy speed: Slow (full new ASG must launch)
- Rollback: Fast โ just terminate the new ASG
- Cost: Doubles capacity during deploy
- Best for: Production where fast rollback is critical
Blue/Green Deployment
Create a completely separate environment (Green) with the new version. Test it independently. When ready, swap the environment URLs (DNS CNAME swap). Traffic instantly shifts from Blue to Green.
- Downtime: Near-zero (DNS swap takes seconds)
- Deploy speed: Slowest (full new environment)
- Rollback: Instant โ swap URLs back
- Cost: Full duplicate environment during deploy
- Best for: Critical production with zero-downtime requirements and instant rollback
๐ Important distinction: Blue/Green is not a Beanstalk deployment policy โ it's a strategy you implement using Beanstalk's "Swap Environment URLs" feature. Beanstalk's built-in policies are: All at Once, Rolling, Rolling with Batch, and Immutable. Blue/Green is done manually or via automation by creating a second environment.
โ ๏ธ Cost warning: Blue/Green uses two complete environments. You pay for both during the transition period. For cost-sensitive workloads, Immutable deployment provides similar safety (fast rollback, no downtime) with only temporary extra capacity instead of a full duplicate environment.
| Strategy | Downtime | Deploy Speed | Rollback | Cost | Capacity During Deploy |
|---|---|---|---|---|---|
| All at Once | โ ๏ธ Yes | โก Fastest | ๐ข Slow (re-deploy) | ๐ฐ None | โ Zero (all updating) |
| Rolling | โ No | โฑ๏ธ Moderate | ๐ข Slow (re-deploy) | ๐ฐ None | โ ๏ธ Reduced |
| Rolling + Batch | โ No | โฑ๏ธ Moderate | ๐ข Slow (re-deploy) | ๐ฐ๐ฐ Temp extra | โ Full |
| Immutable | โ No | ๐ข Slow | โก Fast (kill new ASG) | ๐ฐ๐ฐ๐ฐ Doubles | โ Full + extra |
| Blue/Green | โ Near-zero | ๐ข Slowest | โก Instant (URL swap) | ๐ฐ๐ฐ๐ฐ๐ฐ Full dup | โ Full + duplicate |
Serving traffic
Health checks pass โ take over
Old ASG serves traffic while new ASG launches ยท Once v2 healthy โ ELB switches ยท Old ASG terminates
Five deployment strategies โ choose based on downtime tolerance, rollback speed, and budget.
- All at Once โ fastest, but causes downtime. Use for dev/test only.
- Rolling โ no downtime but reduced capacity. Cost-efficient for non-critical prod.
- Rolling + Batch โ no downtime, full capacity. Slightly more expensive.
- Immutable โ no downtime, fast rollback (kill new ASG). Doubles cost during deploy.
- Blue/Green โ near-zero downtime, instant rollback (swap URLs). Full duplicate cost. Best for critical production.
- Exam tip: know all five, know which has downtime (All at Once only), know which supports instant rollback (Immutable + Blue/Green).
Architecture & Components
Elastic Beanstalk is not a separate compute engine. It is an orchestration layer that creates, configures, and manages real AWS services on your behalf. When you create a Beanstalk environment, it generates a CloudFormation stack that provisions the following resources:
EC2 Instances
The actual compute. Each instance runs the platform runtime (e.g., Node.js, Java) and your application code. Beanstalk selects the AMI, installs the runtime, deploys your code, and configures the web server (Nginx/Apache).
Elastic Load Balancer
Distributes incoming traffic across EC2 instances. Beanstalk supports ALB (HTTP/HTTPS, path-based routing), NLB (TCP, ultra-low latency), or CLB (legacy). For single-instance environments, no ELB is created.
Auto Scaling Group
Manages the fleet of EC2 instances. Defines min, max, desired count. Launches new instances when demand rises, terminates when demand falls. Replaces unhealthy instances automatically.
CloudWatch
Monitoring & alarms. Beanstalk creates CloudWatch alarms for CPU, latency, and health. Logs from instances stream to CloudWatch Logs. Enhanced health reporting provides real-time status.
Security Groups
Firewall rules for your instances and load balancer. Beanstalk creates SGs that allow ELB โ EC2 traffic on app ports and optionally SSH access. You can customize by adding rules.
S3 Bucket
Stores your application versions (ZIP/WAR files), logs, and configuration. Each Beanstalk application has its own S3 bucket. Versions are immutable snapshots.
Beyond the core resources, Beanstalk can optionally create or integrate with additional services:
Amazon RDS
- Beanstalk can create an RDS instance inside the environment
- Connection details auto-injected as env vars:
RDS_HOSTNAME,RDS_PORT,RDS_DB_NAME,RDS_USERNAME,RDS_PASSWORD - โ ๏ธ Warning: If you delete the environment, the RDS instance is deleted too!
- โ Best practice: Create RDS outside Beanstalk and pass the connection string as an environment variable. This decouples the database from the deployment lifecycle.
SNS & SQS
- SNS: Beanstalk creates an SNS topic for environment notifications (deployment events, health changes). You can subscribe your email or Lambda functions.
- SQS: Worker environments automatically get an SQS queue. The daemon polls messages and POSTs them to your app at
http://localhost/. - Dead letter queue support for failed messages
๐ Exam tip: If an exam question mentions "database deleted when environment terminated" โ the RDS was created inside Beanstalk. The solution is always: create RDS outside the environment and reference it via environment variables.
๐จ Critical Warning: RDS created inside Beanstalk is deleted when the environment terminates. For production, always create RDS outside Beanstalk and pass connection details via environment variables. This is a common exam question โ and a real-world disaster waiting to happen. There is no recovery if you accidentally terminate an environment with an embedded RDS and no snapshots.
Every Beanstalk environment is backed by a CloudFormation stack. When you create or update an environment, Beanstalk:
Generates a CFN Template
- Defines EC2 instances, ASG, ELB, SGs, IAM roles
- Based on your environment type + configuration
- Template is deterministic โ same config = same resources
Executes the Stack
- CloudFormation provisions all resources in order
- Updates use stack update โ rolling change sets
- Failures trigger automatic rollback
- You can view the stack in the CloudFormation console
This means: everything Beanstalk does, you could do manually with CloudFormation. Beanstalk is a convenience layer that generates and manages CloudFormation stacks. Understanding this helps demystify what happens when something goes wrong โ you can always inspect the CloudFormation events for detailed error logs.
| Type | When to Use | Features | Beanstalk Config |
|---|---|---|---|
| ALB (Application) | HTTP/HTTPS web apps (default) | Path-based routing, HTTP/2, WebSocket, sticky sessions | LoadBalancerType: application |
| NLB (Network) | TCP/UDP, ultra-low latency, static IP | Millions of requests/sec, TLS termination, preserve source IP | LoadBalancerType: network |
| CLB (Classic) | Legacy only โ avoid for new projects | Basic HTTP/TCP, limited routing | LoadBalancerType: classic |
| None (Single Instance) | Dev/test, low-cost environments | No ELB, public IP on the EC2 instance directly | Environment type: single instance |
๐ Important: You cannot change the load balancer type after environment creation. If you need to switch from CLB to ALB, you must create a new environment. Plan your LB type before creating the environment.
Single Instance
- 1 EC2 instance โ no ELB, no ASG
- Public Elastic IP assigned directly
- Cheapest option (no ELB cost)
- No high availability โ if instance fails, environment is down
- Use for: Dev, test, small personal projects
Load Balanced
- Multiple EC2 instances behind an ELB in an ASG
- Traffic distributed across instances and AZs
- Auto Scaling adds/removes instances
- High availability โ survives instance failures
- Use for: Staging, production, anything requiring uptime
Solid = created by Beanstalk ยท Dashed = optional / external integration
Beanstalk orchestrates real AWS services โ it's not a black box.
- Core resources: EC2 + ASG + ELB + CloudWatch + Security Groups + S3 โ created automatically via CloudFormation
- Optional: RDS (โ ๏ธ create outside env for persistence), SQS (worker envs), SNS (notifications), ElastiCache
- Load Balancer types: ALB (HTTP, default), NLB (TCP, low latency), CLB (legacy), or None (single instance)
- Cannot change LB type after creation โ plan ahead
- Single Instance = cheapest, no HA. Load Balanced = production-grade, multi-AZ
- Everything is a CloudFormation stack โ inspect it for debugging
Scaling & High Availability
Every load-balanced Beanstalk environment includes an Auto Scaling Group (ASG). The ASG manages the fleet of EC2 instances and automatically adjusts the count based on demand. You configure three key parameters:
Minimum Instances
The floor. ASG will never scale below this number. Set to at least 2 for production (one per AZ for high availability).
Desired Instances
The target count ASG tries to maintain. Auto Scaling adjusts this value automatically based on scaling policies. Usually starts at minimum.
Maximum Instances
The ceiling. ASG will never scale above this number. Protects against runaway scaling and unexpected costs. Set based on budget.
Beanstalk uses CloudWatch metrics to decide when to scale. You can configure scaling policies based on several triggers:
| Metric | Scales Out When | Scales In When | Best For |
|---|---|---|---|
| CPUUtilization | CPU > 70% (avg 5 min) | CPU < 30% | CPU-bound workloads (image processing, computation) |
| NetworkOut | Network > threshold | Network < threshold | Data-heavy APIs, file transfers |
| Latency | Response time > threshold | Response < threshold | Web apps where user experience matters |
| RequestCount | Requests/instance > threshold | Requests < threshold | Request-driven APIs, even load distribution |
| HealthyHostCount | Healthy hosts < desired | โ | Maintaining minimum healthy capacity |
| SQS Queue Depth | Messages > threshold | Queue empty | Worker environments processing async jobs |
๐ Default scaling metric: NetworkOut. For most web apps, CPUUtilization or RequestCount are better choices. Always tune the scaling metric for your specific workload โ don't rely on defaults.
โ ๏ธ What NOT to scale on: Avoid scaling on NetworkIn โ it measures incoming data volume, not application load. A single large file upload can trigger unnecessary scale-out. Also avoid DiskReadOps unless your workload is explicitly disk-bound. Stick with CPU, RequestCount, or Latency for most web applications.
Target Tracking (Recommended)
- Set a target value (e.g., "keep CPU at 50%")
- ASG automatically adjusts to maintain the target
- Simplest to configure โ AWS handles the math
- Similar to a thermostat: set the temp, system adjusts
Step Scaling
- Define specific thresholds and how many instances to add/remove
- E.g., "CPU > 60%: +1", "CPU > 80%: +3"
- More control than target tracking
- Useful when you need different scale amounts at different thresholds
Scheduled Scaling
- Scale at specific times (cron-based)
- E.g., "scale to 10 instances at 9 AM, scale to 2 at 10 PM"
- Best for predictable traffic patterns (business hours, marketing events)
- Can combine with target tracking for hybrid approach
Cooldown Period
- After a scaling action, ASG waits before scaling again
- Default: 300 seconds (5 minutes)
- Prevents "thrashing" โ rapidly adding/removing instances
- Tune shorter for fast-changing workloads, longer for gradual changes
Beanstalk uses health checks to determine if instances are working correctly. There are two levels:
Basic Health
- Checks ELB health check endpoint (default:
HTTP 200on/) - Binary: Healthy or Unhealthy
- EC2 instance status checks
- Limited information โ only tells you "up or down"
- Free โ included by default
Enhanced Health (Recommended)
- Beanstalk agent on each instance reports detailed metrics
- Color-coded: Green (Ok), Yellow (Warning), Red (Degraded), Grey (Unknown)
- Monitors: CPU, requests, latency, 2xx/3xx/4xx/5xx counts
- Application-level health โ not just "port open"
- Health history and dashboard in Beanstalk console
- Requires Beanstalk enhanced health reporting IAM role
| Health Color | Meaning | Action |
|---|---|---|
| ๐ข Green | All instances healthy, passing health checks | No action needed |
| ๐ก Yellow | Some requests failing or latency high | Investigate โ may self-resolve |
| ๐ด Red | Multiple instances unhealthy, service degraded | Immediate investigation. Check app logs |
| โช Grey | Updating, initializing, or insufficient data | Wait โ usually resolves after deployment |
Enhanced Health requires the service role aws-elasticbeanstalk-service-role with the AWSElasticBeanstalkEnhancedHealth managed policy attached. Beanstalk creates this automatically when you launch an environment with enhanced health enabled via the console or EB CLI.
To achieve true high availability with Beanstalk, your environment should survive the failure of an entire Availability Zone:
HA Best Practices
- Use Load Balanced environment (not single instance)
- Set minimum 2 instances across 2+ AZs
- Use ALB โ it routes to healthy instances across AZs
- Enable cross-zone load balancing (default with ALB)
- Use external RDS with Multi-AZ deployment
- Enable Enhanced Health for faster failure detection
- Store sessions in ElastiCache (not in-memory on EC2)
- Set appropriate health check grace period (give instances time to boot)
Common HA Mistakes
- Single instance environment in production
- All instances in one AZ
- RDS inside Beanstalk (deleted with env)
- Sticky sessions without external session store
- No health check path configured (using default
/) - Max instances = min instances (no room to scale)
- Cooldown too long โ can't react to sudden traffic
Scaling Flow
CloudWatch monitors โ Alarm triggers scaling policy โ ASG launches/terminates EC2 โ ELB registers/deregisters targets
Beanstalk Auto Scaling keeps your app responsive under any load.
- ASG parameters: min (floor), desired (target), max (ceiling) โ always set min โฅ 2 for HA
- Scaling triggers: CPUUtilization, RequestCount, Latency, NetworkOut, SQS queue depth
- Policy types: Target Tracking (simplest), Step Scaling (granular), Scheduled (predictable patterns)
- Health checks: Basic (up/down) vs Enhanced (color-coded, detailed metrics โ recommended)
- HA best practices: Multi-AZ, external RDS (Multi-AZ), ElastiCache for sessions, min 2 instances
- Exam tip: Know scaling policies, health check types, and why external RDS is critical for HA
Configuration & Customization
Beanstalk applies configuration from multiple sources. When settings conflict, higher-priority sources override lower ones. Understanding this order prevents "why isn't my setting applied?" confusion:
Priority Order (Highest โ Lowest)
- Direct environment settings โ Console, CLI, API changes
- Saved configurations โ Reusable config templates
- .ebextensions โ Config files inside your source bundle
- Platform defaults โ What the platform provides out of the box
If you set an instance type in the console AND in .ebextensions, the console value wins.
Why This Matters
- Use .ebextensions for version-controlled defaults (lives in your code repo)
- Use saved configurations for environment-specific overrides (prod vs dev)
- Use direct settings for quick one-off changes (hotfixes, debugging)
- Platform defaults handle things you usually don't need to change
Environment variables are the simplest and most common way to configure your application in Beanstalk. They inject runtime configuration without changing your code โ database URLs, API keys, feature flags.
How to Set Them
- Console: Configuration โ Software โ Environment properties
- CLI:
eb setenv DB_HOST=mydb.123.rds.amazonaws.com - .ebextensions: In YAML config files (version-controlled)
- EB CLI:
eb configto edit interactively
Common Env Vars
NODE_ENV=productionDATABASE_URL=postgres://...API_KEY=sk-xxxxxLOG_LEVEL=infoPORT=8080(Beanstalk sets this automatically)
๐ Security tip: For sensitive values (API keys, database passwords), use AWS Secrets Manager or SSM Parameter Store instead of environment variables. Env vars are visible in the console and in CloudFormation templates. Secrets Manager encrypts values at rest and supports automatic rotation.
The .ebextensions directory is the most powerful customization tool in Beanstalk. It contains YAML or JSON config files that execute during deployment. You place this directory in the root of your source bundle:
File Structure
my-app/ โโโ .ebextensions/ โ โโโ 01-env-vars.config โ โโโ 02-packages.config โ โโโ 03-nginx.config โ โโโ 04-custom-logs.config โโโ app.js โโโ package.json โโโ ...
Files execute in alphabetical order. Prefix with numbers to control ordering.
What You Can Configure
- option_settings โ Set any Beanstalk configuration option
- packages โ Install yum/apt packages (e.g., ImageMagick)
- sources โ Download and extract archives
- files โ Create files on the instance (configs, scripts)
- commands โ Run shell commands before app deploys
- container_commands โ Run after app code extracted but before launch
- Resources โ Create additional CloudFormation resources (RDS, DynamoDB, SQS)
Example โ 01-env-vars.config:
option_settings:
aws:elasticbeanstalk:application:environment:
NODE_ENV: production
LOG_LEVEL: info
aws:autoscaling:asg:
MinSize: 2
MaxSize: 6
aws:autoscaling:launchconfiguration:
InstanceType: t3.medium
aws:elasticbeanstalk:environment:
LoadBalancerType: application Example โ 02-packages.config:
packages:
yum:
ImageMagick: []
git: []
commands:
01_setup_timezone:
command: "ln -sf /usr/share/zoneinfo/UTC /etc/localtime"
container_commands:
01_run_migrations:
command: "npm run migrate"
leader_only: true # Only runs on ONE instance
02_seed_data:
command: "npm run seed"
leader_only: true # Only runs on ONE instance
03_clear_cache:
command: "npm run cache:clear"
leader_only: false # Runs on EVERY instance ๐ leader_only: true ensures a container_command runs on only one instance โ essential for database migrations. Without it, every instance would run the migration simultaneously, causing conflicts.
Platform hooks are the newer, recommended way to run scripts during the deployment lifecycle. They replace the older commands and container_commands in .ebextensions with a clearer, lifecycle-based structure:
Hook Directories
.platform/
โโโ hooks/
โ โโโ prebuild/ โ Before build
โ โโโ predeploy/ โ Before app starts
โ โโโ postdeploy/ โ After app starts
โโโ confighooks/
โ โโโ prebuild/
โ โโโ predeploy/
โ โโโ postdeploy/
โโโ nginx/
โโโ conf.d/
โโโ custom.conf Lifecycle Stages
- prebuild/ โ Before source code is built. Install dependencies, set up tools.
- predeploy/ โ After build, before app launches. Run DB migrations, compile assets.
- postdeploy/ โ After app is running and healthy. Send notifications, warm caches.
- confighooks/ โ Same stages, but triggered on config changes (not deploys)
- Scripts must be executable (
chmod +x) and use a shebang (#!/bin/bash)
| Feature | .ebextensions | Platform Hooks |
|---|---|---|
| Introduced | Original (legacy) | Amazon Linux 2+ (modern) |
| Execution order | Alphabetical file order | Alphabetical within lifecycle stage |
| Lifecycle clarity | commands vs container_commands (confusing) | Clear: prebuild / predeploy / postdeploy |
| Config changes | No separate stage | confighooks/ for config-only changes |
| CloudFormation resources | โ Supported (Resources key) | โ Not supported โ still use .ebextensions |
| Recommendation | Use for option_settings + Resources only | Use for all scripts and commands |
If your .ebextensions or platform hooks install many packages or take a long time, you can bake a custom AMI โ an image with everything pre-installed. This dramatically reduces deployment time because instances boot with all dependencies already present.
When to Use Custom AMIs
- Large package installations (ML libraries, native compilers)
- Deployment time is too slow (> 10 minutes per instance)
- Need custom OS configuration (kernel tuning, security hardening)
- Compliance requirements (pre-approved base images)
Considerations
- Start from the Beanstalk platform AMI โ don't build from scratch
- You must maintain and update the AMI yourself (OS patches, runtime updates)
- Set via:
aws:autoscaling:launchconfigurationโImageId - Use Packer (by HashiCorp) to automate AMI building
- Combine with .ebextensions for app-specific config on top of the pre-baked image
Beanstalk platforms (Amazon Linux 2+) use Nginx as the reverse proxy in front of your application. You can customize Nginx by placing config files in your source bundle:
Custom Nginx Config
# .platform/nginx/conf.d/proxy.conf client_max_body_size 50M; proxy_read_timeout 300s; # Custom headers add_header X-Frame-Options "DENY"; add_header X-Content-Type "nosniff";
Full Nginx Override
# .platform/nginx/nginx.conf # Complete replacement โ use with care # Must include all required directives # Useful for: # - Custom routing # - WebSocket support # - Gzip configuration # - Static file serving
Environment Variables
DB_HOST, API_KEY, NODE_ENV
Secrets Manager
Encrypted secrets at runtime
.platform/hooks/
Lifecycle scripts
.platform/nginx/
Proxy customization
Custom AMI
Pre-baked dependencies
.ebextensions/
Instance type, ASG, ELB
Resources (CFN)
Extra RDS, SQS, DynamoDB
Saved Configs
Reusable templates
Application config โ your code reads env vars ยท Platform config โ hooks + nginx ยท Infrastructure config โ .ebextensions + CFN
Beanstalk offers multiple configuration layers โ use the right tool for the right job.
- Priority order: Direct settings > Saved configs > .ebextensions > Platform defaults
- Environment variables โ simplest config. Use Secrets Manager for sensitive values.
- .ebextensions โ powerful YAML configs for option_settings, packages, commands, and CloudFormation Resources
- Platform hooks (.platform/hooks/) โ modern lifecycle scripts: prebuild โ predeploy โ postdeploy
- Custom AMI โ pre-bake dependencies for faster deploys. Maintain and update yourself.
- Nginx โ customize via .platform/nginx/conf.d/ or full override. Don't forget
client_max_body_size! - leader_only: true โ run a command on only one instance (critical for DB migrations)
Architecture Patterns
The most common Beanstalk pattern: a single-tier web application with all components managed by one Beanstalk environment. Suitable for most small to medium applications.
Architecture
- Web Server Environment โ ALB + ASG + EC2
- Single codebase handles all requests
- External RDS for persistence
- ElastiCache for sessions (optional)
- CloudFront for static assets (optional)
When to Use
- Standard web apps, REST APIs, admin dashboards
- Small to medium traffic (up to thousands req/sec)
- Single team, single deployment unit
- Quick time-to-market โ simplest architecture
- Monolithic applications (not microservices)
For applications with both user-facing traffic and heavy background processing. Separate the two concerns into two Beanstalk environments connected by SQS.
Web Tier
- Web Server Environment
- Handles HTTP requests
- Sends heavy tasks to SQS
- Responds immediately to user
Message Queue
- SQS Standard or FIFO
- Decouples web from worker
- Buffers work during spikes
- Dead letter queue for failures
Worker Tier
- Worker Environment
- Polls SQS, processes tasks
- Scales on queue depth
- No internet traffic
๐ Real-world examples: E-commerce site (web = product browsing, worker = order processing + email). Photo app (web = upload UI, worker = image resizing + thumbnail generation). SaaS (web = dashboard, worker = report generation + data exports).
For teams that need zero-downtime deployments with instant rollback capability. Combine Beanstalk's URL swap with a CI/CD pipeline for fully automated releases.
Pipeline Flow
- Developer pushes code to CodeCommit / GitHub
- CodePipeline detects change, triggers build
- CodeBuild runs tests, creates artifact
- Deploy to Green environment (new)
- Run smoke tests on Green
- Swap URLs โ Green becomes production
- Old Blue available for instant rollback
Benefits
- Zero downtime โ users never see an outage
- Instant rollback โ swap URLs back in seconds
- Testing in production infra โ Green has same config as Blue
- Canary-like โ test with Route 53 weighted routing before full swap
- Full automation via CodePipeline
When your application runs in Docker containers but you don't need the complexity of ECS or EKS, Beanstalk's Docker platform is the simplest path. Just provide a Dockerfile or docker-compose.yml.
Single-Container Docker
- One Docker container per EC2 instance
- Provide a
DockerfileorDockerrun.aws.json - Beanstalk builds and runs the container
- Simplest Docker deployment on AWS
- Standard ALB + ASG + Auto Scaling
Multi-Container Docker
- Multiple containers per EC2 (via ECS under the hood)
- Define with
Dockerrun.aws.jsonv2 - Sidecar pattern โ app + logging + monitoring containers
- More complex โ consider ECS for production multi-container
- โ ๏ธ Retired on Amazon Linux 2 โ use ECS instead
๐ Docker vs Native Platform: Use Docker when you need a specific runtime version not offered by Beanstalk, or when your team already uses Docker for local development. For standard Node.js/Java/Python apps, the native platform is simpler and faster to deploy.
โ ๏ธ Multi-container Docker migration: The multi-container Docker platform (Dockerrun.aws.json v2) is not available on Amazon Linux 2023. For existing multi-container environments on Amazon Linux 2, migrate to ECS on EC2 or ECS on Fargate before the AL2 platform reaches end of life. For single-container workloads, the AL2023 Docker platform is the recommended path forward.
git push โ CodePipeline โ Build โ Deploy to Green โ Smoke test โ Swap URLs โ Green is prod ยท Blue = rollback target
Choose the right Beanstalk pattern based on your workload complexity.
- Pattern 1 โ Simple Web App: Single env, ALB + ASG + external RDS. Best for monoliths and standard web apps.
- Pattern 2 โ Web + Worker: Two envs connected by SQS. Decouple request handling from heavy processing.
- Pattern 3 โ Blue/Green CI/CD: Automated pipeline with dual environments. Zero-downtime deployments + instant rollback.
- Pattern 4 โ Docker: Run containers on Beanstalk with a Dockerfile. Simplest Docker deployment on AWS.
- When Beanstalk isn't enough: Use ECS/EKS for microservices, Lambda for event-driven, raw EC2 for full control.
- Production checklist: External RDS (Multi-AZ) ยท ElastiCache (sessions) ยท CloudFront (CDN) ยท Enhanced Health ยท Blue/Green deploys
Beanstalk Cheatsheet
| Command | What It Does | When to Use |
|---|---|---|
eb init | Initialize EB application in current directory | First-time project setup |
eb create | Create a new environment | New environment (dev, staging, prod) |
eb deploy | Deploy current code to environment | Push a new version |
eb open | Open environment URL in browser | Quick access to running app |
eb health | Show real-time health status | Monitor instance health |
eb logs | Fetch and display logs | Debugging issues |
eb setenv KEY=value | Set environment variable | Runtime configuration |
eb config | View/edit environment configuration | Change scaling, instance type, etc. |
eb swap env1 --destination_name env2 | Swap CNAMEs between environments | Blue/Green deployment |
eb status | Show environment info (URL, health, platform) | Check environment state |
eb terminate | Delete environment and all resources | Tear down env (โ ๏ธ destructive) |
eb abort | Cancel in-progress environment update | Rolling back a bad deploy |
eb clone | Clone an existing environment | Create staging from prod config |
eb scale N | Set number of running instances | Manual scaling |
| Namespace | Setting | Example Value | Purpose |
|---|---|---|---|
aws:autoscaling:asg | MinSize | 2 | Minimum instances |
aws:autoscaling:asg | MaxSize | 6 | Maximum instances |
aws:autoscaling:launchconfiguration | InstanceType | t3.medium | EC2 instance size |
aws:autoscaling:launchconfiguration | IamInstanceProfile | aws-elasticbeanstalk-ec2-role | Instance IAM role |
aws:elasticbeanstalk:environment | LoadBalancerType | application | ALB / NLB / classic |
aws:elasticbeanstalk:environment | ServiceRole | aws-elasticbeanstalk-service-role | Beanstalk service role |
aws:elasticbeanstalk:application:environment | NODE_ENV | production | App env variable |
aws:elasticbeanstalk:healthreporting:system | SystemType | enhanced | Enable enhanced health |
aws:elasticbeanstalk:command | DeploymentPolicy | Rolling | Deployment strategy |
aws:elasticbeanstalk:command | BatchSizeType | Percentage | Batch size unit |
aws:elasticbeanstalk:command | BatchSize | 25 | % of instances per batch |
aws:autoscaling:trigger | MeasureName | CPUUtilization | Scaling metric |
aws:autoscaling:trigger | UpperThreshold | 70 | Scale out threshold |
aws:autoscaling:trigger | LowerThreshold | 30 | Scale in threshold |
Green
Healthy. All instances passing. No action needed.
Yellow
Warning. Some failures or high latency. Investigate.
Red
Degraded. Multiple unhealthy instances. Immediate action.
Grey
Unknown. Updating or insufficient data. Wait.
| Strategy | Downtime? | Rollback Speed | Extra Cost? | Use For |
|---|---|---|---|---|
| All at Once | โ ๏ธ Yes | ๐ข Slow | None | Dev / test only |
| Rolling | โ No | ๐ข Slow | None | Cost-sensitive prod |
| Rolling + Batch | โ No | ๐ข Slow | Temp extra | Prod, full capacity |
| Immutable | โ No | โก Fast | 2x during deploy | Prod, safe rollback |
| Blue/Green | โ No | โก Instant | Full duplicate | Critical prod, zero risk |
my-app/
โโโ .ebextensions/ โ Infrastructure config (YAML)
โ โโโ 01-env-vars.config โ Environment variables + scaling
โ โโโ 02-packages.config โ yum packages + commands
โ โโโ 03-resources.config โ Extra CloudFormation resources
โโโ .platform/ โ Platform customization (AL2023)
โ โโโ hooks/
โ โ โโโ prebuild/ โ Before build (install deps)
โ โ โโโ predeploy/ โ Before app starts (migrations)
โ โ โโโ postdeploy/ โ After app running (warmup)
โ โโโ confighooks/ โ Same stages, config changes only
โ โโโ nginx/
โ โโโ conf.d/
โ โโโ proxy.conf โ Custom Nginx settings
โโโ app.js โ Your application code
โโโ package.json โ Dependencies
โโโ Procfile โ (Optional) custom start command
web: node app.js --port $PORT Frequently Tested
- RDS inside Beanstalk = deleted on env terminate. Always create externally.
- Blue/Green = URL swap, not built-in deployment policy
- Immutable = new ASG, fast rollback. All at Once = only one with downtime.
- Cannot change LB type after creation
- Worker environments use SQS, no load balancer
- .ebextensions for config, platform hooks for scripts
- leader_only: true for DB migrations
- Beanstalk is free โ you pay for underlying resources only
Common Traps
- "Beanstalk doesn't support Docker" โ โ It does (Dockerfile or Dockerrun.aws.json)
- "Beanstalk is serverless" โ โ EC2 instances run 24/7
- "You can't SSH into Beanstalk instances" โ โ You can
- "Blue/Green is a deployment policy" โ โ It's a URL swap strategy
- "Enhanced health is enabled by default" โ โ Must be explicitly enabled
- "Rolling deployment has downtime" โ โ Only All at Once has downtime
- "Beanstalk manages its own separate compute" โ โ Uses EC2 under the hood
Beanstalk = PaaS convenience + IaaS transparency. Valet parking for your code.
- Upload code โ Beanstalk creates EC2, ASG, ELB, CloudWatch, S3, SNS via CloudFormation
- 5 deploy strategies โ All at Once (dev), Rolling (cheap), Rolling+Batch (safe), Immutable (safer), Blue/Green (safest)
- 2 env types โ Web Server (HTTP) and Worker (SQS)
- Configure via โ env vars, .ebextensions, platform hooks, saved configs, custom AMI
- Scale via โ Target tracking, step scaling, or scheduled. Enhanced health for real-time monitoring.
- Production must-haves โ External RDS, Multi-AZ, ElastiCache, Enhanced Health, Immutable or Blue/Green deploys