前提
CDKとは?
JavaやTypescriptなどのプログラミング言語を使用してAWSのリソースをコードとして定義し、AWS上にデプロイするためのフレームワーク。コードでAWSリソースを管理する感じのもの。個人的には、概念的にはAnsibleに似てると感じた。
ECSとは?
DockerのコンテナをAWS上で動かすサービス
サービスディスカバリとは?
ECS間通信に使うサービス。サービスディスカバリを使えば、コンテナにFQDNがついてIPアドレスではなく名前(FQDN)でアクセスできる。実際はFQDNとIPアドレスの対応がRoute53に自動で登録される。
マネジメントコンソールからだと、
- ECS > クラスター > サービスの作成 > ネットワーク構成 > サービスの検出
から設定する。
一般的な他の方法としては、ECSでコンテナをたてるとIPアドレスを付加して他のリソースからアクセスするなどの方法がある。
困ったこと
CDKでコードを書こうとして、ecs,サービスディスカバリのドキュメントを読んでいくが、ECSとサービスディスカバリのクラスには両者を関連させるメソッドが存在しない。
参考
困る前にできていたこと
- マネジメントコンソールからボタンを押していってサービスの検出をすることはできていた。
-
class ServiceDiscovery · AWS CDK を参考に、CDKで以下の名前解決はできていた。Exampleのコードに書いてある通りに実現できた。
- [FQDN-コンテナのIPアドレス]のレコード追加
- [FQDN-Application load balancer]のレコード追加
解決するために必要だったこと
- サービスディスカバリとはどういうものなのか今一度知ること
結論
(CDKでECSサービスディスカバリを設定するコード)
以下のようにすればよかった。
// まずサービスディスカバリを作る
// 以下の記事あたりを参考
// https://docs.aws.amazon.com/cdk/api/v1/java/software/amazon/awscdk/services/ecs/FargateService.html
Cluster cluster;
TaskDefinition taskDefinition;
Vpc vpc;
FargateService fargateService = FargateService.Builder.create(this, "Service").cluster(cluster).taskDefinition(taskDefinition).build();
// サービスディスカバリの機能を使ってレコードをroute53に登録
// ここのコードは以下に記載してあるものとだいたい同じ
// https://docs.aws.amazon.com/cdk/api/v1/java/index.html?software/amazon/awscdk/services/servicediscovery/package-summary.html
PrivateDnsNamespace namespace = PrivateDnsNamespace.Builder.create(this, "namespace")
.name("domainName")
.vpc(vpc)
.build();
Service service = namespace.createService("service-discovery-service", DnsServiceProps.builder()
.dnsRecordType(DnsRecordType.A)
.dnsTtl(Duration.seconds(30))
.loadBalancer(false)
.name("subDomainName")
.build());
// ECSからcloudMapsサービス経由でサービスディスカバリを用いる。 ここが難しかったポイント
// 以下の記事の中のAssociateCloudMapServiceOptionsメソッドを用いる
// https://docs.aws.amazon.com/cdk/api/v1/java/index.html?software/amazon/awscdk/services/ecs/package-summary.html
fargateService.associateCloudMapService(AssociateCloudMapServiceOptions.builder()
.service(service)
.build());
ポイント
- サービスディスカバリの後ろ側ではCloudMapが動いていると知ること
- ECS-CloudMap-Route53 のように間にCloudMapを仲介してECSとRoute53を関連させること
感想
英語の記事含め、直接「CDKでECSサービスディスカバリを設定する」記事が見つけられなかったので難しかった。
そのため、正直、上記のassociateCloudMapServiceのコードを書いて実行するまで本当に「CDKでECSサービスディスカバリを設定する」ことが可能なのか半信半疑だった。
同じ悩みをもった方々の参考になれば嬉しいです。
謝辞
上記の解決を手助けしてくださった方々、感謝しております。
ありがとうございます。