← Back to DevBytes

Elastic Beanstalk: Complete Setup and Configuration Guide

Introduction to AWS Elastic Beanstalk

Deploying and managing web applications in the cloud involves a staggering number of moving parts: EC2 instances, load balancers, auto-scaling groups, security groups, S3 storage, monitoring alarms, and deployment pipelines. AWS Elastic Beanstalk abstracts away this complexity, giving developers a single, coherent platform to deploy applications with minimal friction. Think of it as a managed Platform-as-a-Service (PaaS) layer that sits on top of core AWS infrastructure services. You hand it your code, and Elastic Beanstalk handles the rest—provisioning resources, managing capacity, monitoring health, and even applying platform updates. This tutorial walks you through a complete setup and configuration journey, from installing the command-line tools to running a production-ready environment with custom configurations, database integration, and secure HTTPS endpoints.

What is AWS Elastic Beanstalk?

šŸš€ Deploy your AI agent in 10 minutes

Managed Hermes hosting. Zero DevOps. 100M tokens/mo included.

Try it free →

AWS Elastic Beanstalk is an orchestration service that automates the deployment of applications across the AWS infrastructure stack. It supports multiple platforms including Java, .NET, Node.js, Python, Ruby, Go, PHP, and Docker containers. When you provide your application code—either as a ZIP archive, a WAR file, or a Docker image—Elastic Beanstalk automatically creates an environment that includes:

The key insight is that you retain full control over every underlying resource—you can SSH into instances, tweak security groups, and customize CloudFormation templates—but you don't have to manage any of it unless you want to. Elastic Beanstalk uses AWS CloudFormation under the hood to provision resources, which means you get all the benefits of infrastructure-as-code without writing a single CloudFormation template by hand.

Why Elastic Beanstalk Matters

For development teams, Elastic Beanstalk solves several critical pain points:

Core Concepts and Architecture

Before diving into the hands-on setup, it is important to understand the building blocks of Elastic Beanstalk:

Prerequisites

To follow this tutorial, you will need:

Complete Setup and Configuration Guide

Step 1: Installing the Elastic Beanstalk CLI

The EB CLI is a Python-based command-line tool that provides direct, scriptable access to Elastic Beanstalk operations. Install it using pip inside a virtual environment to avoid system-wide Python conflicts:

# Create and activate a virtual environment (recommended)
python3 -m venv eb-cli-venv
source eb-cli-venv/bin/activate

# Install the EB CLI via pip
pip install awsebcli

# Verify the installation
eb --version
# Expected output: EB CLI 3.20.x (Python 3.x)

# Deactivate the virtual environment when done
deactivate

Alternatively, you can install it globally, but the virtual environment approach keeps dependencies isolated. On macOS you can also use Homebrew: brew install awsebcli.

Step 2: Creating a Sample Application

Create a minimal Node.js application to use throughout this guide. This gives you a concrete, testable artifact to deploy:

# Create project directory and navigate into it
mkdir my-elasticbeanstalk-app
cd my-elasticbeanstalk-app

# Initialize a Node.js project
npm init -y

# Install Express as a dependency
npm install express

# Create the main application file
cat > app.js << 'EOF'
const express = require('express');
const app = express();
const PORT = process.env.PORT || 8080;

app.get('/', (req, res) => {
  res.json({
    status: 'healthy',
    message: 'Elastic Beanstalk deployment successful!',
    environment: process.env.ENVIRONMENT_NAME || 'unknown',
    timestamp: new Date().toISOString()
  });
});

app.get('/health', (req, res) => {
  res.status(200).json({ status: 'ok' });
});

const server = app.listen(PORT, () => {
  console.log(`Server running on port ${PORT}`);
});

// Graceful shutdown handling
process.on('SIGTERM', () => {
  console.log('SIGTERM received, shutting down gracefully');
  server.close(() => process.exit(0));
});
EOF

# Create a Procfile (optional for Node.js but good practice)
cat > Procfile << 'EOF'
web: node app.js
EOF

The application listens on the port specified by the PORT environment variable—Elastic Beanstalk sets this automatically for web server environments. The /health endpoint is useful for configuring custom health checks later.

