This article is part 1 of a 4 part guide to running Docker containers on AWS ECS. ECS stands for Elastic Container Service. It is a managed container service that can run docker containers. Although AWS also offers container management with Kubernetes, (EKS) it also has its proprietary solution (ECS). The guide will cover:
- Creating the ECS Cluster.
- Provision an Image Registry (ECR) and push docker images to the registry.
- Deploying Containers to the cluster using Task and Service Definitions.
- Creating a Pipeline to Update the services running on the ECS Cluster.
This guide will cover how to create the ECS cluster.
Requirements/Prerequisites
Before proceeding with this guide, the reader/user must have:
- An AWS Account.
- Created a User on the account with Permissions to provision resources on the account.
- Generated an EC2 SSH Key-Pair.
- Created a VPC and Subnets (Optional).
A guide to create VPC and Subnets (AWS Network Architecture) can be found on the link below:
Creating the AWS ECS Cluster
There are two types of ECS clusters we can create.
- ECS with Fargate cluster: This is a cluster that allows the user to run containers without the need to worry about provisioning and managing EC2 instances/servers. It is basically a serverless architecture.
- ECS with EC2 Instances cluster: This cluster allows a user to run containers on provisioned EC2 instances. Hence the need to manage the servers.
Create an AWS ECS Cluster with Fargate Option
To create the cluster we can do so manually or automatically using either CloudFormation or Terraform. For this article, I will create the cluster using CloudFormation and manually.
CloudFormation:
The below CloudFormation Template creates an ECS cluster with a capacity provider as Fargate and Container Insights enabled. The reader should modify the template settings to customize to their specific requirements. Key aspects to change will be:
- Tags.
- The Cluster Settings.
AWSTemplateFormatVersion: "2010-09-09"
Description: "Create ECS fargate cluster"
Parameters:
Name:
Type: String
Description: The name of the ECS Cluster
Resources:
ECSCluster:
Type: 'AWS::ECS::Cluster'
Properties:
ClusterName: !Ref Name
ClusterSettings:
- Name: containerInsights
Value: enabled
CapacityProviders:
- FARGATE
Tags:
-
Key: "Name"
Value: "test-ecs"
-
Key: "CreatedBy"
Value: "Maureen Barasa"
-
Key: "Environment"
Value: "test"
Outputs:
ECS:
Description: The created ECS Cluster
Value: !Ref ECSCluster
Manually:
To manually create the cluster follow the below steps.
On the Elastic Container Services console, click create cluster.
Then, for the cluster template, select Powered by Fargate as your option. Click next step.
Finally, configure cluster setting and click create cluster. N/B: You can create a new VPC for the cluster. But this is optional.
You now have your ECS Fargate cluster running.
Create an AWS ECS Cluster with EC2 Option
We can also do this using CloudFormation, Terraform, or manually.
CloudFormation:
For CloudFormation, use the below template.
AWSTemplateFormatVersion: "2010-09-09"
Description: "Create ECS fargate cluster"
Parameters:
Name:
Type: String
Description: The name of the ECS Cluster
VPC:
Type: String
Description: The vpc to launch the service
Default: vpc-ID
PrivateSubnet01:
Type: String
Description: The subnet where to launch the ecs instances
Default: subnet-ID
PrivateSubnet02:
Type: String
Description: The subnet where to launch the ecs instances
Default: subnet-ID
InstanceType:
Type: String
Description: The EC2 instance type
Default: "t2.micro"
MinSize:
Type: String
Description: The subnet where to launch the ec2
Default: 1
MaxSize:
Type: String
Description: The subnet where to launch the ec2
Default: 2
DesiredSize:
Type: String
Description: The subnet where to launch the ec2
Default: 1
Resources:
IAMInstanceRole:
Type: 'AWS::IAM::Role'
Properties:
Description: The ECS Instance Role
RoleName: ecsInstanceRole2
AssumeRolePolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Principal:
Service:
- ec2.amazonaws.com
Action:
- 'sts:AssumeRole'
ManagedPolicyArns:
- arn:aws:iam::aws:policy/service-role/AmazonEC2ContainerServiceforEC2Role
- arn:aws:iam::aws:policy/CloudWatchAgentServerPolicy
- arn:aws:iam::aws:policy/AmazonS3ReadOnlyAccess
Tags:
-
Key: "Environment"
Value: "test"
-
Key: "createdBy"
Value: "Maureen Barasa"
-
Key: "Name"
Value: "ecsInstanceRole2"
IAMInstanceProfile:
Type: AWS::IAM::InstanceProfile
Properties:
InstanceProfileName: ecsInstanceRole2
Roles:
- !Ref IAMInstanceRole
ECSSecurityGroup:
Type: "AWS::EC2::SecurityGroup"
Properties:
GroupDescription: "Security Group to control access to the ECS cluster"
GroupName: "test-ECS-SG"
VpcId: !Ref VPC
SecurityGroupIngress:
-
CidrIp: 0.0.0.0/0
FromPort: 80
IpProtocol: "tcp"
ToPort: 80
-
CidrIp: 0.0.0.0/0
FromPort: 443
IpProtocol: "tcp"
ToPort: 443
Tags:
-
Key: "Name"
Value: "test-ECS-SG"
-
Key: "CreatedBy"
Value: "Maureen Barasa"
-
Key: "Environment"
Value: "test"
ECSCluster:
Type: 'AWS::ECS::Cluster'
Properties:
ClusterName: !Ref Name
ClusterSettings:
- Name: containerInsights
Value: enabled
Tags:
-
Key: "Name"
Value: "test-ecs"
-
Key: "CreatedBy"
Value: "Maureen Barasa"
-
Key: "Environment"
Value: "test"
ECSAutoScalingGroup:
Type: AWS::AutoScaling::AutoScalingGroup
Properties:
VPCZoneIdentifier:
- !Ref PrivateSubnet01
- !Ref PrivateSubnet02
LaunchConfigurationName: !Ref LaunchConfiguration
MinSize: !Ref MinSize
MaxSize: !Ref MaxSize
DesiredCapacity: !Ref DesiredSize
HealthCheckGracePeriod: 300
Tags:
-
Key: "Name"
Value: "test-ecs"
PropagateAtLaunch: true
-
Key: "CreatedBy"
Value: "MaureenBarasa"
PropagateAtLaunch: true
-
Key: "Environment"
Value: "test"
PropagateAtLaunch: true
LaunchConfiguration:
Type: AWS::AutoScaling::LaunchConfiguration
Properties:
ImageId: "ami-ID"
SecurityGroups:
- !Ref ECSSecurityGroup
InstanceType: !Ref InstanceType
IamInstanceProfile: !Ref IAMInstanceProfile
KeyName: "test-key"
UserData:
Fn::Base64: !Sub |
#!/bin/bash
echo ECS_CLUSTER=test-ecs >> /etc/ecs/ecs.config;echo ECS_BACKEND_HOST= >> /etc/ecs/ecs.config;
BlockDeviceMappings:
-
DeviceName: "/dev/xvda"
Ebs:
Encrypted: false
VolumeSize: 20
VolumeType: "gp2"
DeleteOnTermination: true
Outputs:
IAMProfile:
Description: The created EC2 Instance Role
Value: !Ref IAMInstanceProfile
AutoScalingGroup:
Description: The ECS Autoscaling Group
Value: !Ref ECSAutoScalingGroup
ECS:
Description: The created ECS Cluster
Value: !Ref ECSCluster
On the parameter section of the template, enter the specific customized inputs for your cluster. This include:
- The VPC and Subnets.
- The Instance Type and Auto Scaling Group Scaling Requirements.
Under the resources section. Take note to customize:
- Resources Names and Tags.
- The Key Name of your EC2 launch configuration (Use a Key-Pair you have generated).
- The AMI-ID for your EC2 Instances. (Use an Amazon ECS-optimized AMIs on your account).
After the CloudFormation finishes executing the stack, You should now have an ECS cluster with a registered active EC2 container instance. See below:
Manually:
To create the cluster manually follow the below steps:
Create an ECS Instance Role with the following AWS Managed Policies:
- AmazonS3ReadOnlyAccess
- CloudWatchAgentServerPolicy
- Amazon EC2ContainerServiceforEC2Role
Edit the role trust relationship and add the below JSON trust policy.
{
"Version": "2008-10-17",
"Statement": [
{
"Sid": "",
"Effect": "Allow",
"Principal": {
"Service": "ec2.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}
Then, on the Elastic Container Service console, click create cluster. This time on the select cluster template window, instead of opting for Powered by Fargate, choose EC2 Linux + Networking option. Click next step.
Next, you need to configure your cluster. On cluster configuration, we have 3 main sections:
- Cluster Name
- Instance Configuration
- Networking
Cluster Name:
Instance Configuration:
Ensure you select the correct instance configurations specific to your requirements.
Networking:
Here, there is an option to create a new VPC, and Subnets should the user not have created his/her own. If they had already created a Network Architecture, the reader can use the existing setup. The same applies to the security group for the cluster. A new one can be created or we can choose an existing one.
Then, for the container instance IAM Role, select the role you created above. Enable container insights by checking the box next to enable container insights.
Finally click, create cluster. You will have a cluster up and running in a few minutes.
Below is a link to part 2 of this series where I discuss deploying containers to the cluster using Task and Service Definitions.
Running Docker Containers on AWS ECS – Upload Docker Images to ECR – Part 2
AWS ECS: Deploying Containers using Task and Service Definitions – Part 3
Tags:
- How to create AWS ECS Cluster manually
- How to create AWS ECS Cluster with CloudFormation
- How To Run Docker containers on AWS With ECS – Part 1
Important Links
More guides on AWS:
Happy Building!!!