Fargate(ECS) + VPC + Natゲートウェイ + ECR の組み合わせにおいて、VPCエンドポイントを作成してPrivateLink経由にする事で、コスト削減が可能となります。
概要については偉大な先人達の記事をご参照ください。
Amazon ECR インターフェイス VPC エンドポイント (AWS PrivateLink) - Amazon ECR
[AWS] FargateをNatゲートウェイと組み合わせて完全に死亡した話 | 個人利用で始めるAWS学習記
PrivateLinkとALBを利用してECS Fargateをロードバランシングする | Enjoy IT Life
AWS ECRのPrivate Linkを作る
エンドポイントを使用してプライベートサブネットでECSを使用する | Developers.IO
Fargate1.4.0以降の場合の注意
AWSのDocumentには但し書きがたくさんありますが、Fargate1.4.0以降と未満では必要な設定が異なります。
解説/やってみた記事では、1.3.0以前(1.4.0未満)の内容になっている場合があるので注意が必要です。
具体的には、
Fargate 起動タイプとプラットフォームバージョン 1.4.0 以降を使用する Amazon ECS タスクでこの機能を使用するには、com.amazonaws.region.ecr.dkr と com.amazonaws.region.ecr.api Amazon ECR VPC エンドポイントの両方、および Amazon S3 ゲートウェイエンドポイントが必要です。
が該当します。1.3.0未満との差分は、com.amazonaws.region.ecr.api
が追加で必要になった事です。
まとめると、
必要
- com.amazonaws.region.ecr.api
- com.amazonaws.region.ecr.dkr
- com.amazonaws.region.s3
log出力するなら必要
- com.amazonaws.region.logs
となります。
terraformで書く例
VPC、subnetは各自置き換えてください。
resource "aws_vpc_endpoint" "ecr_api" {
service_name = "com.amazonaws.ap-northeast-1.ecr.api"
vpc_endpoint_type = "Interface"
vpc_id = aws_vpc.main.id
subnet_ids = [aws_subnet.private_1a.id, aws_subnet.private_1c.id]
security_group_ids = [
aws_security_group.https.id,
]
private_dns_enabled = true
tags = {
"Name" = "ecr-api"
}
}
resource "aws_vpc_endpoint" "ecr_dkr" {
service_name = "com.amazonaws.ap-northeast-1.ecr.dkr"
vpc_endpoint_type = "Interface"
vpc_id = aws_vpc.main.id
subnet_ids = [aws_subnet.private_1a.id, aws_subnet.private_1c.id]
security_group_ids = [
aws_security_group.https.id,
]
private_dns_enabled = true
tags = {
"Name" = "ecr-dkr"
}
}
resource "aws_vpc_endpoint" "logs" {
service_name = "com.amazonaws.ap-northeast-1.logs"
vpc_endpoint_type = "Interface"
vpc_id = aws_vpc.main.id
subnet_ids = [aws_subnet.private_1a.id, aws_subnet.private_1c.id]
security_group_ids = [
aws_security_group.https.id,
]
private_dns_enabled = true
tags = {
"Name" = "logs"
}
}
resource "aws_vpc_endpoint" "s3" {
service_name = "com.amazonaws.ap-northeast-1.s3"
vpc_endpoint_type = "Gateway"
vpc_id = aws_vpc.main.id
route_table_ids = [
aws_default_route_table.private.id
]
tags = {
"Name" = "-s3"
}
}
resource "aws_security_group" "https" {
name = "https"
description = "https"
vpc_id = aws_vpc.main.id
egress {
cidr_blocks = ["0.0.0.0/0"]
from_port = 0
protocol = "-1"
to_port = 0
}
ingress {
cidr_blocks = ["0.0.0.0/0"]
from_port = 443
protocol = "tcp"
to_port = 443
}
timeouts {}
tags = {
Name = "https"
}
}