ECSのサービスディスカバリーをCloudFormationで作成する

ECSでサービスディスカバリー(サービス検出)を利用したい場合に、CloudFormationでリソースを作成する方法をまとめました。
2021.03.31

コンサル部のtobachi(@toda_kk)です。

サービスディスカバリー(サービス検出)を使うECSリソースをCloudFormationで作成する機会があり、意外とまとまった記事が見つからなかったのでテンプレートの例を記載してみました。

結論

必要なリソース

  1. AWS::ServiceDiscovery::PrivateDnsNamespaceリソースを作成する。
  2. AWS::ServiceDiscovery::Serviceのリソースを作成する。DnsConfig.NamespaceIdに1. で作成したリソースのIDを指定する。
  3. サービスディスカバリーで名前解決したいAWS::ECS::Serviceリソースを作成する。ServiceRegistries.RegistryArnに2. で作成したリソースのARNを指定する。

サンプルテンプレート

サービスディスカバリーを動かすのに最低限必要なリソースのみを記述したサンプルテンプレートです。

ベタ書きしている箇所がいくつかあるので、適宜修正した上でご利用ください。

AWSTemplateFormatVersion: "2010-09-09"
Resources:
  PrivateDnsNamespace:
    Type: AWS::ServiceDiscovery::PrivateDnsNamespace
    Properties:
      Vpc: "sample-vpc"
      Name: "sample.local"

  ServiceDiscovery:
    Type: AWS::ServiceDiscovery::Service
    Properties:
      HealthCheckCustomConfig:
        FailureThreshold: 1
      DnsConfig:
        DnsRecords:
          - Type: A
            TTL: 60
        NamespaceId: !GetAtt PrivateDnsNamespace.Id
      Name: "service"

  ECSService:
    Type: "AWS::ECS::Service"
    Properties:
      ServiceName: "sample-ecs-service"
      Cluster: "sample-ecs-cluster"
      ServiceRegistries:
        - RegistryArn: !GetAtt ServiceDiscovery.Arn
      DesiredCount: 2
      LaunchType: "FARGATE"
      PlatformVersion: "1.4.0"
      TaskDefinition: "arn:aws:ecs:ap-northeast-1:123456789012:task-definition/sample-ecs-task:1"
      DeploymentConfiguration:
        MaximumPercent: 200
        MinimumHealthyPercent: 100
      NetworkConfiguration:
        AwsvpcConfiguration:
          AssignPublicIp: "DISABLED"
          SecurityGroups:
            - sg-xxxxxxxxxx
          Subnets:
            - subnet-xxxxxxxxxx
            - subnet-xxxxxxxxxx
      SchedulingStrategy: "REPLICA"

何が必要なのか?

上記の通り、ECSサービスディスカバリーを構築するために必要なリソースは下記2つです。

  • AWS::ServiceDiscovery::PrivateDnsNamespace
  • AWS::ServiceDiscovery::Service

サービスディスカバリーの仕組み

サービスディスカバリーの仕組みとして、裏側ではAWS Cloud Mapが動いています。これはVPC内にプライベートな名前空間を作成し管理できるサービスです。

Cloud Mapの詳細については下記の記事をご参照ください。

ECSサービスの設定で「サービス検出」を利用すると、タスクが起動した際に自動的にRoute 53に登録されているAレコードを更新し、タスクが起動するEC2/FargateのプライベートIPを登録してくれます。

VPC内では起動したタスクを名前解決してルーティングできるようになるため、コンテナ間の通信が容易になるというわけです。

AWSマネジメントコンソールとCloudFormationの違い

サービスディスカバリーを設定したい場合、AWSマネジメントコンソールからだとECSサービスを作成する画面で「サービス検出」として設定項目が表示されます。そのため、ECSサービスに付随するリソースなのだと誤解してしまいました。

CloudFormationの場合は、ServiceDiscoveryリソースでCloud MapのNamespaceおよびServiceを作成し、それらをECSサービスに関連づけるような形で設定します。

CloudFormationでリソースを作成すると仕組みが見えてくる

ECSに限らずAWSリソースを作成する際、AWSマネジメントコンソールとCloudFormationでは少し意識を変える必要があります。

CloudFormationで作成する場合は、あるAWSサービスの裏側で他のAWSサービスがどのように関連しているのかを理解する必要があります。今回の場合も、その一例と言えるでしょう。

参考: Fargateを利用してECSをCloudFormationで作成する

本記事では詳しく記載しませんでしたが、Fargateを利用したECSリソースをCloudFormationで作成する場合には、下記の記事が参考になります。

実際にECSサービスディスカバリーを構築する際には、本記事と併せてご参照いただけると良いかなと思います。

以上、コンサル部のtobachi(@toda_kk)でした。