AWS Deployment Strategies

Module 28: DevOps & Deployment - Wednesday, Lecture 2

Introduction to AWS Deployment

Amazon Web Services (AWS) offers a vast array of services for deploying applications of all types and scales. From simple static websites to complex microservices architectures, AWS provides multiple deployment options that can be tailored to your specific requirements.

Think of AWS as a massive toolbox—your job is to select the right tools for your project based on your application's characteristics, your team's skills, and your business requirements. In this lecture, we'll explore various AWS deployment strategies and help you understand when to use each one.

flowchart TD A[AWS Deployment Options] --> B[Compute Services] A --> C[Container Services] A --> D[Serverless Services] A --> E[Platform Services] B --> B1[EC2] B --> B2[Lightsail] C --> C1[ECS] C --> C2[EKS] C --> C3[App Runner] D --> D1[Lambda] D --> D2[Fargate] E --> E1[Elastic Beanstalk] E --> E2[Amplify]

By the end of this lecture, you'll understand the various AWS deployment options and be able to choose the most appropriate strategy for your applications.

Key AWS Services for Deployment

Compute Services

These services provide the fundamental computing resources for running your applications.

EC2 (Elastic Compute Cloud)

Lightsail

Container Services

These services help you deploy and manage containerized applications.

ECS (Elastic Container Service)

EKS (Elastic Kubernetes Service)

App Runner

Serverless Services

These services let you run code without provisioning or managing servers.

Lambda

Fargate

Platform Services

These services provide a platform for deploying applications with minimal infrastructure management.

Elastic Beanstalk

Amplify

AWS Deployment Strategies

Strategy 1: Traditional EC2 Deployment

Deploying applications directly to EC2 instances provides maximum control but requires more management.

graph LR A[Code Repository] --> B[CI/CD Pipeline] B --> C[Artifacts] C --> D[EC2 Instances] D --> E[Load Balancer] E --> F[Route 53] F --> G[Users]

Key Components

Deployment Process

# Example deployment script for EC2
# Create an AMI with your application
aws ec2 create-image --instance-id i-1234567890abcdef0 --name "MyApp-v1.0" --description "My application version 1.0"

# Launch new instances with the AMI
aws ec2 run-instances --image-id ami-12345678 --count 3 --instance-type t3.medium --key-name MyKeyPair --security-group-ids sg-12345678

# Register instances with load balancer
aws elbv2 register-targets --target-group-arn arn:aws:elasticloadbalancing:us-west-2:123456789012:targetgroup/my-targets/73e2d6bc24d8a067 --targets Id=i-1234567890abcdef0 Id=i-0598c7d356eba48d7

When to Use

Strategy 2: Elastic Beanstalk

Elastic Beanstalk simplifies deployment by handling infrastructure provisioning and management.

graph LR A[Application Code] --> B[Elastic Beanstalk] B --> C[Auto Scaling Group] B --> D[Load Balancer] B --> E[Environment Configuration] C --> F[EC2 Instances]

Key Components

Deployment Process

# Example Elastic Beanstalk deployment
# Initialize a new Elastic Beanstalk application
eb init -p node.js MyApplication

# Create a new environment
eb create production-environment

# Deploy a new version
eb deploy

# Configure environment variables
eb setenv NODE_ENV=production DB_HOST=mydb.123456789012.us-west-2.rds.amazonaws.com

When to Use

Strategy 3: Container-Based Deployment (ECS/EKS)

Container-based deployments provide consistency across environments and efficient resource utilization.

graph TD A[Container Registry
ECR] --> B[ECS Cluster] A --> C[EKS Cluster] B --> D[ECS Service] D --> E[ECS Tasks] E --> F[Containers] C --> G[Kubernetes Deployments] G --> H[Kubernetes Pods] H --> I[Containers] J[Load Balancer] --> D J --> G

ECS Deployment

# Example ECS deployment
# Build and push Docker image to ECR
docker build -t myapp:latest .
aws ecr get-login-password --region us-west-2 | docker login --username AWS --password-stdin 123456789012.dkr.ecr.us-west-2.amazonaws.com
docker tag myapp:latest 123456789012.dkr.ecr.us-west-2.amazonaws.com/myapp:latest
docker push 123456789012.dkr.ecr.us-west-2.amazonaws.com/myapp:latest

