AWS Elastic Beanstalk Deployment Guide: Simplified Application Hosting for Small Business

Tyler Maginnis | February 25, 2024

AWSElastic-BeanstalkdeploymentPaaSautomation

Need Professional AWS Solutions?

Get expert assistance with your aws solutions implementation and management. Tyler on Tech Louisville provides priority support for Louisville businesses.

Same-day service available for Louisville area

AWS Elastic Beanstalk Deployment Guide: Simplified Application Hosting for Small Business

AWS Elastic Beanstalk provides an easy-to-use service for deploying and scaling web applications without worrying about the underlying infrastructure. This comprehensive guide helps small businesses leverage Beanstalk's platform-as-a-service capabilities for rapid, reliable application deployment.

Elastic Beanstalk Fundamentals

Understanding Beanstalk's architecture enables effective application deployment and management.

Core Elastic Beanstalk Components

  • Applications: Logical collection of Beanstalk components
  • Application Versions: Specific iterations of your code
  • Environments: Resources running an application version
  • Environment Tiers: Web servers or workers
  • Platforms: Pre-configured templates (Node.js, Python, Java, etc.)

Choosing the Right Platform

Supported Platforms

Select the appropriate runtime:

Platform Versions Use Cases
Node.js 14.x, 16.x, 18.x JavaScript applications, APIs
Python 3.8, 3.9, 3.10 Django, Flask applications
Java Corretto 8, 11, 17 Spring Boot, enterprise apps
PHP 7.4, 8.0, 8.1 WordPress, Laravel
Ruby 2.7, 3.0 Rails applications
.NET Core on Linux Cross-platform .NET apps
Docker Multi/Single Container Containerized applications
Go 1.x Microservices, APIs

Creating Your First Application

Initial Setup

Deploy a sample application:

# Install EB CLI
pip install awsebcli

# Initialize application
eb init my-app --platform python-3.9

# Create environment
eb create production-env --instance-type t3.micro

# Deploy application
eb deploy

# Open in browser
eb open

Application Structure

Organize your project:

my-app/
├── .ebextensions/
   ├── 01_packages.config
   ├── 02_python.config
   └── 03_apache.config
├── .elasticbeanstalk/
   └── config.yml
├── application.py
├── requirements.txt
└── .gitignore

Configuration Management

Environment Configuration

.ebextensions/environment.config:

option_settings:
  aws:elasticbeanstalk:application:environment:
    DATABASE_URL: "postgresql://user:pass@rds-endpoint:5432/dbname"
    REDIS_URL: "redis://elasticache-endpoint:6379"
    APP_ENV: "production"
    DEBUG: "false"

  aws:autoscaling:launchconfiguration:
    InstanceType: t3.medium
    EC2KeyName: my-key-pair

  aws:autoscaling:asg:
    MinSize: 2
    MaxSize: 10

  aws:elasticbeanstalk:environment:
    ServiceRole: aws-elasticbeanstalk-service-role
    EnvironmentType: LoadBalanced

Platform-Specific Settings

Python configuration example:

# .ebextensions/python.config
option_settings:
  aws:elasticbeanstalk:container:python:
    WSGIPath: application.py
    NumProcesses: 3
    NumThreads: 20

commands:
  01_migrate:
    command: "source /var/app/venv/*/bin/activate && python manage.py migrate"
    leader_only: true

  02_collectstatic:
    command: "source /var/app/venv/*/bin/activate && python manage.py collectstatic --noinput"

Deployment Strategies

Rolling Deployments

Configure zero-downtime updates:

option_settings:
  aws:elasticbeanstalk:command:
    DeploymentPolicy: Rolling
    BatchSizeType: Percentage
    BatchSize: 25

  aws:autoscaling:updatepolicy:rollingupdate:
    RollingUpdateEnabled: true
    MaxBatchSize: 1
    MinInstancesInService: 1
    RollingUpdateType: Health
    Timeout: PT30M

Blue/Green Deployments

Safe deployment approach:

# Clone environment
eb clone production-env --clone-name staging-env

# Deploy to staging
eb deploy staging-env

# Test staging environment
# If successful, swap CNAMEs
eb swap production-env --destination-name staging-env

Load Balancing Configuration

Application Load Balancer

Advanced routing setup:

# .ebextensions/alb.config
option_settings:
  aws:elasticbeanstalk:environment:process:default:
    Port: 80
    Protocol: HTTP
    HealthCheckPath: /health
    HealthCheckIntervalSeconds: 15
    HealthCheckTimeoutSeconds: 5
    HealthyThresholdCount: 3
    UnhealthyThresholdCount: 5

  aws:elbv2:listener:443:
    Protocol: HTTPS
    SSLCertificateArns: arn:aws:acm:region:account:certificate/cert-id

  aws:elbv2:listener:80:
    Protocol: HTTP
    Rules: redirect

Path-Based Routing

Route to different services:

# .ebextensions/alb-rules.config
Resources:
  AWSEBV2LoadBalancerListenerRule:
    Type: AWS::ElasticLoadBalancingV2::ListenerRule
    Properties:
      Actions:
        - Type: forward
          TargetGroupArn:
            Ref: AWSEBV2LoadBalancerTargetGroup
      Conditions:
        - Field: path-pattern
          Values: ["/api/*"]
      ListenerArn:
        Ref: AWSEBV2LoadBalancerListener443
      Priority: 1

Auto Scaling Configuration

Dynamic Scaling Policies

Scale based on metrics:

Resources:
  CPUAlarmHigh:
    Type: AWS::CloudWatch::Alarm
    Properties:
      AlarmDescription: "Scale up when CPU > 70%"
      MetricName: CPUUtilization
      Namespace: AWS/EC2
      Statistic: Average
      Period: 300
      EvaluationPeriods: 2
      Threshold: 70
      ComparisonOperator: GreaterThanThreshold
      AlarmActions:
        - Ref: AWSEBAutoScalingScaleUpPolicy

  CPUAlarmLow:
    Type: AWS::CloudWatch::Alarm
    Properties:
      AlarmDescription: "Scale down when CPU < 30%"
      MetricName: CPUUtilization
      Namespace: AWS/EC2
      Statistic: Average
      Period: 300
      EvaluationPeriods: 2
      Threshold: 30
      ComparisonOperator: LessThanThreshold
      AlarmActions:
        - Ref: AWSEBAutoScalingScaleDownPolicy

Database Integration

RDS Configuration

Connect to managed database:

# .ebextensions/rds.config
Resources:
  AWSEBRDSDatabase:
    Type: AWS::RDS::DBInstance
    Properties:
      DBInstanceIdentifier: my-app-db
      AllocatedStorage: 20
      DBInstanceClass: db.t3.micro
      Engine: postgres
      EngineVersion: 13.7
      MasterUsername: dbadmin
      MasterUserPassword: !Ref DBPassword
      DBName: myapp
      MultiAZ: true
      StorageEncrypted: true

Parameters:
  DBPassword:
    NoEcho: true
    Type: AWS::SSM::Parameter::Value<String>
    Default: /myapp/db/password

Monitoring and Logging

CloudWatch Integration

Enhanced monitoring setup:

# .ebextensions/cloudwatch.config
option_settings:
  aws:elasticbeanstalk:cloudwatch:logs:
    StreamLogs: true
    DeleteOnTerminate: false
    RetentionInDays: 30

  aws:elasticbeanstalk:healthreporting:system:
    SystemType: enhanced
    EnhancedHealthAuthEnabled: true

files:
  "/opt/aws/amazon-cloudwatch-agent/etc/custom_logs.json":
    content: |
      {
        "logs": {
          "logs_collected": {
            "files": {
              "collect_list": [
                {
                  "file_path": "/var/log/app/custom.log",
                  "log_group_name": "/aws/elasticbeanstalk/my-app/custom",
                  "log_stream_name": "{instance_id}"
                }
              ]
            }
          }
        }
      }

Application Metrics

Custom metric publishing:

import boto3
import time

cloudwatch = boto3.client('cloudwatch')

def publish_metric(metric_name, value, unit='Count'):
    cloudwatch.put_metric_data(
        Namespace='MyApp',
        MetricData=[{
            'MetricName': metric_name,
            'Value': value,
            'Unit': unit,
            'Timestamp': time.time()
        }]
    )

