9.4
Elastic Beanstalk
Applications, versions and environments, web vs worker tiers, and single-instance vs HA deployments.
18 min Reading + animations
Tip: tap or hover any dotted-underlined term to see what it means.
By the end of this lesson you will be able to
- Explain the problem Elastic Beanstalk solves for developers, and place it between EC2 by hand and Lambda on the managed-versus-control spectrum.
- Describe applications, application versions and environments, environment names, URLs and tiers, and the platforms Beanstalk runs today.
- List what one environment creates in your account through CloudFormation, what you pay for, and how to customise it safely with configuration options,
.ebextensionsand platform hooks. - Choose between a single-instance and a load-balanced environment, and explain why a production database should not live inside the environment.
- Explain how the worker tier uses SQS: the daemon, visibility timeout, retries, the dead-letter queue and
cron.yaml. - Compare the five deployment policies and blue/green by downtime, capacity, time and rollback, calculate batches and peak instance counts, and predict what each one does when the new version is broken.
#The developer’s problem
#Every web app needs the same plumbing
The last three lessons built the same kind of system again and again. For the “what time is it?” site (lesson 9.1) and the clothing shop (lesson 9.2) you put a load balancer in front of an Auto Scaling group across several AZs, added health checks, security groups chained from tier to tier, and a database. For the WordPress blog (lesson 9.3) you added shared storage and learned to launch instances fast.
That design is right for most web applications, and that is exactly the problem. A developer who only wants their code to run has to:
- build and manage the infrastructure: VPC choices, security groups, load balancer, launch template, Auto Scaling group;
- find a way to deploy new code to every instance without breaking the site;
- configure the database, the load balancer listeners, the health checks and the alarms;
- think about scaling: which metric, which limits, which AZs;
- and do it consistently for every application and every environment (dev, test, prod), so that “it worked in test” means something.
Each team would rebuild the same ALB + ASG pattern by hand, slightly differently each time. AWS Elastic Beanstalk is AWS’s answer: a developer-centric way to deploy an application, in which you hand over the code and Beanstalk builds and runs that standard architecture for you.
#Where Beanstalk sits between EC2 and Lambda
Beanstalk is a PaaS (Platform as a Service, lesson 1.1): you manage the application code and its settings; AWS manages the platform under it. It helps to see it on a line from “I do everything” to “I do almost nothing”.
| EC2 by hand (lessons 4–6) | Elastic Beanstalk | Lambda (serverless) | |
|---|---|---|---|
| You provide | AMI, launch template, ALB, ASG, scaling, deployment scripts | Code (a zip, a WAR, or a Docker image definition) and settings | One function per event |
| Servers | Your EC2 instances | Your EC2 instances, created and managed for you | None you can see |
| OS access | Full | Full (you can log in to the instances) | None |
| Scaling | You configure the ASG | Beanstalk configures the ASG; you set the limits | Automatic, per request |
| Deployment | Your own tooling | Built-in policies (all at once, rolling, immutable…) | Upload a new version |
| Billing | Instance hours + everything else | The same resources at the same prices; Beanstalk adds nothing | Per request and duration |
| Best for | Unusual architectures, total control | Standard web apps and workers, fast | Event-driven, spiky, short tasks |
The notes give three reasons to choose Beanstalk:
- Fast deployment: code goes straight to a production-shaped environment in minutes.
- Full control: unlike serverless, Beanstalk does not lock you out. The EC2 instances and the load balancer it creates are visible in your account, and you can log in to the instances and change them. (The next section explains the catch.)
- Free service: there is no charge for Beanstalk itself; you pay only for the resources it creates.
#What it costs
Elastic Beanstalk itself is free. The bill is the sum of what it creates: EC2 instances (On-Demand by default, Spot or a Savings Plan if you configure them, lesson 4.4), the load balancer, EBS volumes, the S3 storage for your application versions and logs, CloudWatch alarms and, if you add one, an RDS database. Two environments cost twice as much, which matters for blue/green deployments later in this lesson.
#Applications, versions and environments
#The three building blocks
- Application: a named container for everything that belongs to one piece of software: its versions, its environments and its saved configurations. It runs nothing and costs nothing.
- Application version: one specific build of your code, a source bundle (a zip or WAR file) that Beanstalk stores in S3 with a label such as
v42. Versions belong to the application, not to an environment, so you can deploy the same version to test and later to prod. The default quota is 1,000 application versions per Region across all applications; a version lifecycle policy deletes old ones automatically. - Environment: a set of AWS resources running one application version at a time. You usually have several per application:
shop-dev,shop-test,shop-prod. Each has its own configuration, resources and URL.
Around them sit saved configurations (templates of environment settings you can reuse) and the platform the environment runs on. The workflow is always the same: create the application, upload a version, launch an environment, then manage it; to release, you upload a new version and deploy it to the environment.
From an application down to your code
Every Beanstalk environment is a stack of layers. You write only the innermost one; Beanstalk builds and looks after the rest.
Scenario
An application is only a container with a name. It costs nothing and runs nothing. It groups everything that belongs to one piece of software.
#Environment names, URLs and tiers
When you create an environment you choose:
- an environment name, unique within the application, such as
shop-prod; - a domain prefix (CNAME prefix), unique within the Region. The environment URL becomes
shop-prod.us-east-1.elasticbeanstalk.com. For a load-balanced environment it is a DNS name that points at the load balancer; for a single-instance environment, at the instance’s Elastic IP. You normally put your own name in front of it,www.example.com, with a Route 53 alias record that targets the environment (lesson 8.2) or a CNAME to the environment URL; - a tier: web server (it answers HTTP or HTTPS from users) or worker (it processes jobs from an SQS queue and has no public URL of its own). Tiers get their own section below.
#Platforms you can run
A platform is the software stack on the instances: operating system, language runtime, web server or proxy, and Beanstalk’s agents. The current list (October 2026):
- Docker (Docker running on Amazon Linux 2023) and ECS running on Amazon Linux 2023 (several containers per instance, managed by an ECS agent; it replaced “multi-container Docker”);
- Go, Java (plain Java apps on Amazon Corretto), Tomcat (Java web apps as WAR files);
- .NET Core on Linux and .NET on Windows Server (IIS);
- Node.js, PHP, Python, Ruby.
A few terms matter in practice:
- A platform branch is a major line, such as “Node.js 22 running on 64bit Amazon Linux 2023”. A platform version inside it is numbered major.minor.patch, for example 6.11.12.
- Managed platform updates apply new minor and patch versions automatically in a weekly two-hour maintenance window, using an immutable update so capacity never drops. Console-created environments have them on by default. They never cross to a new branch; when a branch retires, you migrate yourself, usually with a blue/green deployment.
- Docker is the escape hatch: if your language or stack is not on the list, put it in a container.
#What Beanstalk builds in your account
#One environment, one CloudFormation stack
Beanstalk does not have its own hidden servers. For every environment it writes an AWS CloudFormation template and creates a stack in your account (CloudFormation, AWS’s infrastructure-as-code service, has its own chapter near the end of the course). The notes put it simply: Beanstalk uses CloudFormation under the hood. A load-balanced web server environment typically contains:
- an S3 bucket named
elasticbeanstalk-<region>-<account-id>(one per Region, shared by your applications) holding your source bundles and logs; - security groups: one for the load balancer, one for the instances that allows traffic only from the load balancer (the tier-to-tier chaining of lesson 9.2);
- an Elastic Load Balancer: an Application Load Balancer by default from the console and the EB CLI (Network and Classic are options, and several environments can share one ALB);
- a launch template and an Auto Scaling group across the AZs you choose, by default minimum 1 and maximum 4 instances;
- CloudWatch alarms that drive scaling. The default trigger is network traffic out of the instances (scale out above 6 MB, in below 2 MB, over 5 minutes); most teams switch to CPU or request count;
- for a single-instance environment, an Elastic IP instead of the load balancer;
- optionally an RDS DB instance (see “Keep the database out of the environment” below).
Beanstalk also needs two IAM roles: a service role that lets Beanstalk call other services for you, and an instance profile that lets the instances read the bundle from S3, upload logs and report health. The console and EB CLI create both on first use.
What one environment builds
The developer hands over a zip. Beanstalk stores it in S3 and asks CloudFormation to build everything else in your account.
Scenario
eb create with the defaults: a load-balanced web server environment across two AZs.
The developer runs eb create shop-prod. The EB CLI zips the project folder into a source bundle and sends it to Beanstalk. Nothing exists in the Region yet.
#Changing the configuration: options, .ebextensions and platform hooks
Everything about an environment is a configuration option in a namespace, for example aws:autoscaling:asg → MinSize, or aws:elasticbeanstalk:command → DeploymentPolicy. You can set options in four places, and the first one that sets an option wins:
- directly on the environment (console, EB CLI, API);
- a saved configuration you applied;
- configuration files in your source bundle;
- the defaults.
Inside the source bundle you can customise the instances and the environment:
.ebextensions/*.config(YAML or JSON):option_settings,packagesto install,filesto write,commandsandcontainer_commandsto run, and even extraResourcesin CloudFormation syntax (an SQS queue, a DynamoDB table);.platform/hooks/(prebuild,predeploy,postdeploy) and.platform/confighooks/: scripts that run at fixed points of a deployment on Amazon Linux 2023 platforms;.platform/nginx/overrides the proxy configuration;- a
Procfilefor the command that starts your app, and environment properties (environment variables) for settings such as feature flags or a database endpoint.
#Full control, with one catch
You really do have OS-level access: eb ssh logs you in to an instance, and you can change anything. But instances are disposable. An Auto Scaling scale-in, a failed health check, an immutable deployment or a managed platform update replaces them with fresh ones built from the platform AMI and your source bundle, and every change you made by hand is gone. The same is true of the resources in the stack: if you edit the load balancer or the security groups in their own consoles, the next environment update can put them back.
So “full control” means: any change you want, as long as it lives in your source bundle or your environment configuration. That rule is the same lesson 4.3 taught about AMIs and user data: anything not in the recipe does not survive a relaunch.
#Single-instance or load-balanced
The slides call these the two deployment modes; in the console and the API they are environment types.
Single instance: great for devLoad-balanced (high availability): great for prod
- One EC2 instance, in an Auto Scaling group with minimum and maximum both 1
- An Elastic IP on the instance; the environment URL points to it
- No load balancer, so it is cheap
- No redundancy: if the instance or its AZ fails, the site is down until the ASG replaces it
- Deployment policies: all at once and immutable only
eb create --single
- An ALB (by default) in front of an Auto Scaling group across two or more AZs
- Health checks, automatic replacement and scaling on CloudWatch alarms
- Set the minimum to 2 or more for real high availability: the default minimum of 1 is still a single point of failure
- All five deployment policies, and blue/green
eb create(the default type)
A common pattern is one cheap single-instance environment per developer or per feature branch, and a load-balanced environment for staging and production, all running the same application versions.
#Keep the database out of the environment
The slide for the HA mode shows an RDS primary and standby inside the environment, and Beanstalk can indeed create an RDS database as part of the environment (MySQL, PostgreSQL, Oracle or SQL Server). It then passes the connection details to your code as environment properties: RDS_HOSTNAME, RDS_PORT, RDS_DB_NAME, RDS_USERNAME, RDS_PASSWORD. That is called a coupled database, and it is handy for a first test.
For production it is a trap, because a coupled database shares the environment’s lifecycle:
- When the environment is terminated, the stack deletes what it created. The database follows its deletion policy:
Delete(the default),Snapshot(take a final snapshot, then delete) orRetain(keep it running). - Blue/green needs two environments that both talk to the same production database. A database that belongs to one of them cannot be shared that way.
- Other environments, other applications or a reporting tool cannot use it cleanly, and settings changed in the RDS console are overwritten by the environment’s own.
The fix is to decouple it: create the RDS database (Multi-AZ, lesson 7.1) outside Beanstalk, or decouple an existing one with the Retain policy, then give the environment the endpoint through environment properties or AWS Secrets Manager, and allow the instances’ security group in the database’s security group. Apply the deletion policy change first, as its own update, and decouple in a second one: if you submit both together, the old policy wins.
#Web server tier and worker tier
#The web server environment
A web server environment is what you have seen so far: it has a URL, receives HTTP and HTTPS requests from the internet through its load balancer, and runs them on the instances in its Auto Scaling group. Its job is to answer users quickly.
Some work does not fit inside a request: converting a video, building a large report, resizing photos, sending a batch of emails, calling a slow partner API. Done inside the web request, each one makes the user wait, ties up a web server, and under load can starve the requests that should be fast.
#The worker environment and its SQS daemon
A worker environment runs those jobs in the background. It has no public URL. The pieces are:
- The web tier puts a message on an Amazon SQS queue with the AWS SDK, for example
{"video": 42}, and immediately answers the user (often with HTTP 202 Accepted). SQS, AWS’s managed message queue, gets a full chapter later (chapter 13); here you need only the basics. - Beanstalk creates the queue for you (an autogenerated standard queue) or uses an existing one, standard or FIFO.
- On every worker instance, Beanstalk runs the SQS daemon (
sqsd). It pulls messages from the queue and, for each one, sends an HTTP POST tohttp://localhost/on port 80 (the path is configurable), with the message body as the request body and SQS details inX-Aws-Sqsd-*headers. - Your worker code is therefore just a web handler. If it returns 200 OK, the daemon deletes the message. Any other status, or no answer, means failure, and the message comes back for another try.
This is decoupling: the web tier can absorb a burst of uploads instantly, the queue holds the backlog, and the workers process it at their own pace without being overwhelmed. Messages also survive worker failures, which is the topic of the next part.
#Timeouts, retries and the dead-letter queue
- Visibility timeout (default 300 seconds, up to 12 hours): when a daemon receives a message, SQS hides it from everyone else for this long. If the job is not confirmed in time, the message becomes visible again and another worker gets it. Set it longer than your longest job, otherwise a slow job is processed twice.
- Error visibility timeout: how long a message stays hidden after your code returns an error, before the next try.
- Inactivity timeout: how long the daemon waits for your code to answer; raise it with the visibility timeout for long jobs.
- Max retries (default 10, range 1–100): after that many failed attempts, the message moves to a dead-letter queue (DLQ). With an autogenerated queue the DLQ is set up for you; with your own queue you configure it in SQS. Without a DLQ, a message that always fails cycles until its retention period (4 days by default) runs out.
- SQS delivers at least once: even with good settings, a message can be processed twice (for example when an instance dies just after finishing). Make jobs idempotent, so running one twice does no harm.
#Periodic tasks with cron.yaml
A cron.yaml file in the worker’s source bundle defines scheduled jobs: a name, a URL path and a cron expression (times are in Coordinated Universal Time). Exactly one instance, the leader, enqueues each task when it is due; the instances elect the leader by writing to a DynamoDB table, and if the leader dies another takes over. Any worker then processes the message, like any other job. Periodic tasks are not supported with a FIFO queue.
version: 1
cron:
- name: "nightly-report"
url: "/tasks/report"
schedule: "0 2 * * *"
#Scaling the workers
A worker environment has its own Auto Scaling group. Its default scaling triggers are the same generic instance metrics as a web environment, but the real signal for a worker is the queue: how many messages are waiting per instance. Add a CloudWatch alarm or a target tracking policy on the SQS metric ApproximateNumberOfMessagesVisible divided by the number of instances, the “backlog per instance” method from lesson 6.5. A worker that waits on a slow external API can have a growing queue and low CPU at the same time, so CPU-based scaling would never react.
Web tier → SQS → worker tier
The web tier answers users fast and drops slow jobs into an SQS queue. A daemon on every worker instance pulls each message and POSTs it to your code on localhost.
Scenario
A user uploads a video. Converting it takes minutes, far too long to keep an HTTP request open, and it would tie up the web server.
#Deploying a new version
You upload v2 and deploy it to an environment that runs v1. How v2 reaches the instances is the deployment policy, set per environment (option DeploymentPolicy in aws:elasticbeanstalk:command). There are five built-in policies. The notes list four; the fifth, traffic splitting, is just as examinable. Blue/green is not a policy at all, but a pattern with two environments, covered in the next section.
#All at once
Beanstalk installs v2 on every instance at the same time. The application servers restart, so for a short time nothing is in service.
- Fastest deployment, no extra instances, no extra cost.
- Downtime during the deployment. If v2 is broken, the whole fleet is broken: a full outage until you redeploy v1 manually.
- Use it for development and test, or when a short outage is acceptable. It is Beanstalk’s default policy, except that a load-balanced environment created with the EB CLI starts with rolling.
#Rolling
Beanstalk splits the instances into batches and updates one batch at a time. For each batch it takes the instances out of the load balancer (draining connections), deploys v2, waits for them to pass health checks, and puts them back.
- No downtime, but capacity drops by one batch for the whole deployment, so plan for it at peak hours.
- Batch size is a percentage of the instances or a fixed number.
- For a while, v1 and v2 serve users side by side, so both must work with the same database schema and APIs.
- If a batch fails its health checks within the command timeout, the deployment stops: completed batches run v2, the rest run v1. There is no automatic rollback; you deploy a known good version again.
- Not available for single-instance environments.
Calculating it: 8 instances with a 25% batch size = 2 instances per batch = 4 batches, and only 6 of 8 instances (75%) serve during the deployment. With a batch size of 50% it is 2 batches, faster, but only 4 of 8 serve.
Self-checkQuestion
An environment runs 6 instances with the Rolling policy and a fixed batch size of 2. How many batches does a deployment take, and how many instances are in service while a batch is being updated?
#Rolling with additional batch
The same as rolling, except that Beanstalk first launches one extra batch of new instances with v2. Then it rolls through the existing instances, and at the end it terminates an extra batch’s worth of instances.
- Full capacity throughout: the in-service count never drops below the original. Use it when a rolling deployment’s lost capacity would hurt.
- Slightly more cost (the extra batch runs for the length of the deployment) and a longer deployment than rolling.
- If the very first (new) batch fails, impact is minimal because no existing instance was touched; if a later batch fails, you are in the same partial state as a failed rolling deployment. Rollback is a manual redeploy.
- Calculating it: 8 instances, batch 25% → Beanstalk adds 2, so up to 10 instances run and 8 are always in service.
#Immutable
Beanstalk never touches the existing instances. Instead:
- It creates a temporary Auto Scaling group behind the same load balancer and launches one instance with v2.
- When that instance passes health checks, it launches enough instances to match the original group.
- When all of them are healthy, it moves the new instances into the original Auto Scaling group, then terminates the old instances and the temporary group.
Properties:
- Zero downtime, full capacity, and every v2 instance is brand new: no half-updated instance, no leftovers from v1.
- For a short time the environment runs double the instances (8 become 16), so check your EC2 On-Demand quota on a big fleet. It is the slowest of the policies inside one environment, and instances lose their accumulated burst credits.
- Rollback is quick and automatic: if the new instances fail their health checks, Beanstalk terminates the temporary group. The original instances never stopped serving v1.
- It requires enhanced health reporting, and it works on single-instance environments too.
The notes describe immutable as “a whole new ASG; delete the old one after tests pass”. More precisely, the original ASG survives: the new instances are moved into it, and it is the temporary group and the old instances that are deleted.
#Traffic splitting
Traffic splitting is a canary deployment built into Beanstalk:
- Like immutable, Beanstalk launches a full set of new instances in a temporary Auto Scaling group.
- The load balancer sends a percentage of requests to the new instances (
NewVersionPercent, default 10%) for an evaluation time (default 5 minutes, range 3–600). - If the new instances stay healthy, all traffic moves to them, they join the original ASG, and the old instances and the temporary group are removed. If they become unhealthy, or you abort, Beanstalk moves all traffic back to v1 and terminates the new instances.
Only the canary share of users can see a broken v2, and the rollback is automatic. Traffic splitting needs an Application Load Balancer, which does the split much like the weighted target groups of lesson 6.3, and is not available for single-instance environments.
#The five policies side by side
| Policy | Downtime | Capacity during deploy | Extra instances | Deploy time | If v2 fails | Rollback | v2 runs on |
|---|---|---|---|---|---|---|---|
| All at once | Yes | 0 for a short time | None | Fastest | Full outage | Manual redeploy | Existing instances |
| Rolling | No | Reduced by one batch | None | Moderate (depends on batch size) | One batch out; finished batches on v2 | Manual redeploy | Existing instances |
| Rolling with additional batch | No | Full | One batch | Longer | Minimal if the first batch fails, else like rolling | Manual redeploy | New and existing |
| Immutable | No | Full, doubled briefly | A full set | Slowest | Minimal | Terminate new instances (automatic) | New instances |
| Traffic splitting | No | Full, doubled | A full set | Slowest (plus evaluation time) | Canary share affected | Reroute and terminate (automatic) | New instances |
| Blue/green (pattern) | No | Full, two environments | A whole environment | Slowest | Minimal (caught before the swap) | Swap URLs back | A new environment |
None of the five built-in policies changes DNS; only blue/green does.
Try every policy with a working and a broken v2:
Deployment policy simulator
Four instances serve v1. Pick a policy, choose whether v2 is broken, and press play. Watch where v2 runs, how much capacity is left, and how each policy fails.
Deployment policy
Batch size
Version 2
Environment’s ASG
v1 · v2 · deploying (out of service) · launching · broken v2 · terminated
Time
0 min
Healthy in service
4 / 4
Instances running
4
Requests now
Four instances serve v1 behind the load balancer. You run eb deploy with v2 and the All at once policy.
#Blue/green: a second environment and a URL swap
The safest release keeps the whole old environment ready to take traffic back. That is blue/green, and in Beanstalk it is a manual pattern, not a deployment policy:
- Blue (
shop-prod) serves production with v1. - You clone it, or create a new environment, as green (
shop-green) and deploy v2 there. Green has its own URL, load balancer and instances. - You test green through its own URL while users stay on blue.
- You choose Swap environment URLs (
eb swap, or theSwapEnvironmentCNAMEsAPI). Beanstalk swaps the CNAME records of the two environments:shop-prod.us-east-1.elasticbeanstalk.comnow points at green’s load balancer. - If something goes wrong, you swap again. Blue never stopped.
Use blue/green when a deployment policy cannot do the job: moving to a new platform branch, changing settings that cannot be changed in place, or when you need the old environment intact as the fastest way back.
The caveats:
- DNS caching. The swap changes a DNS record, so it moves users only as fast as resolvers drop the old answer. Some users keep reaching blue for the TTL of the record (lesson 8.1), and some resolvers and clients cache longer than the TTL. AWS’s advice: do not terminate the old environment until the old DNS records have expired. The rollback swap has the same delay.
- Your own domain must follow. If
www.example.comis a Route 53 alias to the environment (or a CNAME to the environment URL), it follows the swap. If someone pointed it straight at blue’s load balancer DNS name, the swap does nothing for your users. - Shared database. Both environments must use the same database outside Beanstalk (the coupled database problem from earlier).
- Cost. You pay for two full environments while both run.
When you need an instant, per-request switch rather than a DNS one, use traffic splitting inside the environment, or Route 53 weighted records (lesson 8.3) in front of the two environments for a gradual DNS-level shift.
Blue/green: swapping environment URLs
Two complete environments. The production name is a DNS record, and swapping it moves users, but only as fast as DNS caches let it.
Scenario
User A looks up shop-prod.us-east-1.elasticbeanstalk.com. That name is a CNAME record that points at the blue environment’s load balancer.
#Health and automatic rollback
#Basic and enhanced health
Every environment shows a health colour: green (OK), yellow (warning), red (degraded or severe) or grey (unknown, or an update in progress).
- Basic health uses the load balancer’s health checks (or, for a single instance, EC2 status checks) and a few CloudWatch metrics published every 5 minutes.
- Enhanced health adds a health agent on every instance that reports OS metrics, web server logs (request counts, 4xx and 5xx rates, latency) and deployment status to Beanstalk every 10 seconds, with statuses such as Ok, Warning, Degraded and Severe and a “cause” for each. It is on by default for environments created in the console, it is free unless you publish its metrics to CloudWatch, and immutable deployments and managed platform updates require it.
eb healthshows it live.
Set a proper health check URL (a path such as /health that really exercises the app). Without one, an instance counts as healthy as soon as it accepts a TCP connection, possibly before the app has started.
#What happens when a deployment fails
During a deployment, each batch (or each new group of instances) must become healthy within the command timeout (default 600 seconds, plus a fixed four minutes Beanstalk adds). With enhanced health, a web instance must pass 12 consecutive checks over two minutes. Then:
- All at once, rolling, rolling with additional batch: the deployment fails and stops where it is. Nothing is undone automatically; the deployment ID on each instance shows which version it runs, and you redeploy a good version to roll back.
- Immutable: Beanstalk terminates the temporary Auto Scaling group; logs from the failed instances stay in S3 for an hour so you can see why.
- Traffic splitting: Beanstalk shifts all traffic back to the old instances and terminates the new ones.
- Two settings change this: Healthy threshold lets instances pass at a lower level (for example Warning), and Ignore health check deploys regardless of health. Both trade safety for speed.
#Exam patterns at a glance
#Beanstalk in system design
- It is the 9.1–9.3 architecture, packaged. ALB across AZs, an ASG with health checks, security groups chained tier to tier: Beanstalk builds exactly what you designed by hand. Your design work moves to choosing settings: minimum of 2 or more, multi-AZ subnets, a scaling metric that matches the load, a health check URL.
- Keep instances stateless. Every deployment policy except all at once replaces or recycles instances, so sessions belong in ElastiCache or DynamoDB (lesson 9.2), uploads in S3 or EFS (lesson 9.3), and the database outside the environment.
- Pick the policy by risk. Dev: all at once or single instance. Production web: immutable or traffic splitting, with rolling with additional batch when cost matters more. Platform-branch migrations and risky changes: blue/green.
- Split by tier. Fast requests in the web tier, slow work through SQS into a worker tier that scales on queue depth. Several applications can share one queue pattern with different paths.
- Know when to move on. Microservices with many containers usually outgrow Beanstalk for ECS or EKS (chapter 14); event-driven glue fits Lambda better (chapter 15); a full infrastructure-as-code setup with CloudFormation or the CDK gives you everything Beanstalk does, with more work and more control.
#Try it yourself
With the EB CLI (pip install awsebcli) in a project folder:
# 1. Create the application (asks for Region and platform) and a cheap dev environment
eb init shop --platform node.js --region us-east-1
eb create shop-dev --single # one instance + Elastic IP, no load balancer
# 2. A production environment with an Application Load Balancer
eb create shop-prod --elb-type application
# 3. Ship a new version, watch health, read logs, log in
eb deploy shop-prod # zips, uploads to S3 as a new version, deploys
eb health shop-prod # enhanced health, refreshed live
eb logs shop-prod
eb ssh shop-prod # OS access (changes made here do not survive)
# 4. Environment properties (environment variables) for the app
eb setenv DB_HOST=shop-db.abc123.us-east-1.rds.amazonaws.com FEATURE_X=on
# 5. Blue/green: clone, deploy v2 to the clone, test it, swap the URLs
eb clone shop-prod --clone_name shop-green
eb deploy shop-green
eb swap shop-prod --destination_name shop-green
# 6. A worker environment for background jobs
eb create shop-worker --tier worker
The same with the AWS CLI:
# Upload a version from S3 and deploy it with the Immutable policy
aws elasticbeanstalk create-application-version --application-name shop \
--version-label v42 --source-bundle S3Bucket=my-builds-bucket,S3Key=shop-v42.zip
aws elasticbeanstalk update-environment --environment-name shop-prod --version-label v42 \
--option-settings Namespace=aws:elasticbeanstalk:command,OptionName=DeploymentPolicy,Value=Immutable
# Real high availability: at least two instances
aws elasticbeanstalk update-environment --environment-name shop-prod \
--option-settings Namespace=aws:autoscaling:asg,OptionName=MinSize,Value=2
# Health, events and the URL swap
aws elasticbeanstalk describe-environment-health --environment-name shop-prod --attribute-names All
aws elasticbeanstalk describe-events --environment-name shop-prod --max-items 20
aws elasticbeanstalk swap-environment-cnames \
--source-environment-name shop-prod --destination-environment-name shop-green
# What did the environment create? (the stack is named after the environment ID)
aws elasticbeanstalk describe-environment-resources --environment-name shop-prod
A configuration file in the source bundle, .ebextensions/01-deploy.config:
option_settings:
aws:elasticbeanstalk:command:
DeploymentPolicy: TrafficSplitting
aws:elasticbeanstalk:trafficsplitting:
NewVersionPercent: "10"
EvaluationTime: "5"
aws:elasticbeanstalk:application:
Application Healthcheck URL: /health
packages:
yum:
ImageMagick: []
And a platform hook that runs on every instance before the new version goes live, .platform/hooks/predeploy/01-migrate.sh:
#!/bin/bash
# Runs after the bundle is extracted, before the app starts serving
cd /var/app/staging && npm run migrate
#Summary
Key takeaways
- Elastic Beanstalk is a developer-centric PaaS: you upload code, it builds and runs the standard ALB + ASG + EC2 architecture in your account through CloudFormation. Beanstalk is free; you pay for the resources. It is not serverless.
- Full control: you can log in to the instances, but instances are replaced, so persistent changes go in
.ebextensions,.platformhooks and configuration options. - Application (container) → application versions (source bundles in S3, quota 1,000 per Region) → environments (one version at a time, own URL
name.region.elasticbeanstalk.com, tier). - Platforms: Docker and ECS on Amazon Linux 2023, Go, Java (Corretto), Tomcat, .NET (Linux and Windows/IIS), Node.js, PHP, Python, Ruby. Managed platform updates: minor and patch, weekly window, immutable.
- Single instance (Elastic IP, no load balancer, dev) vs load-balanced (ALB, multi-AZ ASG, prod; set minimum ≥ 2). Keep RDS outside the environment; a coupled database is deleted with it by default.
- Web tier answers users; worker tier takes jobs from SQS: the sqsd daemon POSTs to localhost, 200 → delete; visibility timeout longer than the job; max retries → DLQ;
cron.yamlfor schedules; scale on queue depth. - Five policies: all at once (fast, downtime), rolling (capacity − one batch, manual rollback), rolling with additional batch (full capacity, extra batch), immutable (temporary ASG, doubled briefly, automatic cheap rollback), traffic splitting (canary %, ALB, automatic rollback).
- Blue/green = second environment + swap environment URLs (CNAME swap); keep the old one until DNS caches expire; point your domain at the environment, not the load balancer.
- Enhanced health (agent every 10 s) is required for immutable and managed updates; failed rolling deployments need a manual redeploy.
Answer on your own first, then read the explanation, even when you got it right.
Self-checkQuestion
Which description of AWS Elastic Beanstalk is the most accurate?
Self-checkQuestion
How is Elastic Beanstalk billed?
Self-checkQuestion
Which two statements about applications, application versions and environments are true?
Choose 2
Self-checkQuestion
What does Elastic Beanstalk use under the hood to create an environment’s resources?
Self-checkQuestion
Which of the following is NOT created by default for a new load-balanced web server environment?
Self-checkQuestion
Which two platforms can you choose for a new Elastic Beanstalk environment today?
Choose 2
Self-checkQuestion
Which statement about managed platform updates is correct?
Self-checkQuestion
Which two statements describe a single-instance environment?
Choose 2
Self-checkQuestion
Which deployment policies can a single-instance environment use?
Self-checkQuestion
How does code in a worker environment receive jobs from the SQS queue?
Self-checkQuestion
What is true about periodic tasks defined in cron.yaml in a worker environment?
Self-checkQuestion
Developers want to deploy a web application without managing the underlying infrastructure, but they must keep full administrative access to the operating system of the servers. Which service fits best?
Self-checkQuestion
A Beanstalk web application generates large report files on request, and pages slow down for every user whenever several reports run. What should the architect do?
Self-checkQuestion
A colleague says “Beanstalk is serverless, so we no longer pay for idle servers”. What is accurate?
Self-checkQuestion
A team terminated an old Beanstalk environment during a blue/green release and lost its production database, which had been added through the environment’s Database settings. How should they avoid this in future?
Self-checkQuestion
A developer logs in to a Beanstalk instance with eb ssh and installs a system package by hand. A few days later the package is missing on some instances. What explains it, and what is the fix?
Self-checkQuestion
An environment runs 8 instances and uses the Rolling policy with a 25% batch size. How many batches does a deployment take, and what is the lowest number of instances in service during it?
Self-checkQuestion
The same 8-instance environment switches to Rolling with additional batch, still with a 25% batch size. What is the largest number of instances running at once, and the lowest number in service?
Self-checkQuestion
A company deploys to an 8-instance environment with the Immutable policy. Its On-Demand instance quota is close to the limit. Why is that a concern?
Self-checkQuestion
A rolling deployment fails during the third of four batches. What is the state of the environment?
Self-checkQuestion
During an immutable deployment, the first new instance fails its health checks. What does Elastic Beanstalk do?
Self-checkQuestion
An exam question asks for the deployment approaches in Elastic Beanstalk that give zero downtime and the quickest rollback. Which two should you choose?
Choose 2
Self-checkQuestion
Which two statements about the traffic splitting deployment policy are true?
Choose 2
Self-checkQuestion
A production environment must keep its full serving capacity during every deployment, and the company wants to avoid doubling its fleet each time. Which deployment policy fits best?
Self-checkQuestion
A team wants each new version to receive a small share of real user traffic first and to be rolled back automatically if it becomes unhealthy, with no manual DNS changes. What should they use?
Self-checkQuestion
In a worker environment with an autogenerated queue, one message always makes the application return HTTP 500. What happens to it with default settings?
Self-checkQuestion
Worker jobs take about 10 minutes. Customers sometimes receive the same email twice, and logs show two workers handling the same message. The worker settings are the defaults. What is the fix?
Self-checkQuestion
A worker environment calls a slow partner API for each job. The SQS queue grows to thousands of messages, yet the workers’ CPU stays around 10% and the environment never scales out. What should the architect change?
Self-checkQuestion
After swapping environment URLs for a blue/green release, some users still reach the old version for several minutes. What is the cause?
Self-checkQuestion
www.example.com is a Route 53 alias record that targets the DNS name of the blue environment’s load balancer. After a URL swap, every user still gets the old version. What should be changed?