AWS ECR & ECS

AWS ECR

Github repository Github repository

Amazon Elastic Container Registry (Amazon ECR) is an AWS managed container image registry service that is secure, scalable, and reliable. Amazon ECR supports private repositories with resource-based permissions using AWS IAM. This is so that specified users or Amazon EC2 instances can access your container repositories and images.AWS ECR

Run below command to create AWS ECR

1
terraform apply -target=module.ecr -var-file="aws-ecs.tfvars"

The terraform will create 2 ECR repository, attach access rule and lifecycle policy.

image

Both repository are using below lifecycle policy

  • Remove all untagged images after 7 days
  • Remove all images after 30 days since the ECR only for testing purpose.

image

Both repository will enable docker image scan after it’s been published to ECR.

*Remember to Enable AWS Inspector V2 from console before enhanced scanning, ECR enhanced scanning will use AWS inspector to scan images. For AWS free plan not allow to use the service, thus discard the code as below.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# ECR image scan
# Remember to Enable AWS Inspector V2 from console before enhanced scanning
resource "aws_ecr_registry_scanning_configuration" "ecr_enhanced_scanning" {

scan_type = "ENHANCED"

rule {
scan_frequency = "CONTINUOUS_SCAN"
repository_filter {
filter = "*" # For all repositories
filter_type = "WILDCARD"
}
}
}

Push to ECR

Run step3 to build docker image first if you don’t have.

In this example, I will push nginx to ECR.

image

Use below script to login ECR

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
AWS_ACCOUNT_ID="795359014551"
REGION="ap-northeast-1"
REPO_NAME="my-app-test"
IMAGE_NAME="ecr-nginx"
IMAGE_TAG="latest"

# Login to ECR
aws ecr get-login-password --region $REGION | \
docker login --username AWS --password-stdin \
$AWS_ACCOUNT_ID.dkr.ecr.$REGION.amazonaws.com

# Tag local image
docker tag $IMAGE_NAME:$IMAGE_TAG \
$AWS_ACCOUNT_ID.dkr.ecr.$REGION.amazonaws.com/$REPO_NAME:$IMAGE_NAME-$IMAGE_TAG

# Push to ECR
docker push \
$AWS_ACCOUNT_ID.dkr.ecr.$REGION.amazonaws.com/$REPO_NAME:$IMAGE_NAME-$IMAGE_TAG

# Health check
aws ecr describe-images \
--repository-name $REPO_NAME \
--region $REGION

Push result as below

image

Login AWS Console to check image in ECR

image

Promote image to another repository

Promote image from my-app-test to my-app-prod

1
2
3
4
5
6
7
8
9
10
11
12
13
14
AWS_ACCOUNT_ID="795359014551"
REGION="ap-northeast-1"
SOURCE_REPO_NAME="my-app-test"
TARGET_REPO_NAME="my-app-prod"
IMAGE_NAME="ecr-nginx"
IMAGE_TAG="latest"

# Get from ECR, can use describe api
IMAGE_DIGEST="sha256:2b8abdef88bc14753679af02869bebd507ad15705da02e6992af06078c47291b"

TARGET_TAG="${IMAGE_NAME:-$IMAGE_TAG}"
TARGET_IMAGE_URI="$AWS_ACCOUNT_ID.dkr.ecr.$REGION.amazonaws.com/$TARGET_REPO_NAME:$TARGET_TAG"

docker tag $AWS_ACCOUNT_ID.dkr.ecr.$REGION.amazonaws.com/$SOURCE_REPO_NAME@$IMAGE_DIGEST $TARGET_IMAGE_URI

Best Practise

1.We should create repository for each application for better management and control.

For example

123456789012.dkr.ecr.us-east-1.amazonaws.com/user-service:latest
123456789012.dkr.ecr.us-east-1.amazonaws.com/order-service:latest
123456789012.dkr.ecr.us-east-1.amazonaws.com/payment-service:latest
123456789012.dkr.ecr.us-east-1.amazonaws.com/api-gateway:latest
123456789012.dkr.ecr.us-east-1.amazonaws.com/nginx:latest

In CI/CD, we need to check whether repository exists or not. If not then need to create a new 1 before we push the images.

2.We should seprate the image for difference environment.

For example

123456789012.dkr.ecr.us-east-1.amazonaws.com/user-service-dev:latest

123456789012.dkr.ecr.us-east-1.amazonaws.com/user-service-uat:latest

123456789012.dkr.ecr.us-east-1.amazonaws.com/user-service-prod:latest

Pull from ECR

Run below command to pull image from ECR.

1
2
3
4
5
6
7
8
9
10
11
12
13
AWS_ACCOUNT_ID="795359014551"
REGION="ap-northeast-1"
REPO_NAME="my-app-test"
IMAGE_NAME="ecr-nginx"
IMAGE_TAG="latest"

# Login
aws ecr get-login-password --region $REGION | \
docker login --username AWS --password-stdin \
$AWS_ACCOUNT_ID.dkr.ecr.$REGION.amazonaws.com

# Pull the image
docker pull $AWS_ACCOUNT_ID.dkr.ecr.$REGION.amazonaws.com/$REPO_NAME:$IMAGE_NAME-$IMAGE_TAG

Result as below

image

ECS

Amazon Elastic Container Service (Amazon ECS) is a fully managed container orchestration service that helps you easily deploy, manage, and scale containerized applications. As a fully managed service, Amazon ECS comes with AWS configuration and operational best practices built-in. It’s integrated with both AWS tools, such as Amazon Elastic Container Registry (ECR), and third-party tools, such as Docker. AWS ECS

ECS provide 2 type of capacity:

  • Fargate - Serviceless compute engine managed by AWS, developer no need to care about the server detail like CPU and memory but higher cost.
  • EC2 - Developer need to create EC2 and managed instance on their own with lower cost.

Fargate

image

In this example, terraform module will create:

  • Route53
  • VPC endpoint to access ECR
  • AWS Application Load Balancer
  • ECS service with fargate type
  • CloudWatch log group

Run step 5 command as below

1
terraform apply -target=module.ecs_fargate -var-file="aws-ecs.tfvars"

To stop ECS task, can execute below command

*After the task stop, it will auto start up a new task.

1
2
3
aws ecs stop-task \
--cluster <your_cluster> \
--task <your_task_id>

If we need to stop all task without auto startup, then we will need the whole ECS service get stopped.

Change the expected task count to be 0.

1
2
3
4
5
6
7
8
9
10
aws ecs update-service \
--cluster your-cluster-name \
--service your-service-name \
--desired-count 0

# For example
aws ecs update-service \
--cluster my-ecs-cluster \
--service my-app-service \
--desired-count 0

TroubleShoot

Fail to pull image from ECR

ResourceInitializationError: unable to pull secrets or registry auth: The task cannot pull registry auth from Amazon ECR: There is a connection issue between the task and Amazon ECR.

image

Solution:

Execute AWS document to idenfity the root cause.

image

Reference Verify AWS ECS task connectivity

0%