Skip to content

Conversation

@sharmaakshay1985
Copy link
Collaborator

AWSTemplateFormatVersion: 2010-09-09

This CloudFormation template deploys docker image on ECS cluster.

Parameters:
EcsClusterName:
Type: String
Description: >
Specifies the ECS Cluster Name with which the resources would be
associated
Default: default
DockerImageUrl:
Type: String
Description: >
Specifies the Docker image url from where the docker image will be downloaded
Resources:

First, a VPC:

VPC:
Type: AWS::EC2::VPC
Properties:
CidrBlock: 10.1.0.0/16
EnableDnsSupport: true
EnableDnsHostnames: true
Tags:
- Key: Name
Value: !Join ['', [!Ref "AWS::StackName", "-VPC" ]]

Our VPC will need internet access:

InternetGateway:
Type: AWS::EC2::InternetGateway
DependsOn: VPC
AttachGateway:
Type: AWS::EC2::VPCGatewayAttachment
# Notice how you can't attach an IGW to a VPC unless both are created:
Properties:
VpcId: !Ref VPC
InternetGatewayId: !Ref InternetGateway
PublicSubnetA:
Type: AWS::EC2::Subnet
Properties:
VpcId: !Ref VPC
CidrBlock: 10.1.10.0/24
AvailabilityZone: !Select [ 0, !GetAZs ] # Get the first AZ in the list
Tags:
- Key: Name
Value: !Sub ${AWS::StackName}-Public-A
PublicSubnetB:
Type: AWS::EC2::Subnet
Properties:
VpcId: !Ref VPC
CidrBlock: 10.1.20.0/24
AvailabilityZone: !Select [ 1, !GetAZs ] # Get the second AZ in the list
Tags:
- Key: Name
Value: !Sub ${AWS::StackName}-Public-B
PrivateSubnetA:
Type: AWS::EC2::Subnet
Properties:
VpcId: !Ref VPC
CidrBlock: 10.1.50.0/24
AvailabilityZone: !Select [ 0, !GetAZs ] # Get the first AZ in the list
Tags:
- Key: Name
Value: !Sub ${AWS::StackName}-Private-A
PrivateSubnetB:
Type: AWS::EC2::Subnet
Properties:
VpcId: !Ref VPC
CidrBlock: 10.1.60.0/24
AvailabilityZone: !Select [ 1, !GetAZs ] # Get the second AZ in the list
Tags:
- Key: Name
Value: !Sub ${AWS::StackName}-Private-B

A NAT Gateway:

NATGateway:
Type: AWS::EC2::NatGateway
Properties:
AllocationId: !GetAtt ElasticIPAddress.AllocationId
SubnetId: !Ref PublicSubnetA
Tags:
- Key: Name
Value: !Sub NAT-${AWS::StackName}
ElasticIPAddress:
Type: AWS::EC2::EIP
Properties:
Domain: VPC

Some route tables for our subnets:

PublicRouteTable:
Type: AWS::EC2::RouteTable
Properties:
VpcId: !Ref VPC
Tags:
- Key: Name
Value: Public
PublicRoute1: # Public route table has direct routing to IGW:
Type: AWS::EC2::Route
DependsOn: AttachGateway
Properties:
RouteTableId: !Ref PublicRouteTable
DestinationCidrBlock: 0.0.0.0/0
GatewayId: !Ref InternetGateway

Here is a private route table:

PrivateRouteTable:
Type: AWS::EC2::RouteTable
Properties:
VpcId: !Ref VPC
Tags:
- Key: Name
Value: Private
PrivateRoute1: # Private route table can access web via NAT (created below)
Type: AWS::EC2::Route
Properties:
RouteTableId: !Ref PrivateRouteTable
DestinationCidrBlock: 0.0.0.0/0
# Route traffic through the NAT Gateway:
NatGatewayId: !Ref NATGateway

Attach the public subnets to public route tables,

and attach the private subnets to private route tables:

