[アップデート] VPC Lattice が Amazon ECS とのネイティブ統合をサポートしました
こんにちは!AWS 事業本部コンサルティング部のたかくに(@takakuni_)です。
VPC Lattice が Amazon ECS とのネイティブ統合をサポートしました。
何が嬉しいのか
今まで、 VPC Lattice を用いて ECS とサービス間接続を行うには前段に内部 ALB が必要でした。今回のアップデートで直接、 VPC Lattice と ECS サービスが統合できるようになりました。見通しがかなり良くなりましたね。
IAM ロール
今回のアップデートを利用するには ECS にインフラストラクチャ IAM ロールを付与する必要があります。
特段要件がなければ、マネージドポリシーとして AmazonECSInfrastructureRolePolicyForVpcLattice
が用意されているため、こちらを利用しましょう。
{
"Version" : "2012-10-17",
"Statement" : [
{
"Sid" : "ManagedVpcLatticeTargetRegistration",
"Effect" : "Allow",
"Action" : [
"vpc-lattice:RegisterTargets",
"vpc-lattice:DeregisterTargets"
],
"Resource" : [
"arn:aws:vpc-lattice:*:*:targetgroup/*"
]
},
{
"Sid" : "DescribeVpcLatticeTargetGroup",
"Effect" : "Allow",
"Action" : "vpc-lattice:GetTargetGroup",
"Resource" : [
"arn:aws:vpc-lattice:*:*:targetgroup/*"
]
},
{
"Sid" : "ListVpcLatticeTargets",
"Effect" : "Allow",
"Action" : "vpc-lattice:ListTargets",
"Resource" : [
"arn:aws:vpc-lattice:*:*:targetgroup/*"
]
},
{
"Sid" : "DescribeEc2Resources",
"Effect" : "Allow",
"Action" : [
"ec2:DescribeSubnets",
"ec2:DescribeVpcs",
"ec2:DescribeInstances"
],
"Resource" : [
"*"
]
}
]
}
VPC Lattice
このアップデートがあるまで、VPC Lattice をキャッチアップできていなかったのですが、Amazon VPC Lattice Workshop をやると結構わかった気になれるのでオススメです。
また、以下のブログも参考資料としてオススメです。大村さんいつもありがとうございます。
とくにこの図は神ですね。
やってみる
実際に試してみましょう。
今回は異なる VPC に属する ECS をターゲットに VPC Lattice で接続してみたいと思います。
今回インフラの構築は Terraform を利用してみました。利用したコードは以下に格納されています。
VPC Lattice
それでは VPC Lattice の設定値を見てみましょう。
サービスネットワーク
サービスネットワークはホストするサービスと、接続元の VPC を管理します。ホストするサービス(ECS)側の VPC は、今回の場合だと VPC 関連付けは不要です。
接続先と接続元を別々で管理し、メッシュのように接続しなくていいシンプルな作りはとても良いですよね。ただし、各 VPC は 1 つのサービスネットワークにのみ関連付けることができる点に注意です。(複数サービスネットワークに関連づけられるようになってくれ〜と思いつつ、そうなった時は逆に複雑になりそうだなと思いますが。)
サービス
続いてサービスです。「ALB + リスナーをより抽象度高くまとめたような立ち位置」です。
今回の場合、単一の ECS サービスが VPC Lattice のサービスに属していますが、複数の ECS サービスを混在させることもできます。サービスネットワークを RAM で共有することでアカウント跨いだ ECS サービスも所属できます。
今回は /
と、/headers
は ECS に疎通できるよう設定しました。
複数の ECS サービスを VPC Lattice サービスにまとめられるため、どのような分割単位にするべきか?と疑問が出てくると思います。
私も明確な答えを持っているわけではないですが、サービスごとにアクセスポリシーを設定できるため、アクセスポリシーごとに VPC Lattice のサービスをわけて設計してあげれば良いのではないかと思いました。
たとえば、次のように特定の VPC のみ、特定の VPC Lattice サービスにアクセスすると言ったポリシーを設定できます。
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": "*",
"Action": "vpc-lattice-svcs:Invoke",
"Resource": "*",
"Condition": {
"StringNotEquals": {
"aws:PrincipalType": "Anonymous"
},
"StringEquals": {
"vpc-lattice-svcs:SourceVpc": "vpc-1a2b3c4d"
}
}
}
]
}
ターゲットグループ
最後にターゲットグループです。こちらは ALB のターゲットグループに近い作りです。
ECS なのでターゲットタイプは IP です。今回の ECS 統合により ECS タスクで利用している IP が VPC Lattice のターゲットグループに自動で登録されるようになりました。なお、自動で登録するためにインフラストラクチャ IAM ロールを利用します。
キャプチャではデータが不足していますが、メトリクスも非常にシンプルで、リクエストタイム、ステータスコードが用意されていますね。
CloudWatch コンソールに行くと、他のメトリクスも閲覧できるようです。
疎通確認
それでは疎通確認をしてみます。
Web コンテナには FastAPI を利用しました。
/headers
のパスにアクセスが来た時、どんなヘッダーが拾えるのか確認してみましょう。
from fastapi import FastAPI, Request
from typing import Dict
app = FastAPI()
@app.get("/headers")
async def get_headers(request: Request) -> Dict:
return {"headers": dict(request.headers)}
@app.get("/")
async def root():
return {"message": "Welcome to the Headers API"}
いくつか、ヘッダー情報が取れていますね。x-forwarded-for
で送信元 IP アドレスもしっかり取得できています。
[ssm-user@ip-10-0-1-213 ~]$ ifconfig
enX0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 9001
inet 10.0.1.213 netmask 255.255.255.0 broadcast 10.0.1.255
inet6 fe80::49a:67ff:fe66:264f prefixlen 64 scopeid 0x20<link>
ether 06:9a:67:66:26:4f txqueuelen 1000 (Ethernet)
RX packets 4422 bytes 707958 (691.3 KiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 4622 bytes 686513 (670.4 KiB) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536
inet 127.0.0.1 netmask 255.0.0.0
inet6 ::1 prefixlen 128 scopeid 0x10<host>
loop txqueuelen 1000 (Local Loopback)
RX packets 12 bytes 1020 (1020.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 12 bytes 1020 (1020.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
[ssm-user@ip-10-0-1-213 ~]$ curl -s ecslattice-01-svc-00000000000000000.7d67968.vpc-lattice-svcs.ap-northeast-1.on.aws/ | jq
{ "message": "Welcome to the Headers API"
}
[ssm-user@ip-10-0-1-213 ~]$ curl -s ecslattice-01-svc-00000000000000000.7d67968.vpc-lattice-svcs.ap-northeast-1.on.aws/headers | jq
{
"headers": {
"host": "ecslattice-01-svc-00000000000000000.7d67968.vpc-lattice-svcs.ap-northeast-1.on.aws",
"user-agent": "curl/8.5.0",
"accept": "*/*",
"x-forwarded-for": "10.0.1.213",
"x-amzn-lattice-network": "SourceVpcArn=arn:aws:ec2:ap-northeast-1:123456789012:vpc/vpc-032dbed1cacd149af",
"x-amzn-lattice-target": "ServiceArn=arn:aws:vpc-lattice:ap-northeast-1:123456789012:service/svc-00000000000000000; ServiceNetworkArn=arn:aws:vpc-lattice:ap-northeast-1:123456789012:servicenetwork/sn-0896b9
4dcf5a98c64; TargetGroupArn=arn:aws:vpc-lattice:ap-northeast-1:123456789012:targetgroup/tg-076e6345721be1482",
"x-amzn-source-vpc": "vpc-032dbed1cacd149af" }
}
まとめ
以上、「VPC Lattice が Amazon ECS とのネイティブ統合をサポートしました。」でした。
新しいサービス間、VPC 間通信の手段の 1 つとして検討できそうですね。
このブログがどなたかの参考になれば幸いです
AWS 事業本部コンサルティング部のたかくに(@takakuni_)でした!