Step 3: Initializing an Elastic Beanstalk Environment

Navigate to your project directory and run eb init to configure the application and its first environment. This interactive command sets up the connection between your local code and the Elastic Beanstalk service:

# Initialize Elastic Beanstalk for this project
eb init

# Interactive prompts (fill in as follows):
# Select a default region: [choose your preferred region, e.g., us-east-1]
# Select an application: [Create new application] 
# Application name: my-elasticbeanstalk-app
# Select a platform: Node.js 18 (or the latest available)
# Select a platform branch: [default]
# Do you want to use CodeCommit? [N]
# Do you want to set up SSH for your instances? [Y]
# Select a keypair: [choose existing or create new]

Behind the scenes, eb init creates a hidden .elasticbeanstalk directory containing configuration files. The key file is config.yml, which stores your application name, default region, platform selection, and SSH keypair name. You can inspect it:

cat .elasticbeanstalk/config.yml
# Example output:
# branch-defaults:
#   default:
#     environment: null
# global:
#   application_name: my-elasticbeanstalk-app
#   default_ec2_keyname: my-keypair
#   default_platform: Node.js 18
#   default_region: us-east-1

Step 4: Creating Your First Environment

Now create a running environment. The eb create command provisions all resources and deploys your application in one step:

# Create a production-ready environment with a load balancer
eb create production-env

# Or create a simpler, single-instance environment for development
eb create dev-env --single

# Monitor the creation process
eb status

# Once complete, open the application in a browser
eb open

The environment creation process takes approximately 5–10 minutes. During this time, Elastic Beanstalk provisions an EC2 instance, a security group, an Elastic Load Balancer (unless you used --single), and an Auto Scaling group, then uploads your application code and deploys it. You can watch the events stream with:

eb events --follow

Step 5: Deploying Application Updates

After making changes to your code, deploy updates with a single command. Elastic Beanstalk handles the deployment strategy based on your environment type:

# Stage and deploy all changes
eb deploy

# Deploy with a specific version label
eb deploy --version v1.2.0

# Deploy with a message for tracking
eb deploy --message "Added health check endpoint and error handling"

# List all deployed versions
eb list

# View detailed deployment information
eb status --verbose

By default, eb deploy creates a ZIP archive of your project (respecting .ebignore or .gitignore), uploads it to S3, creates a new application version, and triggers a deployment to your environment. The deployment strategy defaults to "all at once" for new environments—you can change this later.

Step 6: Configuring Environment Properties and Variables

Environment variables are the primary way to inject configuration into your application without modifying code. Set them via the CLI or the Management Console:

# Set environment variables via CLI
eb setenv ENVIRONMENT_NAME=production DATABASE_URL=postgres://localhost:5432/mydb LOG_LEVEL=info

# View current environment variables
eb printenv

# Remove a specific variable
eb setenv DATABASE_URL= --delete

# Set multiple variables from a file
cat > env-vars.txt << 'EOF'
ENVIRONMENT_NAME=production
DATABASE_URL=postgres://db-host:5432/mydb
LOG_LEVEL=info
API_KEY=sk-123456789
EOF
eb setenv --file env-vars.txt

Environment variables are stored encrypted in the Elastic Beanstalk configuration and are available to your application process at runtime. For sensitive values like API keys and database passwords, consider using AWS Secrets Manager or SSM Parameter Store combined with IAM roles for retrieval at application startup, rather than plain environment variables.

Step 7: Customizing Environment Configuration with .ebextensions

For configurations beyond what the CLI exposes directly, Elastic Beanstalk uses .ebextensions configuration files written in YAML or JSON. These files allow you to customize every aspect of the underlying CloudFormation stack. Create a .ebextensions directory in your project root and add configuration files:

mkdir .ebextensions

