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.
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)
- What it is: Virtual servers in the cloud
- Best for: Applications requiring full control over the computing environment
- Key features: Multiple instance types, auto-scaling, spot instances, reserved instances
- Use case: Custom applications, legacy applications, applications with specific OS requirements
Lightsail
- What it is: Simplified virtual private servers
- Best for: Simple web applications, development/test environments
- Key features: Fixed pricing, simplified management, pre-configured applications
- Use case: WordPress sites, simple web applications, small business websites
Container Services
These services help you deploy and manage containerized applications.
ECS (Elastic Container Service)
- What it is: Managed container orchestration service
- Best for: Docker-based applications that need easy deployment and scaling
- Key features: Task definitions, service auto-scaling, AWS integrations
- Use case: Microservices architectures, batch processing, distributed applications
EKS (Elastic Kubernetes Service)
- What it is: Managed Kubernetes service
- Best for: Applications already using Kubernetes, complex container orchestration
- Key features: Managed control plane, integrated IAM, AWS integrations
- Use case: Large-scale microservices, multi-region deployments, portable container workloads
App Runner
- What it is: Fully managed service for containerized applications
- Best for: Simple container deployments without infrastructure management
- Key features: Automatic scaling, HTTPS endpoints, continuous deployment
- Use case: API services, web applications, microservices with simple scaling needs
Serverless Services
These services let you run code without provisioning or managing servers.
Lambda
- What it is: Event-driven, serverless compute service
- Best for: Event-driven processing, microservices, backend APIs
- Key features: Pay-per-use pricing, automatic scaling, event source integrations
- Use case: Data processing, real-time file processing, backend for web and mobile apps
Fargate
- What it is: Serverless compute engine for containers
- Best for: Containerized applications without server management
- Key features: No server management, per-task pricing, works with ECS and EKS
- Use case: Microservices, batch processing, applications with variable workloads
Platform Services
These services provide a platform for deploying applications with minimal infrastructure management.
Elastic Beanstalk
- What it is: Platform as a Service (PaaS) for web applications
- Best for: Web applications with standard architecture
- Key features: Multiple language support, environment management, auto-scaling
- Use case: Web applications, APIs, applications requiring simple deployment
Amplify
- What it is: Full-stack development and hosting platform
- Best for: Web and mobile applications, especially with React, Angular, or Vue
- Key features: CI/CD workflow, backend generation, authentication, hosting
- Use case: Single-page applications, JAMstack applications, mobile app backends
AWS Deployment Strategies
Strategy 1: Traditional EC2 Deployment
Deploying applications directly to EC2 instances provides maximum control but requires more management.
Key Components
- EC2 Instances: Virtual servers running your application
- Auto Scaling Groups: Automatically adjust the number of instances based on demand
- Elastic Load Balancer: Distribute traffic across instances
- AMI (Amazon Machine Image): Custom image with your application pre-installed
- User Data Scripts: Bootstrap scripts to configure instances at launch
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
- Applications requiring specific OS configurations
- Legacy applications not designed for containers or serverless
- Applications requiring full control over the runtime environment
- When you need specific instance types (e.g., GPU for ML workloads)
Strategy 2: Elastic Beanstalk
Elastic Beanstalk simplifies deployment by handling infrastructure provisioning and management.
Key Components
- Application: Collection of Elastic Beanstalk components
- Application Version: Specific labeled version of deployable code
- Environment: Collection of AWS resources running an application version
- Environment Configuration: Parameters and settings for an environment
- Platform: Operating system, runtime, web server, and Beanstalk 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
- Web applications with standard architectures
- Applications using supported platforms (Node.js, Java, .NET, PHP, Python, Ruby, Go)
- When you want to focus on code rather than infrastructure
- Development and test environments that need to match production
Strategy 3: Container-Based Deployment (ECS/EKS)
Container-based deployments provide consistency across environments and efficient resource utilization.
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
- Microservices architectures
- Applications already containerized
- When you need consistent environments across development, testing, and production
- Applications requiring efficient resource utilization
- ECS: When you prefer AWS-native tools and integrations
- EKS: When you need Kubernetes features or cross-cloud compatibility
Strategy 4: Serverless Deployment
Serverless deployments abstract away infrastructure management completely, allowing you to focus solely on code.
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
- Event-driven applications
- APIs and microservices
- Applications with variable or unpredictable traffic
- When you want to minimize operational overhead
- Applications that can be broken down into small, independent functions
- When pay-per-use pricing is advantageous
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.
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.
Deployment Strategy: Containerized microservices with ECS Fargate for compute workloads, combined with managed services for databases and caching.
Key AWS Services:
- S3 and CloudFront for static content delivery
- ECS Fargate for containerized services
- Application Load Balancer for traffic routing
- RDS for relational database
- ElastiCache for caching
- SQS for message queuing
- Lambda for event processing
- DynamoDB for NoSQL data storage
Example 2: Content Management System
A CMS deployed with Elastic Beanstalk for simplicity and managed services.
Deployment Strategy: PaaS approach using Elastic Beanstalk to minimize infrastructure management.
Key AWS Services:
- Elastic Beanstalk for application hosting
- RDS for database
- S3 for media storage
- ElastiCache for session management
- CloudFront for content delivery
- Route 53 for DNS management
- CodePipeline for CI/CD
Example 3: Serverless Web Application
A modern web application built entirely on serverless architecture.
Deployment Strategy: Fully serverless architecture with no server management required.
Key AWS Services:
- S3 for static website hosting
- CloudFront for content delivery
- API Gateway for API management
- Lambda for backend logic
- DynamoDB for database
- Cognito for authentication
- Amplify for frontend deployment and backend generation
Practical Exercise: AWS Deployment Plan
Scenario
You're tasked with planning the AWS deployment for a new web application with the following components:
- React frontend
- Node.js API backend
- MongoDB database
- Image upload and processing functionality
- User authentication
- Expected initial traffic: 10,000 users/month with potential for growth
Exercise Tasks
- Select the most appropriate AWS services for each component
- Design the architecture with a diagram
- Choose a deployment strategy
- Outline the CI/CD pipeline
- Consider monitoring and scaling approaches
Example Solution Outline
Component Selection
- Frontend: S3 for hosting, CloudFront for content delivery
- Backend API: Elastic Beanstalk for Node.js application
- Database: DocumentDB (MongoDB-compatible database service)
- Image Processing: S3 for storage, Lambda for processing
- Authentication: Amazon Cognito for user management
Architecture Diagram
Deployment Strategy
Use a hybrid approach:
- Static content (React frontend) deployed to S3/CloudFront
- API (Node.js) deployed with Elastic Beanstalk for simplified management
- Managed services for database and authentication
- Serverless approach for image processing with Lambda
CI/CD Pipeline
- AWS CodePipeline for orchestration
- GitHub as the source repository
- CodeBuild for building frontend and backend
- Separate pipelines for frontend and backend
- Automated testing before deployment
- Blue/green deployment for zero-downtime updates
Monitoring and Scaling
- CloudWatch for metrics and logs
- CloudWatch Alarms for alerting
- X-Ray for distributed tracing
- Auto Scaling for Elastic Beanstalk based on CPU and request count
- CloudFront for frontend scaling
- DocumentDB scaling based on CPU utilization
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
- Follow the Principle of Least Privilege: Grant only the permissions necessary for each component
- Use IAM Roles: Avoid hardcoded credentials in your applications
- Enable MFA: Require multi-factor authentication for AWS console access
- Encrypt Data: Use encryption for data at rest and in transit
- Implement Security Groups: Restrict network access to the minimum required
- Regular Security Audits: Use AWS Config and Security Hub for compliance
Cost Optimization
- Right-size Resources: Choose appropriate instance types and sizes
- Use Auto Scaling: Scale resources based on demand
- Consider Reserved Instances: Use for predictable workloads
- Implement Lifecycle Policies: Automatically delete or archive unused resources
- Monitor Costs: Use AWS Cost Explorer and Budgets
- Optimize Storage: Use appropriate storage classes and lifecycle policies
Reliability and High Availability
- Deploy Across Multiple AZs: Mitigate zone failures
- Implement Health Checks: Detect and replace unhealthy resources
- Design for Failure: Assume components will fail and design accordingly
- Implement Circuit Breakers: Prevent cascading failures
- Regular Backups: Backup critical data and test restore procedures
- Disaster Recovery Plan: Prepare for worst-case scenarios
Performance Efficiency
- Use Caching: Implement CloudFront and ElastiCache
- Optimize Database Queries: Use proper indexing and query design
- Implement CDN: Reduce latency for global users
- Use Asynchronous Processing: Decouple components with SQS/SNS
- Monitor Performance: Set up dashboards for key metrics
- Load Testing: Test performance under expected load conditions
Operational Excellence
- Infrastructure as Code: Use CloudFormation or Terraform
- Automated Deployments: Implement CI/CD pipelines
- Comprehensive Monitoring: Monitor all aspects of the application
- Centralized Logging: Aggregate logs for analysis
- Runbooks and Playbooks: Document operational procedures
- Regular Reviews: Continuously improve deployment processes
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:
- Multiple Deployment Options: AWS provides traditional VMs, container services, serverless options, and platform services
- Choose the Right Strategy: Select based on application architecture, team expertise, and operational requirements
- Infrastructure as Code: Use tools like CloudFormation, CDK, or Terraform for reproducible deployments
- CI/CD Automation: Implement automated pipelines for consistent, reliable deployments
- Follow Best Practices: Adhere to security, cost, reliability, performance, and operational best practices
In our next lecture, we'll explore deploying applications to Heroku, a platform that offers a simpler alternative to AWS for many web applications.