Skip to content
C Codeloom
AWS

AWS Elastic Beanstalk Tutorial: PaaS on AWS Without the Yak Shaving

Deploy web apps fast with Elastic Beanstalk. Learn environments, platforms, deployment policies, configuration via .ebextensions, and when to graduate to ECS or EKS.

·5 min read · By Codeloom
Beginner 9 min read

What you'll learn

  • What Elastic Beanstalk gives you out of the box
  • How environments, platforms, and application versions fit together
  • How to deploy a Node.js or Python app with the EB CLI
  • How .ebextensions and Procfile customize the platform
  • When Beanstalk is the wrong answer and you should move on

Prerequisites

  • A simple web app in Node.js, Python, Java, .NET, Go, Ruby, PHP, or Docker
  • An AWS account and the AWS CLI configured

Elastic Beanstalk (EB) is AWS’s original platform-as-a-service. You hand it a zip of your app and it provisions everything underneath: an EC2 Auto Scaling group, an Application Load Balancer, security groups, IAM roles, CloudWatch logs, and a deployment pipeline. You get URL-up-in-minutes simplicity without giving up access to the underlying resources.

What and Why

Beanstalk is a thin orchestration layer over CloudFormation. When you create an environment, it expands a stack template tailored to your chosen platform — Node 20, Python 3.12, Corretto 21, Docker, and so on. Each platform branch is essentially a curated AMI plus a deployment hook system.

Why pick it? Because the cheapest infrastructure is the one you don’t have to design. A small team shipping a single web service can be in production in an afternoon, with rolling deployments, health checks, and log aggregation already wired. The escape hatches are real too: every resource it creates can be tweaked or replaced.

Why not? Beanstalk hides primitives. Once you need multiple services per environment, gRPC sidecars, or fine-grained traffic shifting, you fight the abstraction. That’s the moment to graduate to ECS, EKS, or App Runner.

Mental Model

Three nouns, two verbs.

  • Application: a logical container, e.g. orders-api.
  • Application version: a labeled zip in S3, e.g. v42.
  • Environment: a running stack with a URL, e.g. orders-api-prod.

You create an environment from a version, and you deploy new versions into it. Most teams keep a prod and staging environment per application and swap CNAMEs for blue/green cutovers.

A deployment policy controls how new code reaches instances: AllAtOnce, Rolling, RollingWithAdditionalBatch, or Immutable. Production almost always wants Immutable — it spins up a fresh ASG, validates it, then swaps.

Hands-on Example

Install the EB CLI and ship a Node.js app:

pip install awsebcli
mkdir hello-eb && cd hello-eb
cat > app.js <<'EOF'
const http = require('http');
http.createServer((_, r) => r.end('hello from beanstalk\n'))
    .listen(process.env.PORT || 8080);
EOF
cat > package.json <<'EOF'
{ "name": "hello-eb", "scripts": { "start": "node app.js" }, "engines": { "node": "20.x" } }
EOF

eb init -p "Node.js 20" hello-eb --region us-east-1
eb create hello-eb-prod --instance-type t3.small

A minute later, eb open loads the URL. Update the code, run eb deploy, and the rolling deployment kicks off.

         Route 53
          |
          v
ALB (auto-created)
      / \
     v   v
 EC2-1  EC2-2  (Auto Scaling Group)
    \  /
     v
Optional RDS (created with env or external)

Around the box:
 - CloudWatch logs streamed from each instance
 - S3 bucket holds versions (zips)
 - IAM instance profile + service role
 - .ebextensions run on each instance at deploy time
Elastic Beanstalk environment architecture

To customize, drop YAML files under .ebextensions/:

# .ebextensions/01-env.config
option_settings:
  aws:elasticbeanstalk:application:environment:
    LOG_LEVEL: info
  aws:autoscaling:asg:
    MinSize: 2
    MaxSize: 6

For Docker platforms, use a Dockerrun.aws.json or a plain Dockerfile and let EB build it.

Common Pitfalls

  • Mixing config sources. Settings can come from saved configurations, .ebextensions, the console, and the CLI. When they conflict, debugging is painful. Pick one source of truth — usually .ebextensions in the repo.
  • Single-instance “production”. EB defaults to single-instance for dev. Production should be load-balanced with at least two AZs; switch via the environment type setting.
  • Tightly coupling RDS to the environment. EB can create an RDS instance inside the environment, but terminating the environment destroys the database. Always run RDS as a separate stack and pass its endpoint as an env var.
  • Deployment policy AllAtOnce in prod. Every instance gets the new code at once with no health gating. Use Immutable for prod.
  • Ignoring health colors. Yellow/red environment health is real signal. The enhanced health system surfaces actual HTTP status codes and slow responses.

Production Tips

Pin platform versions and update them on a schedule — managed platform updates can drift environments unexpectedly. Stream logs to CloudWatch Logs and turn off the per-instance log tail; on-disk logs disappear when an instance recycles.

Use the EB CLI’s eb deploy --version v42 for explicit version pinning in CI, and never eb deploy from a developer laptop into prod. Keep your .ebextensions minimal — once they exceed a few files, it’s a sign you’ve outgrown Beanstalk.

Wrap-up

Elastic Beanstalk is the fast path for small-to-medium web apps on AWS. Use the EB CLI, pick Immutable deployments, decouple your database, and lean on .ebextensions for repeatable config. When your needs grow past one service per environment, plan a graceful migration to ECS Fargate or App Runner.