cat > .ebextensions/01-instance-config.config << 'EOF'
option_settings:
  aws:autoscaling:launchconfiguration:
    InstanceType: t3.medium
    EC2KeyName: my-keypair
    IamInstanceProfile: aws-elasticbeanstalk-ec2-role
  aws:autoscaling:asg:
    MinSize: 2
    MaxSize: 4
  aws:elasticbeanstalk:application:
    Application Healthcheck URL: /health
  aws:elasticbeanstalk:environment:
    EnvironmentType: LoadBalanced
    LoadBalancerType: application
  aws:ec2:vpc:
    VPCId: vpc-0a1b2c3d4e5f6
    Subnets: subnet-111,subnet-222
    ELBSubnets: subnet-333,subnet-444
EOF

cat > .ebextensions/02-cloudwatch-logs.config << 'EOF'
packages:
  yum:
    awslogs: []

commands:
  01_configure_awslogs:
    command: |
      cat > /etc/awslogs/awslogs.conf << 'AWSCONF'
      [general]
      state_file = /var/lib/awslogs/agent-state
      [/var/log/eb-engine.log]
      file = /var/log/eb-engine.log
      log_group_name = `/aws/elasticbeanstalk/${AWSEBEnvironmentName}/eb-engine.log`
      log_stream_name = {instance_id}
      [/var/log/nginx/access.log]
      file = /var/log/nginx/access.log
      log_group_name = `/aws/elasticbeanstalk/${AWSEBEnvironmentName}/nginx-access.log`
      log_stream_name = {instance_id}
      AWSCONF
  02_start_awslogs:
    command: service awslogs start
EOF

Configuration files are processed in alphabetical order. The naming convention 01-xxx.config, 02-xxx.config ensures predictable execution order. The option_settings key maps directly to CloudFormation resource properties, giving you fine-grained control over instance types, scaling parameters, VPC placement, and health check URLs.

Step 8: Configuring Auto Scaling and Load Balancing

Production environments need proper scaling policies. Elastic Beanstalk supports multiple scaling options that you can configure through .ebextensions:

cat > .ebextensions/03-scaling.config << 'EOF'
option_settings:
  aws:autoscaling:asg:
    MinSize: 2
    MaxSize: 10
    CustomMin: 2
    CustomMax: 10
  aws:autoscaling:trigger:
    MeasureName: TargetResponseTime
    Statistic: Average
    Unit: Seconds
    Period: 300
    EvaluationPeriods: 2
    UpperThreshold: 3
    LowerThreshold: 1
    UpperBreachScaleIncrement: 2
    LowerBreachScaleIncrement: -1
  aws:elbv2:listener:default:
    ListenerEnabled: true
    Protocol: HTTP
    Port: 80
  aws:elasticbeanstalk:healthreporting:system:
    SystemType: enhanced
    HealthCheckSuccessThreshold: 3
    ConfigDocument:
      ApplicationHealthcheckEnabled: true
      ApplicationHealthcheckURL: /health
      ApplicationHealthcheckTimeoutSeconds: 5
EOF

This configuration establishes CPU-based scaling with thresholds that react to sustained load. The enhanced health reporting system provides detailed instance-level metrics and automatic recovery when instances fail health checks. For more sophisticated scaling, you can use step scaling policies or scheduled scaling actions via additional CloudFormation resources in your .ebextensions files.

Step 9: Integrating an RDS Database

Elastic Beanstalk can provision and manage an RDS database instance tied to your environment. However, for production workloads, it is strongly recommended to create the database independently and reference it via environment variables, so that environment termination does not accidentally delete your data:

# Create an RDS instance independently (recommended for production)
aws rds create-db-instance \
  --db-instance-identifier myapp-postgres \
  --db-instance-class db.t3.medium \
  --engine postgres \
  --engine-version 15.4 \
  --master-username myappuser \
  --master-user-password 'SecurePassw0rd!' \
  --allocated-storage 20 \
  --vpc-security-group-ids sg-0a1b2c3d4e5f6 \
  --db-subnet-group-name my-db-subnet-group \
  --publicly-accessible false

# Wait for the database to become available
aws rds describe-db-instances \
  --db-instance-identifier myapp-postgres \
  --query 'DBInstances[0].Endpoint.Address'

# Set the connection string as an environment variable in Elastic Beanstalk
eb setenv DATABASE_URL=postgres://myappuser:SecurePassw0rd!@myapp-postgres.xxxxx.us-east-1.rds.amazonaws.com:5432/mydb