PublicSubnetARouteTableAssociation:
Type: AWS::EC2::SubnetRouteTableAssociation
Properties:
SubnetId: !Ref PublicSubnetA
RouteTableId: !Ref PublicRouteTable
PublicSubnetBRouteTableAssociation:
Type: AWS::EC2::SubnetRouteTableAssociation
Properties:
SubnetId: !Ref PublicSubnetB
RouteTableId: !Ref PublicRouteTable
PrivateSubnetARouteTableAssociation:
Type: AWS::EC2::SubnetRouteTableAssociation
Properties:
SubnetId: !Ref PrivateSubnetA
RouteTableId: !Ref PrivateRouteTable
PrivateSubnetBRouteTableAssociation:
Type: AWS::EC2::SubnetRouteTableAssociation
Properties:
SubnetId: !Ref PrivateSubnetB
RouteTableId: !Ref PrivateRouteTable
#Network LoadBalancer
LoadBalancer:
Type: AWS::ElasticLoadBalancingV2::LoadBalancer
Properties:
IpAddressType: ipv4
Name: !Join ['', [!Ref "AWS::StackName", "-LoadBalancer" ]]
Scheme: internet-facing
Subnets:
- !Ref PublicSubnetA
- !Ref PublicSubnetB
Type: network
LoadBalancerListener:
Type: AWS::ElasticLoadBalancingV2::Listener
DependsOn:
- DefaultTargetGroup
Properties:
LoadBalancerArn: !Ref LoadBalancer
Protocol: TCP
Port: 80
DefaultActions:
- Type: forward
TargetGroupArn: !Ref DefaultTargetGroup
DefaultTargetGroup:
Type: AWS::ElasticLoadBalancingV2::TargetGroup
Properties:
Name: TargetGroupforMSR
VpcId: !Ref VPC
Protocol: TCP
Port: 80
#ECS cluster
MyCluster101:
Type: 'AWS::ECS::Cluster'
Properties:
ClusterName: !Ref EcsClusterName
ClusterSettings:
- Name: containerInsights
Value: enabled
EcsSecurityGroup:
Type: AWS::EC2::SecurityGroup
Properties:
GroupDescription: ECS Allowed Ports
GroupName: !Join ['', [!Ref "AWS::StackName", "-EcsSecurityGroup" ]]
VpcId: !Ref VPC
SecurityGroupIngress:
-
IpProtocol: tcp
FromPort: 80
ToPort: 80
CidrIp: 0.0.0.0/0
-
IpProtocol: tcp
FromPort: 22
ToPort: 22
CidrIp: 0.0.0.0/0
-
IpProtocol: tcp
FromPort: 5555
ToPort: 5555
CidrIp: 0.0.0.0/0
ECSInstanceRole:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Version: 2008-10-17
Statement:
- Sid: ''
Effect: Allow
Principal:
Service: ec2.amazonaws.com
Action: 'sts:AssumeRole'
ManagedPolicyArns:
- 'arn:aws:iam::aws:policy/service-role/AmazonEC2ContainerServiceforEC2Role'
ECSInstanceProfile:
Type: AWS::IAM::InstanceProfile
Properties:
Path: "/"
Roles:
-
Ref: ECSInstanceRole
EcsInstanceLc:
Type: AWS::AutoScaling::LaunchConfiguration
Properties:
ImageId: ami-00f69adbdc780866c
InstanceType: t2.small
AssociatePublicIpAddress: true
IamInstanceProfile: !GetAtt ECSInstanceProfile.Arn
SecurityGroups: [!Ref EcsSecurityGroup]
UserData:
Fn::Base64:
!Sub |
#!/bin/bash
echo ECS_CLUSTER=${MyCluster101} >> /etc/ecs/ecs.config;
echo ECS_BACKEND_HOST= >> /etc/ecs/ecs.config;
BlockDeviceMappings:
- DeviceName: /dev/xvdcz
Ebs:
VolumeSize: 22
VolumeType: gp2
EcsInstanceAsg:
Type: AWS::AutoScaling::AutoScalingGroup
Properties:
VPCZoneIdentifier:
- !Ref PrivateSubnetA
- !Ref PrivateSubnetB
LaunchConfigurationName: !Ref EcsInstanceLc
MinSize: 0
MaxSize: 2
DesiredCapacity: 2
Tags:
-
Key: Name
Value: !Sub "ECS Instance - ${AWS::StackName}"
PropagateAtLaunch: 'true'
-
Key: Description
Value: "This instance is the part of the Auto Scaling group which was created through ECS Console"
PropagateAtLaunch: 'true'
ECSTaskExecutionRole:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Statement:
- Effect: Allow
Principal:
Service: [ecs-tasks.amazonaws.com]
Action: ['sts:AssumeRole']
Path: /
Policies:
- PolicyName: AmazonECSTaskExecutionRolePolicy
PolicyDocument:
Statement:
- Effect: Allow
Action:
# ECS Tasks to download images from ECR
- 'ecr:GetAuthorizationToken'
- 'ecr:BatchCheckLayerAvailability'
- 'ecr:GetDownloadUrlForLayer'
- 'ecr:BatchGetImage'
# ECS tasks to upload logs to CloudWatch
- 'logs:CreateLogStream'
- 'logs:PutLogEvents'
Resource: '*'
Taskdefinition:
Type: AWS::ECS::TaskDefinition
Properties:
RequiresCompatibilities: [EC2]
ExecutionRoleArn: !GetAtt ECSTaskExecutionRole.Arn
Family: MsrTask
ContainerDefinitions:
-
Name: MsrContainer
Image: !Ref DockerImageUrl
PortMappings:
-
ContainerPort: 5555
HostPort: 5555
Memory: 1024
MemoryReservation: 600
ECSServiceRole:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Version: 2008-10-17
Statement:
- Sid: ''
Effect: Allow
Principal:
Service: ecs.amazonaws.com
Action: 'sts:AssumeRole'
ManagedPolicyArns:
- 'arn:aws:iam::aws:policy/service-role/AmazonEC2ContainerServiceRole'
ServiceDefinition:
Type: AWS::ECS::Service
DependsOn:
- LoadBalancer
Properties:
Cluster: !Ref MyCluster101
LaunchType: EC2
TaskDefinition: !Ref Taskdefinition
ServiceName: !Join ['', [!Ref "AWS::StackName", "-Service" ]]
DesiredCount: 2
SchedulingStrategy: REPLICA
PlacementStrategies:
- Type: spread
Field: attribute:ecs.availability-zone
- Type: spread
Field: instanceId
DeploymentConfiguration:
MaximumPercent: 200
MinimumHealthyPercent: 100
Role: !GetAtt ECSServiceRole.Arn
LoadBalancers:
- TargetGroupArn: !Ref DefaultTargetGroup
ContainerPort: 5555
ContainerName: MsrContainer
Outputs:
LoadBalancerDNS:
Description: Load Balancer public DNS
Value: !GetAtt LoadBalancer.DNSName

@sharmaakshay1985 sharmaakshay1985 merged commit a92fc13 into master Apr 3, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants