AWS for DevOps
Learn AWS DevOps services: ALB, Auto Scaling, ECS, EKS, CodePipeline, CloudFormation, and container orchestration on AWS.
Learn AWS DevOps services: ALB, Auto Scaling, ECS, EKS, CodePipeline, CloudFormation, and container orchestration on AWS. This hands-on tutorial focuses on practical implementation of aws for devops concepts.
AWS for DevOps
AWS provides a comprehensive suite of services for DevOps practices including container orchestration, CI/CD, and infrastructure management.
Application Load Balancer (ALB)
Layer 7 load balancer with content-based routing.
ALB Features
- Content-based routing: Path, host, headers, query strings
- WebSocket support: Native WebSocket and HTTP/2
- Health checks: HTTP/HTTPS health checks
- SSL/TLS termination: Centralized certificate management
- Integration: ECS, EKS, Lambda, EC2
ALB Configuration
# CloudFormation
AWSTemplateFormatVersion: '2010-09-09'
Resources:
ALB:
Type: AWS::ElasticLoadBalancingV2::LoadBalancer
Properties:
Name: my-alb
Scheme: internet-facing
Type: application
SecurityGroups:
- !Ref ALBSecurityGroup
Subnets:
- !Ref PublicSubnet1
- !Ref PublicSubnet2
ALBListener:
Type: AWS::ElasticLoadBalancingV2::Listener
Properties:
LoadBalancerArn: !Ref ALB
Port: 443
Protocol: HTTPS
Certificates:
- CertificateArn: !Ref CertificateArn
DefaultActions:
- Type: forward
TargetGroupArn: !Ref DefaultTargetGroup
APIPathRule:
Type: AWS::ElasticLoadBalancingV2::ListenerRule
Properties:
ListenerArn: !Ref ALBListener
Priority: 1
Conditions:
- Field: path-pattern
PathPatternConfig:
Values:
- /api/*
Actions:
- Type: forward
TargetGroupArn: !Ref APITargetGroup
# AWS CLI
aws elbv2 create-load-balancer \
--name my-alb \
--subnets subnet-123 subnet-456 \
--security-groups sg-123
aws elbv2 create-target-group \
--name my-tg \
--protocol HTTP \
--port 80 \
--vpc-id vpc-123 \
--health-check-path /health
aws elbv2 register-targets \
--target-group-arn arn:aws:elasticloadbalancing:... \
--targets Id=i-123 Id=i-456
ECS (Elastic Container Service)
AWS container orchestration service.
ECS Launch Types
- EC2: Run containers on EC2 instances you manage
- Fargate: Serverless container compute
- External: On-premises containers
ECS Task Definition
{
"family": "web-app",
"networkMode": "awsvpc",
"requiresCompatibilities": ["FARGATE"],
"cpu": "256",
"memory": "512",
"executionRoleArn": "arn:aws:iam::123456789:role/ecsTaskExecutionRole",
"taskRoleArn": "arn:aws:iam::123456789:role/ecsTaskRole",
"containerDefinitions": [
{
"name": "web",
"image": "nginx:alpine",
"portMappings": [
{
"containerPort": 80,
"protocol": "tcp"
}
],
"environment": [
{
"name": "ENVIRONMENT",
"value": "production"
}
],
"secrets": [
{
"name": "DB_PASSWORD",
"valueFrom": "arn:aws:secretsmanager:...:secret:db-password"
}
],
"logConfiguration": {
"logDriver": "awslogs",
"options": {
"awslogs-group": "/ecs/web-app",
"awslogs-region": "us-east-1",
"awslogs-stream-prefix": "ecs"
}
},
"healthCheck": {
"command": ["CMD-SHELL", "curl -f http://localhost/ || exit 1"],
"interval": 30,
"timeout": 5,
"retries": 3,
"startPeriod": 60
}
}
]
}
ECS Service
# Create cluster
aws ecs create-cluster --cluster-name production
# Register task definition
aws ecs register-task-definition --cli-input-json file://task-definition.json
# Create service
aws ecs create-service \
--cluster production \
--service-name web-service \
--task-definition web-app:1 \
--desired-count 2 \
--launch-type FARGATE \
--network-configuration "awsvpcConfiguration={subnets=[subnet-123],securityGroups=[sg-123],assignPublicIp=ENABLED}" \
--load-balancers "targetGroupArn=arn:aws:elasticloadbalancing:...,containerName=web,containerPort=80"
# Update service
aws ecs update-service \
--cluster production \
--service-name web-service \
--task-definition web-app:2 \
--force-new-deployment
EKS (Elastic Kubernetes Service)
Managed Kubernetes service on AWS.
EKS Cluster Creation
# Create cluster
aws eks create-cluster \
--name production \
--role-arn arn:aws:iam::123456789:role/eks-cluster-role \
--resources-vpc-config subnetIds=subnet-123,subnet-456,securityGroupIds=sg-123
# Update kubeconfig
aws eks update-kubeconfig --region us-east-1 --name production
# Create managed node group
aws eks create-nodegroup \
--cluster-name production \
--nodegroup-name standard-workers \
--node-role arn:aws:iam::123456789:role/eks-node-role \
--subnets subnet-123 \
--scaling-config minSize=2,maxSize=10,desiredSize=3 \
--instance-types t3.medium \
--ami-type AL2_x86_64
EKS with eksctl (Recommended)
# Create cluster
eksctl create cluster \
--name production \
--region us-east-1 \
--node-type t3.medium \
--nodes 3 \
--nodes-min 2 \
--nodes-max 10 \
--managed
# Add node group
eksctl create nodegroup \
--cluster production \
--name spot-workers \
--node-type t3.medium \
--nodes-min 1 \
--nodes-max 20 \
--spot
# Enable addons
eksctl utils update-aws-node --cluster production --approve
eksctl utils update-coredns --cluster production --approve
eksctl utils update-kube-proxy --cluster production --approve
EKS Fargate
# Create Fargate profile
eksctl create fargateprofile \
--cluster production \
--name fp-default \
--namespace default
# Namespace with Fargate
eksctl create fargateprofile \
--cluster production \
--name fp-apps \
--namespace apps \
--labels app=backend
AWS CI/CD Services
CodePipeline
# CloudFormation
Pipeline:
Type: AWS::CodePipeline::Pipeline
Properties:
Name: my-pipeline
RoleArn: !Ref PipelineRole
ArtifactStore:
Type: S3
Location: !Ref ArtifactBucket
Stages:
- Name: Source
Actions:
- Name: GitHubSource
ActionTypeId:
Category: Source
Owner: ThirdParty
Provider: GitHub
Version: 1
Configuration:
Owner: myorg
Repo: myrepo
Branch: main
OAuthToken: '{{resolve:secretsmanager:github-token:SecretString:token}}'
OutputArtifacts:
- Name: SourceCode
- Name: Build
Actions:
- Name: CodeBuild
ActionTypeId:
Category: Build
Owner: AWS
Provider: CodeBuild
Version: 1
Configuration:
ProjectName: !Ref CodeBuildProject
InputArtifacts:
- Name: SourceCode
OutputArtifacts:
- Name: BuildArtifact
- Name: Deploy
Actions:
- Name: ECSDeploy
ActionTypeId:
Category: Deploy
Owner: AWS
Provider: ECS
Version: 1
Configuration:
ClusterName: production
ServiceName: web-service
FileName: imagedefinitions.json
InputArtifacts:
- Name: BuildArtifact
CodeBuild
CodeBuildProject:
Type: AWS::CodeBuild::Project
Properties:
Name: my-project
ServiceRole: !Ref CodeBuildRole
Artifacts:
Type: CODEPIPELINE
Environment:
Type: LINUX_CONTAINER
ComputeType: BUILD_GENERAL1_SMALL
Image: aws/codebuild/standard:5.0
PrivilegedMode: true
EnvironmentVariables:
- Name: AWS_DEFAULT_REGION
Value: us-east-1
- Name: IMAGE_REPO_NAME
Value: myapp
- Name: IMAGE_TAG
Value: latest
Source:
Type: CODEPIPELINE
BuildSpec: |
version: 0.2
phases:
pre_build:
commands:
- echo Logging in to Amazon ECR...
- aws ecr get-login-password | docker login --username AWS --password-stdin $AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com
build:
commands:
- echo Build started on `date`
- echo Building the Docker image...
- docker build -t $IMAGE_REPO_NAME:$IMAGE_TAG .
- docker tag $IMAGE_REPO_NAME:$IMAGE_TAG $AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com/$IMAGE_REPO_NAME:$IMAGE_TAG
post_build:
commands:
- echo Build completed on `date`
- echo Pushing the Docker image...
- docker push $AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com/$IMAGE_REPO_NAME:$IMAGE_TAG
- printf '[{"name":"web","imageUri":"%s"}]' $AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com/$IMAGE_REPO_NAME:$IMAGE_TAG > imagedefinitions.json
artifacts:
files: imagedefinitions.json
CloudFormation
Infrastructure as Code for AWS.
Template Structure
AWSTemplateFormatVersion: '2010-09-09'
Description: 'Complete VPC with public and private subnets'
Parameters:
Environment:
Type: String
Default: production
AllowedValues:
- development
- staging
- production
VpcCidr:
Type: String
Default: 10.0.0.0/16
Description: CIDR block for VPC
Mappings:
RegionMap:
us-east-1:
AMI: ami-0c55b159cbfafe1f0
us-west-2:
AMI: ami-0c55b159cbfafe1f0
Resources:
VPC:
Type: AWS::EC2::VPC
Properties:
CidrBlock: !Ref VpcCidr
EnableDnsHostnames: true
EnableDnsSupport: true
Tags:
- Key: Name
Value: !Sub ${Environment}-vpc
InternetGateway:
Type: AWS::EC2::InternetGateway
Properties:
Tags:
- Key: Name
Value: !Sub ${Environment}-igw
AttachGateway:
Type: AWS::EC2::VPCGatewayAttachment
Properties:
VpcId: !Ref VPC
InternetGatewayId: !Ref InternetGateway
Outputs:
VPCId:
Description: VPC ID
Value: !Ref VPC
Export:
Name: !Sub ${Environment}-vpc-id
VPCCidr:
Description: VPC CIDR
Value: !GetAtt VPC.CidrBlock
CloudFormation Commands
# Create stack
aws cloudformation create-stack \
--stack-name my-vpc \
--template-body file://vpc.yaml \
--parameters ParameterKey=Environment,ParameterValue=production
# Update stack
aws cloudformation update-stack \
--stack-name my-vpc \
--template-body file://vpc.yaml
# Delete stack
aws cloudformation delete-stack --stack-name my-vpc
# Drift detection
aws cloudformation detect-stack-drift --stack-name my-vpc
# Stacksets (multi-account)
aws cloudformation create-stack-set \
--stack-set-name my-baseline \
--template-body file://baseline.yaml
AWS Systems Manager (SSM)
Manage EC2 and on-premises servers at scale.
# Run command on instances
aws ssm send-command \
--document-name "AWS-RunShellScript" \
--targets "Key=instanceids,Values=i-1234567890abcdef0" \
--parameters 'commands=["yum update -y", "systemctl restart nginx"]'
# Session Manager (secure shell without bastion)
aws ssm start-session --target i-1234567890abcdef0
# Parameter Store
aws ssm put-parameter \
--name /production/database/password \
--value mysecretpassword \
--type SecureString
aws ssm get-parameter \
--name /production/database/password \
--with-decryption
# Patch Manager
aws ssm create-patch-baseline \
--name ProductionPatches \
--operating-system AMAZON_LINUX_2 \
--approval-rules PatchRules=[{PatchFilterGroup={PatchFilters=[{Key=SEVERITY,Values=Critical,Important}]}}]
Quiz
Quiz
Question 1 of 5What is the main difference between ECS and EKS?
Next Steps
Now let's explore Infrastructure as Code with Terraform—the industry standard for multi-cloud IaC.