# Update ECS service with new image
aws ecs update-service --cluster my-cluster --service my-service --force-new-deployment

EKS Deployment

# Example Kubernetes deployment for EKS
apiVersion: apps/v1
kind: Deployment
metadata:
  name: myapp
spec:
  replicas: 3
  selector:
    matchLabels:
      app: myapp
  template:
    metadata:
      labels:
        app: myapp
    spec:
      containers:
      - name: myapp
        image: 123456789012.dkr.ecr.us-west-2.amazonaws.com/myapp:latest
        ports:
        - containerPort: 80
        resources:
          limits:
            cpu: "1"
            memory: "1Gi"
          requests:
            cpu: "0.5"
            memory: "512Mi"

When to Use

Strategy 4: Serverless Deployment

Serverless deployments abstract away infrastructure management completely, allowing you to focus solely on code.

graph TD A[Code Repository] --> B[CI/CD Pipeline] B --> C[AWS Lambda] C --> D[API Gateway] D --> E[CloudFront] E --> F[Users] G[S3] --> E H[DynamoDB] <--> C

Lambda Deployment

# Example Lambda deployment using AWS SAM
# Define resources in template.yaml
cat > template.yaml << EOF
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Resources:
  MyFunction:
    Type: AWS::Serverless::Function
    Properties:
      Handler: index.handler
      Runtime: nodejs16.x
      CodeUri: ./
      Events:
        ApiEvent:
          Type: Api
          Properties:
            Path: /hello
            Method: get
EOF

# Build and deploy
sam build
sam deploy --guided

Amplify Deployment

# Example Amplify deployment for a React app
# Initialize Amplify project
amplify init

# Add API
amplify add api

# Push changes to AWS
amplify push

# Deploy frontend
amplify publish

When to Use

AWS Deployment Considerations

Infrastructure as Code (IaC)

Using IaC tools to define and provision AWS infrastructure ensures consistency and reproducibility.

AWS CloudFormation

# Example CloudFormation template
AWSTemplateFormatVersion: '2010-09-09'
Resources:
  WebAppInstance:
    Type: AWS::EC2::Instance
    Properties:
      InstanceType: t3.micro
      ImageId: ami-0abcdef1234567890
      SecurityGroups:
        - !Ref WebServerSecurityGroup
      UserData:
        Fn::Base64: !Sub |
          #!/bin/bash -xe
          yum update -y
          yum install -y httpd
          systemctl start httpd
          systemctl enable httpd

  WebServerSecurityGroup:
    Type: AWS::EC2::SecurityGroup
    Properties:
      GroupDescription: Enable HTTP access
      SecurityGroupIngress:
        - IpProtocol: tcp
          FromPort: 80
          ToPort: 80
          CidrIp: 0.0.0.0/0

AWS CDK (Cloud Development Kit)

# Example CDK code in TypeScript
import * as cdk from 'aws-cdk-lib';
import * as ec2 from 'aws-cdk-lib/aws-ec2';
import * as ecs from 'aws-cdk-lib/aws-ecs';
import * as ecr from 'aws-cdk-lib/aws-ecr';

export class MyEcsStack extends cdk.Stack {
  constructor(scope: cdk.Construct, id: string, props?: cdk.StackProps) {
    super(scope, id, props);

    // Create a VPC
    const vpc = new ec2.Vpc(this, 'MyVpc', {
      maxAzs: 2
    });

    // Create an ECS Cluster
    const cluster = new ecs.Cluster(this, 'MyCluster', {
      vpc: vpc
    });

    // Create a Task Definition
    const taskDefinition = new ecs.FargateTaskDefinition(this, 'MyTaskDef');

    // Add container to task definition
    taskDefinition.addContainer('MyContainer', {
      image: ecs.ContainerImage.fromRegistry('amazon/amazon-ecs-sample'),
      memoryLimitMiB: 512,
      cpu: 256,
      portMappings: [{ containerPort: 80 }]
    });

    // Create a Fargate Service
    new ecs.FargateService(this, 'MyService', {
      cluster,
      taskDefinition,
      desiredCount: 2
    });
  }
}