If you do choose to let Elastic Beanstalk create the database, use the --database flag with eb create. But always enable snapshot retention and understand that the database lifecycle is tied to the environment unless you explicitly decouple it:

# Creating an environment with an integrated RDS database (development only)
eb create dev-with-db --database \
  --database.instance db.t3.micro \
  --database.storage 20 \
  --database.user myappuser \
  --database.pass 'SecurePassw0rd!'

Step 10: Configuring HTTPS and Custom Domains

Production applications must serve traffic over HTTPS. Elastic Beanstalk supports Application Load Balancers (ALB) with HTTPS listeners and ACM certificates. Here is how to configure it:

cat > .ebextensions/04-https-listener.config << 'EOF'
option_settings:
  aws:elbv2:listener:443:
    ListenerEnabled: true
    Protocol: HTTPS
    SSLCertificateArns: arn:aws:acm:us-east-1:123456789012:certificate/abc123-def456-ghi789
    SSLPolicy: ELBSecurityPolicy-TLS13-1-2-2021-06
    DefaultProcess: default
  aws:elbv2:listener:443:default:
    Protocol: HTTPS
    Port: 443

Resources:
  HttpListenerRedirect:
    Type: AWS::ElasticLoadBalancingV2::Listener
    Properties:
      DefaultActions:
        - Type: redirect
          RedirectConfig:
            Protocol: HTTPS
            Port: 443
            Host: '#{host}'
            Path: '/#{path}'
            Query: '#{query}'
            StatusCode: HTTP_301
      LoadBalancerArn:
        Ref: AWSEBLoadBalancer
      Port: 80
      Protocol: HTTP
EOF

Before applying this configuration, you must request an ACM certificate for your domain in the same region as your Elastic Beanstalk environment. Then update the SSLCertificateArns value with your certificate ARN. The included CloudFormation resource creates an HTTP-to-HTTPS redirect listener automatically.

For custom domains, create a CNAME or alias record in Route 53 pointing to your environment's load balancer endpoint:

# Get the environment's load balancer DNS name
eb status --verbose | grep -i "load.*balancer.*dns"

# Create a Route 53 alias record (via AWS CLI)
aws route53 change-resource-record-sets \
  --hosted-zone-id Z1234567890ABC \
  --change-batch '{
    "Changes": [{
      "Action": "CREATE",
      "ResourceRecordSet": {
        "Name": "app.example.com",
        "Type": "A",
        "AliasTarget": {
          "HostedZoneId": "Z35HXDROA1ZABC",
          "DNSName": "myapp-env-123.us-east-1.elb.amazonaws.com",
          "EvaluateTargetHealth": true
        }
      }
    }]
  }'

Step 11: Configuring Deployment Strategies

Elastic Beanstalk offers several deployment strategies that trade off speed against safety. Configure your preferred strategy through the CLI or configuration files:

# Set immutable deployment (safest option)
eb deploy --strategy immutable

# Set rolling deployment with batch size
eb deploy --strategy rolling --batch-size 25

# Set rolling with additional batch (extra safety)
eb deploy --strategy rolling-with-batch --batch-size 30

# Store the deployment strategy in a saved configuration
eb config save --cfg-name production-config

Immutable deployments create an entirely new set of instances, redirect traffic, and then terminate the old instances. This approach eliminates the risk of in-place failures but temporarily doubles your instance count. Rolling deployments update instances in batches, keeping capacity online throughout the process. Choose the strategy that matches your application's tolerance for brief capacity reduction and your budget for temporary duplicate infrastructure.

Step 12: Enabling Managed Platform Updates

AWS regularly releases updated platform versions with security patches, new AMIs, and language runtime updates. Elastic Beanstalk can automatically apply these updates on a schedule you control:

cat > .ebextensions/05-managed-updates.config << 'EOF'
option_settings:
  aws:elasticbeanstalk:managedactions:
    ManagedActionsEnabled: true
    PreferredStartTime: 'Sun:03:00'
  aws:elasticbeanstalk:managedactions:platform:
    UpdateLevel: minor
    InstanceRefreshEnabled: true
