Skip to main content

AWS Elastic Beanstalk

Elastic Beanstalk provides an easy way to deploy containerized applications on AWS with automatic scaling, load balancing, and managed infrastructure.

Architecture

flowchart TB
subgraph EB["Elastic Beanstalk"]
ALB["Application Load Balancer"]

subgraph ASG["Auto Scaling Group"]
EC2_1["EC2<br/>API+Worker"]
EC2_2["EC2<br/>API+Worker"]
EC2_3["EC2<br/>API+Worker"]
end

ALB --> ASG
end

ASG --> RDS["RDS<br/>(Postgres)"]
ASG --> ElastiCache["ElastiCache<br/>(Redis)"]
ASG --> S3["S3<br/>(Storage)"]

Prerequisites

  • AWS account with appropriate permissions
  • EB CLI installed (pip install awsebcli)
  • RDS PostgreSQL instance (setup guide)
  • ElastiCache Redis cluster

Project Setup

1. Create Application Directory

mkdir boards-eb && cd boards-eb

2. Create docker-compose.yml

Elastic Beanstalk uses Docker Compose for multi-container deployments:

version: "3.8"

services:
api:
image: ghcr.io/weirdfingers/boards-backend:latest
command: ["uvicorn", "boards.api.app:app", "--host", "0.0.0.0", "--port", "8800"]
ports:
- "80:8800"
environment:
- BOARDS_DATABASE_URL=${BOARDS_DATABASE_URL}
- BOARDS_REDIS_URL=${BOARDS_REDIS_URL}
- BOARDS_GENERATOR_API_KEYS=${BOARDS_GENERATOR_API_KEYS}
- BOARDS_AUTH_PROVIDER=${BOARDS_AUTH_PROVIDER}
- BOARDS_LOG_FORMAT=json
- BOARDS_GENERATORS_CONFIG_PATH=/app/config/generators.yaml
- BOARDS_STORAGE_CONFIG_PATH=/app/config/storage_config.yaml
volumes:
- ./config:/app/config:ro

worker:
image: ghcr.io/weirdfingers/boards-backend:latest
command: ["boards-worker", "--log-level", "info", "--processes", "1", "--threads", "1"]
environment:
- BOARDS_DATABASE_URL=${BOARDS_DATABASE_URL}
- BOARDS_REDIS_URL=${BOARDS_REDIS_URL}
- BOARDS_GENERATOR_API_KEYS=${BOARDS_GENERATOR_API_KEYS}
- BOARDS_INTERNAL_API_URL=http://api:8800
- BOARDS_LOG_FORMAT=json
- BOARDS_GENERATORS_CONFIG_PATH=/app/config/generators.yaml
- BOARDS_STORAGE_CONFIG_PATH=/app/config/storage_config.yaml
volumes:
- ./config:/app/config:ro

3. Create Configuration Files

mkdir config

Create config/generators.yaml:

generators:
- class: boards.generators.fal.flux.FluxProGenerator
enabled: true
- class: boards.generators.openai.dalle.DallE3Generator
enabled: true

Create config/storage_config.yaml:

default_provider: s3

providers:
s3:
type: s3
bucket: my-boards-bucket
region: us-east-1

Initialize Elastic Beanstalk

eb init

# Select region
# Select "Create new Application"
# Name: boards
# Platform: Docker running on 64bit Amazon Linux 2023
# Select default options for remaining prompts

Create Environment

eb create boards-production \
--instance-type t3.small \
--scale 2 \
--elb-type application \
--vpc.id vpc-xxxxx \
--vpc.ec2subnets subnet-xxxxx,subnet-yyyyy \
--vpc.elbsubnets subnet-xxxxx,subnet-yyyyy

Configure Environment Variables

Store sensitive values securely:

# Database URL
eb setenv BOARDS_DATABASE_URL="postgresql://user:pass@rds-endpoint:5432/boards?sslmode=require"

# Redis URL
eb setenv BOARDS_REDIS_URL="redis://elasticache-endpoint:6379/0"

# Generator API keys
eb setenv BOARDS_GENERATOR_API_KEYS='{"fal": "your-key", "openai": "your-key"}'