# Usage
publish_metric('OrdersProcessed', order_count)
publish_metric('ResponseTime', response_time, 'Milliseconds')

Security Best Practices

Environment Security

Implement security controls:

# .ebextensions/security.config
commands:
  01_security_updates:
    command: "yum update -y --security"

option_settings:
  aws:autoscaling:launchconfiguration:
    IamInstanceProfile: aws-elasticbeanstalk-ec2-role
    SecurityGroups: sg-restricted-access

  aws:elasticbeanstalk:application:environment:
    AWS_REGION: us-east-1

files:
  "/etc/httpd/conf.d/security.conf":
    content: |
      ServerTokens Prod
      ServerSignature Off
      Header always set X-Frame-Options "SAMEORIGIN"
      Header always set X-Content-Type-Options "nosniff"
      Header always set X-XSS-Protection "1; mode=block"

Secrets Management

Secure sensitive data:

# Reference secrets from Parameter Store
option_settings:
  aws:elasticbeanstalk:application:environment:
    DATABASE_PASSWORD: '{{resolve:ssm:/myapp/db/password:1}}'
    API_KEY: '{{resolve:secretsmanager:myapp/api-key:SecretString:key}}'

Container Deployment

Docker Configuration

Multi-container setup:

{
  "AWSEBDockerrunVersion": 2,
  "containerDefinitions": [
    {
      "name": "web",
      "image": "my-app:latest",
      "memory": 512,
      "essential": true,
      "portMappings": [
        {
          "hostPort": 80,
          "containerPort": 8000
        }
      ],
      "environment": [
        {
          "name": "APP_ENV",
          "value": "production"
        }
      ]
    },
    {
      "name": "worker",
      "image": "my-worker:latest",
      "memory": 256,
      "essential": false
    }
  ]
}

Cost Optimization

Resource Optimization

Reduce Beanstalk costs:

Strategies:
  1. Use Spot Instances:
     - Save up to 90% on compute
     - Good for non-critical environments

  2. Right-size instances:
     - Monitor actual usage
     - Adjust instance types

  3. Scheduled scaling:
     - Scale down during off-hours
     - Weekend/holiday schedules

  4. Reserved instances:
     - For production workloads
     - 1 or 3-year commitments

Environment Management

# Stop development environments when not in use
eb terminate dev-env --force

# Use saved configurations
eb config save production-config
eb create new-env --cfg production-config

Troubleshooting

Common Issues

Debug deployment problems:

# View recent logs
eb logs

# SSH into instance
eb ssh

# Check application health
eb health

# View environment events
eb events -f

# Abort stuck deployment
eb abort

Log Analysis

Find root causes:

# Download full logs
eb logs --zip

# Common log locations:
# /var/log/eb-engine.log - Deployment logs
# /var/log/web.stdout.log - Application output
# /var/log/nginx/error.log - Web server errors

CI/CD Integration

GitHub Actions Example

name: Deploy to Elastic Beanstalk

on:
  push:
    branches: [main]

jobs:
  deploy:
    runs-on: ubuntu-latest

    steps:
    - uses: actions/checkout@v2

    - name: Create ZIP deployment package
      run: zip -r deploy.zip . -x '*.git*'

    - name: Deploy to EB
      uses: einaregilsson/beanstalk-deploy@v20
      with:
        aws_access_key: ${{ secrets.AWS_ACCESS_KEY_ID }}
        aws_secret_key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
        application_name: my-app
        environment_name: production-env
        version_label: ${{ github.sha }}
        region: us-east-1
        deployment_package: deploy.zip

Best Practices Summary

  1. Use Configuration Files: Store all settings in .ebextensions
  2. Implement Health Checks: Ensure reliable deployments
  3. Monitor Everything: Use enhanced health reporting
  4. Secure by Default: Apply security headers and policies
  5. Automate Deployments: Integrate with CI/CD pipelines

Conclusion

AWS Elastic Beanstalk simplifies application deployment while providing the flexibility to customize when needed. By following these deployment strategies and best practices, small businesses can achieve enterprise-grade application hosting without the complexity of managing infrastructure.

For professional Elastic Beanstalk deployment and application hosting services in Louisville, contact Tyler on Tech Louisville to streamline your application deployment process and ensure reliable, scalable hosting solutions.