Terraform

# Example Terraform configuration
provider "aws" {
  region = "us-west-2"
}

resource "aws_instance" "web_server" {
  ami           = "ami-0abcdef1234567890"
  instance_type = "t3.micro"
  
  vpc_security_group_ids = [aws_security_group.web.id]
  
  user_data = <<-EOF
              #!/bin/bash
              yum update -y
              yum install -y httpd
              systemctl start httpd
              systemctl enable httpd
              EOF
  
  tags = {
    Name = "WebServer"
  }
}

resource "aws_security_group" "web" {
  name        = "web-server-sg"
  description = "Allow HTTP traffic"
  
  ingress {
    from_port   = 80
    to_port     = 80
    protocol    = "tcp"
    cidr_blocks = ["0.0.0.0/0"]
  }
  
  egress {
    from_port   = 0
    to_port     = 0
    protocol    = "-1"
    cidr_blocks = ["0.0.0.0/0"]
  }
}

Continuous Integration/Continuous Deployment (CI/CD)

Implementing CI/CD pipelines automates the testing and deployment process, enabling faster and more reliable releases.

graph LR A[Code Repository] --> B[AWS CodePipeline] B --> C[AWS CodeBuild] C --> D[AWS CodeDeploy] D --> E[Production Environment]

AWS CodePipeline Configuration

{
  "pipeline": {
    "name": "MyAppPipeline",
    "roleArn": "arn:aws:iam::123456789012:role/CodePipelineServiceRole",
    "artifactStore": {
      "type": "S3",
      "location": "my-pipeline-artifacts"
    },
    "stages": [
      {
        "name": "Source",
        "actions": [
          {
            "name": "Source",
            "actionTypeId": {
              "category": "Source",
              "owner": "AWS",
              "provider": "CodeStarSourceConnection",
              "version": "1"
            },
            "configuration": {
              "ConnectionArn": "arn:aws:codestar-connections:us-west-2:123456789012:connection/my-connection",
              "FullRepositoryId": "my-username/my-repo",
              "BranchName": "main"
            },
            "outputArtifacts": [
              {
                "name": "SourceCode"
              }
            ]
          }
        ]
      },
      {
        "name": "Build",
        "actions": [
          {
            "name": "BuildAction",
            "actionTypeId": {
              "category": "Build",
              "owner": "AWS",
              "provider": "CodeBuild",
              "version": "1"
            },
            "configuration": {
              "ProjectName": "MyBuildProject"
            },
            "inputArtifacts": [
              {
                "name": "SourceCode"
              }
            ],
            "outputArtifacts": [
              {
                "name": "BuildOutput"
              }
            ]
          }
        ]
      },
      {
        "name": "Deploy",
        "actions": [
          {
            "name": "DeployAction",
            "actionTypeId": {
              "category": "Deploy",
              "owner": "AWS",
              "provider": "ElasticBeanstalk",
              "version": "1"
            },
            "configuration": {
              "ApplicationName": "MyApplication",
              "EnvironmentName": "MyApplication-Production"
            },
            "inputArtifacts": [
              {
                "name": "BuildOutput"
              }
            ]
          }
        ]
      }
    ]
  }
}

Configuration Management

Managing application configuration across different environments is critical for successful deployments.

AWS Systems Manager Parameter Store

# Store a parameter
aws ssm put-parameter \
    --name "/myapp/production/database-url" \
    --value "mysql://user:password@db.example.com:3306/mydb" \
    --type SecureString

# Retrieve a parameter
aws ssm get-parameter \
    --name "/myapp/production/database-url" \
    --with-decryption

AWS Secrets Manager

# Store a secret
aws secretsmanager create-secret \
    --name "myapp/db-credentials" \
    --description "Database credentials for MyApp" \
    --secret-string '{"username":"admin","password":"t0p-s3cr3t"}'

# Retrieve a secret
aws secretsmanager get-secret-value \
    --secret-id "myapp/db-credentials"

Monitoring and Logging

