ECS-Fargate Private ECR Through VPC Endpoints
When working with ECS services that don't have access to the internet you need security group rules that enable the docker pull
to connect to the account ECR.
There are a few moving parts.
First, create the VPC endpoints normally required for ECS Fargate. The Secrets manager is not strictly required for ECR endpoints but most containers need a secret.
module "vpc_endpoints" {
source = "terraform-aws-modules/vpc/aws//modules/vpc-endpoints"
version = "~> 5"
vpc_id = local.vpc_id
create_security_group = true
security_group_name_prefix = "vpc-endpoints-"
security_group_description = "VPC endpoint security group"
security_group_rules = {
ingress_https = {
description = "HTTPS from VPC"
cidr_blocks = [local.vpc_cidr_block]
}
}
endpoints = {
ecr_dkr = {
service = "ecr.dkr"
private_dns_enabled = true
subnet_ids = local.private_subnets
tags = { Name = "ecr-dkr-vpc-endpoint" }
},
ecr_api = {
service = "ecr.api"
private_dns_enabled = true
subnet_ids = local.private_subnets
tags = { Name = "ecr-api-vpc-endpoint" }
}
cloudwatch = {
service = "logs"
private_dns_enabled = true
subnet_ids = local.private_subnets
tags = { Name = "logs-vpc-endpoint" }
}
s3 = {
service = "s3"
service_type = "Gateway"
subnet_ids = local.private_subnets
route_table_ids = local.private_subnet_route_table_ids
tags = { Name = "s3-gateway-vpc-endpoint" }
}
secretsmanager = {
service = "secretsmanager"
private_dns_enabled = true
subnet_ids = local.private_subnets
tags = {
Name = "secretsmanager-vpc-endpoint"
}
}
}
}
Note the use of a Gateway S3, that means there is no ENI launched into the VPC whereas the others are interfaces which do have a VPC private ENI created and attached.
Next create an ECS cluster with a service inside that has the following SG rules:
- Egress 443 to
module.vpc_endpoints.endpoints["s3"].prefix_list_id
. This will allow the IP's of the public S3 endpoints even though the traffic is private. - Egress 443 to the source security group id of
module.vpc_endpoints.security_group_id
. This will allow 443 to the security group of the endpoints. - Make sure your route tables in the private subnet have a route to the S3 gateway.
You might need other SG rules for RDS, Elasticache, OpenSearch, or ingress from an ALB but that is on you.