はじめに
App Runner からの移行先として ECS Express Mode で中々な苦労をしています。
現状では、ALB が重複作成されるかどうかは「運」(AWS基盤側の実装次第という意味で)であることまで調査ができておりますのでこの記事で共有しておきます。
背景
前回の記事で、ECS Express Mode で複数サービスを Terraform でデプロイすると ALB が重複作成される問題を取り上げました。原因は並列作成による race condition と考え、depends_on で直列化する対策を紹介しました。
しかし、その後の調査で depends_on による直列化では解決しないことが分かりました。さらに、Terraform AWS Provider のソースコードと AWS API の仕様を確認した上で、Terraform を完全に排除して AWS CLI で直接検証した結果、少なくとも Terraform / Provider 固有の問題ではないことが判明しました。前回の記事で紹介した depends_on による対策は誤りでしたので、本記事で訂正します。
前回の結論(誤り)
- 並列作成による race condition が原因
-
depends_onで直列化すれば ALB 共有が機能する
今回分かったこと
-
depends_onで直列化しても ALB は重複する - AWS CLI で直接 API を叩いても同じ結果になる(Terraform は無関係)
-
CreateExpressGatewayServiceAPI に ALB 共有を制御するパラメータは存在しない
まだ不明なこと
- ALB 共有の成否を決める内部条件
- 同じ手順でもアカウントによって結果が異なる理由
概要
ALB が重複作成されるかどうかは、利用者側で制御できるパラメータでは決まらないようです。現時点では AWS Express Mode 側の内部判定に依存している可能性が高く、同じコード・同じ条件・同じ手順でもアカウントによって結果が異なることを確認しました。
内容
検証 1: Terraform を排除して AWS CLI で直接作成
Terraform / Provider の影響を完全に排除するため、AWS CLI で直接 create-express-gateway-service を実行しました。
前提条件:
- サービス A が ACTIVE、ALB が 1 つ稼働中
- サービス B は削除済み(NotFound)、ALB は 1 つに減少済み
aws ecs create-express-gateway-service \
--cluster <CLUSTER> \
--service-name <SERVICE_B_NAME> \
--execution-role-arn <ARN> \
--infrastructure-role-arn <ARN> \
--primary-container '{"image":"<IMAGE>","containerPort":8088}' \
--network-configuration '{"subnets":[<サービスAと同一のサブネット>],"securityGroups":[<サービスAと同一のSG>]}' \
--health-check-path "/health" \
--cpu 1024 --memory 2048
結果: ALB が 2 つ作られました。 少なくとも Terraform / Provider 固有の問題ではないことが確認できました。
検証 2: Terraform AWS Provider のソースコードと API 仕様の確認
Terraform AWS Provider のソースコード(express_gateway_service.go)を確認したところ、Provider は CreateExpressGatewayService API を呼んでサービスが ACTIVE になるまで待機するだけで、ALB の共有判定には関与していませんでした。
また、CreateExpressGatewayService API の仕様を確認しましたが、ALB の指定・共有・再利用を制御するパラメータは存在しません。ALB の作成と共有は Express Mode 側の自動判定に委ねられています。
検証 3: 正常アカウントとの比較
同じ手順でサービス B を削除→再作成した複数の AWS アカウントのうち、ALB が正常に共有されたものと重複したものがありました。
確認した範囲で以下の項目に差異はありませんでした。
- ALB タグ(
AmazonECSManaged、environment、service、Name) - ALB の scheme(internet-facing)
- リスナールールの設定
- サブネット ID / AZ 構成
- セキュリティグループ
- VPC 設定(IPv6 なし、パブリックサブネット)
- 既存サービス数(1 サービス)
公開仕様だけでは説明できない差異がある状況です。
ALB 共有について公式ドキュメントから確認できる条件
AWS 公式ドキュメント から確認できる ALB 共有条件としては、少なくとも以下があります。
Express services share Application Load Balancers within a VPC, with up to 25 services per load balancer.
- 同一 VPC 内であること
- ALB あたり最大 25 サービスの容量内
- サブネット/AZ の一致(最初のサービスが定義した AZ 構成と後続が一致すること)
今回のケースはこれらの条件を満たしていましたが、ALB は共有されませんでした。ドキュメントに記載されていない内部条件が別途存在する可能性があります。
結論: 利用者側で再現条件を制御できない
depends_on による直列化は恒久対策とは言えず、少なくとも Terraform / Provider 固有の問題とは断定できません。CreateExpressGatewayService の公開仕様上は ALB 共有を明示制御する手段が見当たらず、現時点では Express Mode 側の内部判定または未公開条件に依存する事象とみられます。
終わりに
前回の記事では depends_on による直列化を対策として紹介しましたが、それだけでは不十分でした。現時点では AWS Support への問い合わせを検討しています。
ECS Express Mode は便利な仕組みですが、複数サービスの ALB 共有については公開仕様だけでは説明できない挙動があります。同様の問題に遭遇した方の参考になれば幸いです。
一言
もしこの記事が気に入って頂けたらここでのいいね&フォローとX( @___nix___ )でのフォローもお願い致します。