Setting up proper monitoring and logging ensures you can detect and diagnose issues quickly.

AWS CloudWatch

# Create a CloudWatch alarm for high CPU utilization
aws cloudwatch put-metric-alarm \
    --alarm-name "HighCPUUtilization" \
    --comparison-operator GreaterThanThreshold \
    --evaluation-periods 2 \
    --metric-name CPUUtilization \
    --namespace AWS/EC2 \
    --period 300 \
    --statistic Average \
    --threshold 70 \
    --alarm-description "Alarm when CPU exceeds 70%" \
    --dimensions "Name=InstanceId,Value=i-1234567890abcdef0" \
    --alarm-actions arn:aws:sns:us-west-2:123456789012:MyTopic

AWS X-Ray

// Tracing a Node.js application with X-Ray
const AWSXRay = require('aws-xray-sdk');
const express = require('express');

// Capture all incoming HTTP requests
const app = express();
app.use(AWSXRay.express.openSegment('MyApp'));

app.get('/', function (req, res) {
  res.send('Hello World!');
});

// Close the segment
app.use(AWSXRay.express.closeSegment());

app.listen(3000);

Real-World AWS Deployment Examples

Example 1: E-Commerce Application

A multi-tier e-commerce application using AWS services for different components.

graph TD A[CloudFront] --> B[S3 - Static Content] A --> C[ALB - Application Load Balancer] C --> D[ECS Fargate - Frontend Service] C --> E[ECS Fargate - API Service] E --> F[RDS - Database] E --> G[ElastiCache - Redis] E --> H[SQS - Message Queue] H --> I[Lambda - Order Processing] I --> J[DynamoDB - Order History]

Deployment Strategy: Containerized microservices with ECS Fargate for compute workloads, combined with managed services for databases and caching.

Key AWS Services:

Example 2: Content Management System

A CMS deployed with Elastic Beanstalk for simplicity and managed services.

graph TD A[Route 53] --> B[CloudFront] B --> C[Elastic Beanstalk Environment] C --> D[RDS - MySQL] C --> E[S3 - Media Storage] C --> F[ElastiCache - Redis] G[CodePipeline] --> C

Deployment Strategy: PaaS approach using Elastic Beanstalk to minimize infrastructure management.

Key AWS Services:

Example 3: Serverless Web Application

A modern web application built entirely on serverless architecture.

graph TD A[CloudFront] --> B[S3 - Static Website] A --> C[API Gateway] C --> D[Lambda Functions] D --> E[DynamoDB] D --> F[S3 - File Storage] G[Cognito] --> C H[AWS Amplify] --> B

Deployment Strategy: Fully serverless architecture with no server management required.

Key AWS Services:

Practical Exercise: AWS Deployment Plan

Scenario

You're tasked with planning the AWS deployment for a new web application with the following components:

Exercise Tasks

  1. Select the most appropriate AWS services for each component
  2. Design the architecture with a diagram
  3. Choose a deployment strategy
  4. Outline the CI/CD pipeline
  5. Consider monitoring and scaling approaches

Example Solution Outline

Component Selection

Architecture Diagram

graph TD A[Route 53] --> B[CloudFront] B --> C[S3 - Frontend] B --> D[ALB] D --> E[Elastic Beanstalk - Node.js API] E --> F[DocumentDB] E --> G[S3 - Images] G --> H[Lambda - Image Processing] I[Cognito] --> E J[CloudWatch] --> E & H K[CodePipeline] --> C & E

Deployment Strategy

Use a hybrid approach:

CI/CD Pipeline

Monitoring and Scaling

Complete this exercise for your specific application requirements, considering factors like budget, expected traffic patterns, and team expertise.

AWS Deployment Best Practices

Security Best Practices

Cost Optimization

Reliability and High Availability

Performance Efficiency

Operational Excellence

Conclusion

AWS offers a rich ecosystem of services for deploying applications of all types and scales. The key to successful AWS deployment is selecting the right combination of services that align with your application requirements, team skills, and business objectives.

Key takeaways from this lecture include:

In our next lecture, we'll explore deploying applications to Heroku, a platform that offers a simpler alternative to AWS for many web applications.

Additional Resources