EOF

This configuration enables managed platform updates every Sunday at 3 AM UTC, applying minor version updates automatically. Major version updates (e.g., Python 3.10 to 3.11) require explicit opt-in. The InstanceRefreshEnabled setting ensures that during an update, instances are replaced rather than patched in-place, maintaining immutable infrastructure principles.

Step 13: Setting Up Environment Cloning and Blue/Green Deployments

For zero-downtime major version upgrades or risky changes, use environment cloning to create a staging environment identical to production:

# Clone the production environment
eb clone production-env --name production-green

# Deploy the new version to the green environment
eb deploy production-green --version v2.0.0

# Run smoke tests against the green environment's URL
curl https://production-green.us-east-1.elasticbeanstalk.com/health

# Swap environment CNAMEs to promote green to production
eb swap production-env --destination_name production-green

# After verifying the swap, terminate the old environment
eb terminate production-env --force

Environment swapping exchanges the CNAME records between two environments, instantly redirecting traffic with no downtime. This is the foundation of blue/green deployments on Elastic Beanstalk. Always test the green environment thoroughly before initiating the swap.

Step 14: Monitoring, Logging, and Troubleshooting

Elastic Beanstalk integrates deeply with CloudWatch for metrics, logs, and alarms. Access logs and metrics through the EB CLI:

# View recent environment events
eb events --limit 20

# Tail environment logs in real time
eb logs --tail

# Download all logs for a specific instance
eb logs --instance i-0a1b2c3d4e5f6 --zip-output logs.zip

# View CloudWatch metrics for the environment
eb health --refresh

# SSH into an instance for deeper troubleshooting
eb ssh
# Once connected, check application logs:
sudo tail -f /var/log/eb-engine.log
sudo tail -f /var/log/nginx/access.log

Set up CloudWatch alarms for critical metrics to receive notifications when your environment experiences issues:

cat > .ebextensions/06-cloudwatch-alarms.config << 'EOF'
Resources:
  HighCPUAlarm:
    Type: AWS::CloudWatch::Alarm
    Properties:
      AlarmName: 
        Fn::Sub: "${AWSEBEnvironmentName}-HighCPU"
      AlarmDescription: "CPU utilization exceeds 85% for 5 minutes"
      Namespace: AWS/EC2
      MetricName: CPUUtilization
      Dimensions:
        - Name: AutoScalingGroupName
          Value: 
            Ref: AWSEBAutoScalingGroup
      Statistic: Average
      Period: 300
      EvaluationPeriods: 1
      Threshold: 85
      ComparisonOperator: GreaterThanThreshold
      AlarmActions:
        - Ref: NotificationTopic

  NotificationTopic:
    Type: AWS::SNS::Topic
    Properties:
      TopicName: 
        Fn::Sub: "${AWSEBEnvironmentName}-Alerts"
      Subscription:
        - Endpoint: admin@example.com
          Protocol: email
EOF

Best Practices for Elastic Beanstalk

Conclusion

AWS Elastic Beanstalk occupies a powerful middle ground in the cloud deployment landscape—it provides enough abstraction to eliminate infrastructure toil while preserving enough control to handle complex production requirements. Through this guide, you have walked through a complete journey: installing the CLI, creating a sample application, provisioning environments, configuring auto-scaling, integrating databases, enabling HTTPS, setting up managed updates, and establishing deployment pipelines with blue/green strategies. The combination of the EB CLI for rapid iteration and .ebextensions for deep customization gives you a platform that grows with your application's needs. As your architecture evolves, Elastic Beanstalk integrates naturally with other AWS services—you can add CloudFront CDN distributions, connect ElastiCache clusters, or route traffic through API Gateway, all while Elastic Beanstalk continues to handle the core compute and deployment concerns. The result is a development experience where infrastructure fades into the background, letting you focus on the code that delivers value to your users.

šŸš€ Need a reliable AI agent for your project?

Deploy Hermes Agent in 10 minutes. Managed hosting, zero DevOps.

Get Started — $23.99/mo
← Back to all articles