# Auth configuration
eb setenv BOARDS_AUTH_PROVIDER=jwt
eb setenv BOARDS_JWT_SECRET="your-secret"

# AWS credentials for S3 (or use instance role)
eb setenv AWS_ACCESS_KEY_ID="xxxxx"
eb setenv AWS_SECRET_ACCESS_KEY="xxxxx"

Security Groups

Configure security group rules to allow:

  1. Elastic Beanstalk → RDS: Port 5432
  2. Elastic Beanstalk → ElastiCache: Port 6379
  3. Load Balancer → EC2: Port 80
# Allow EB instances to access RDS
aws ec2 authorize-security-group-ingress \
--group-id sg-rds-xxxxx \
--protocol tcp \
--port 5432 \
--source-group sg-eb-xxxxx

# Allow EB instances to access ElastiCache
aws ec2 authorize-security-group-ingress \
--group-id sg-redis-xxxxx \
--protocol tcp \
--port 6379 \
--source-group sg-eb-xxxxx

Deploy

eb deploy

Check deployment status:

eb status
eb health

HTTPS Configuration

Using ACM Certificate

  1. Request a certificate in AWS Certificate Manager
  2. Configure the load balancer:

Create .ebextensions/https.config:

option_settings:
aws:elbv2:listener:443:
ListenerEnabled: true
Protocol: HTTPS
SSLCertificateArns: arn:aws:acm:us-east-1:123456789:certificate/xxxxx
aws:elbv2:listener:80:
ListenerEnabled: true
Protocol: HTTP
Rules: redirect-to-https

Resources:
AWSEBV2LoadBalancerListener80:
Type: AWS::ElasticLoadBalancingV2::Listener
Properties:
DefaultActions:
- Type: redirect
RedirectConfig:
Protocol: HTTPS
Port: "443"
StatusCode: HTTP_301

Auto Scaling

Configure scaling in .ebextensions/autoscaling.config:

option_settings:
aws:autoscaling:asg:
MinSize: 2
MaxSize: 10
aws:autoscaling:trigger:
MeasureName: CPUUtilization
Unit: Percent
UpperThreshold: 70
LowerThreshold: 30
UpperBreakSize: 1
LowerBreakSize: 1

Instance Profile (IAM Role)

Create an instance profile with necessary permissions:

{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:PutObject",
"s3:GetObject",
"s3:DeleteObject"
],
"Resource": "arn:aws:s3:::my-boards-bucket/*"
},
{
"Effect": "Allow",
"Action": [
"secretsmanager:GetSecretValue"
],
"Resource": "arn:aws:secretsmanager:us-east-1:*:secret:boards/*"
}
]
}

Logging

CloudWatch Logs

Enable log streaming in .ebextensions/logs.config:

option_settings:
aws:elasticbeanstalk:cloudwatch:logs:
StreamLogs: true
DeleteOnTerminate: false
RetentionInDays: 30

View logs:

eb logs

Application Logs

# Recent logs
eb logs --all

# Stream logs
eb logs --stream

Monitoring

CloudWatch Metrics

Key metrics to monitor:

  • EnvironmentHealth
  • InstanceHealth
  • CPUUtilization
  • NetworkIn/NetworkOut

Health Dashboard

eb health --refresh

Updates and Rollback

Deploy New Version

# Update image version in docker-compose.yml
eb deploy

Rollback

# List versions
eb appversion

# Rollback to previous version
eb deploy --version version-label

Cost Optimization

  • Use Spot Instances for workers
  • Right-size instances based on usage
  • Consider Reserved Instances for steady workloads

Enable Spot in .ebextensions/spot.config:

option_settings:
aws:ec2:instances:
EnableSpot: true
SpotMaxPrice: 0.05

Troubleshooting

View Instance Logs

eb ssh
cat /var/log/eb-docker/containers/eb-current-app/*.log

Container Issues

eb ssh
docker ps
docker logs <container-id>

Database Connection

eb ssh
docker exec -it <api-container> python -c "from boards.db import engine; print(engine.connect())"

Next Steps