Launch ECS container using AWS CLI - Step 2 - Launch EC2 Instance
Create an "EC2 Contaner Service" (ECS) cluster with one EC2 instance. This will be used to host ECS tasks / container instances.
This is part of a multi-post thread involving these steps:
- Network Setup
- Launch EC2 Instance (this post)
- Create Docker Image
- Create Service
- Cleanup
Define names
# Subnets
subnet_1="subnet-ecs-1"
subnet_2="subnet-ecs-2"
# Security Group
security_group="security-ecs"
# cluster
cluster="cluster-ecs"
# IAM
instance_role="instance-role-ecs"
instance_profile="instance-profile-ecs"
# EC2
instance="instance-ecs"
# SSH access key
key="aws-ec2-key"
ECS Cluster
Create ECS Cluster:
# Get IDs
group_id=$(aws ec2 describe-security-groups --filters Name=tag:Name,Values=$security_group | jq -r '.SecurityGroups[0].GroupId')
subnet_1_id=$(aws ec2 describe-subnets --filters Name=tag:Name,Values=$subnet_1 | jq -r '.Subnets[0].SubnetId')
echo "Create ECS cluster $cluster ..."
aws ecs create-cluster --cluster-name $cluster
EC2 Instance Role
Create an "assume role" policy configuration and save it to a file instance-policy.json
:
cat << EOT > ./instance-policy.json
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "ec2.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}
EOT
Create the EC2 Instance Role:
# EC2 Instance Role
echo "Create EC2 Instance Role ..."
aws iam create-role \
--role-name $instance_role \
--assume-role-policy-document file://instance-policy.json
... and attach the AmazonEC2ContainerServiceforEC2Role
policy to the instance role:
aws iam attach-role-policy \
--role-name $instance_role \
--policy-arn arn:aws:iam::aws:policy/service-role/AmazonEC2ContainerServiceforEC2Role
When you attach a managed policy to a role, the managed policy becomes part of the role's permission (access) policy.
EC2 Instance Profile
Create EC2 Instance Profile:
# EC2 Instance Profile
echo "Create EC2 Instance Profile ..."
aws iam create-instance-profile --instance-profile-name $instance_profile
aws iam add-role-to-instance-profile \
--instance-profile-name $instance_profile \
--role-name $instance_role
aws iam list-instance-profiles
echo "Wait 15 seconds for new instance profile to replicate in AWS ..."
sleep 15
EC2 Instance
Create a "block device mappings" configuration and save it to a file instance-block-device-mappings.json
:
cat << EOT > ./instance-block-device-mappings.json
[
{
"DeviceName": "/dev/sdf",
"Ebs": {
"DeleteOnTermination": true,
"VolumeSize": 50
}
}
]
EOT
Create an "instance startup" script and save it to a file instance-user-data.sh
. You can do anything in the startup script. In our case we use it to generate /etc/ecs/ecs.config
.
NOTE: This script runs on the EC2 instance after it launches.
cat << "EOT" > ./instance-user-data.sh
#!/bin/bash
cluster="cluster-ecs"
echo "ECS_CLUSTER=$cluster" >> /etc/ecs/ecs.config
echo "ECS_CONTAINER_INSTANCE_TAGS={\"ECS_CLUSTER\": \"$cluster\"}" >> /etc/ecs/ecs.config
echo ECS_AVAILABLE_LOGGING_DRIVERS='["json-file", "awslogs"]' >> /etc/ecs/ecs.config
EOT
Now we have everything that's needed. Launch the EC2 instance in subnet 1:
# EC2 Instance
echo "Launch EC2 instance in subnet 1: $subnet_1_id ..."
json=$(aws ec2 run-instances \
--subnet-id $subnet_1_id \
--security-group-ids $group_id \
--image-id resolve:ssm:/aws/service/ecs/optimized-ami/amazon-linux-2/recommended/image_id \
--instance-type t2.micro \
--count 1 \
--key-name $key \
--iam-instance-profile Name=$instance_profile \
--user-data file://instance-user-data.sh \
--block-device-mappings file://instance-block-device-mappings.json \
--tag-specifications 'ResourceType=instance,Tags=[{Key=Name,Value='$instance'}]')
instance_id=$(echo $json | jq -r '.Instances[0].InstanceId')
aws ec2 wait instance-exists --instance-ids $instance_id
echo " Instance created ..."
aws ec2 wait instance-running --instance-ids $instance_id
echo " Instance is running ..."
aws ec2 wait instance-status-ok --instance-ids $instance_id
echo " Instance is ready ..."
Verify
Check that EC2 container instance has checked in to the ECS Cluster:
Also should be reported in registeredContainerInstancesCount
when describing the ECS cluster: