Amazon ECS タスク定義を複数リビジョン保持させるための AWS CloudFormation テンプレートの記述テクニック [Amazon ECS+AWS CloudFormation]

こんにちは。SCSKのふくちーぬです。

みなさんは、コンテナ関連のサービスを利用したことありますでしょうか。

本記事では、ECSタスク定義をCloudFormationで管理・デプロイするときのちょっとしたテクニックをご紹介します。

ECSタスク定義をCFNで管理するとリビジョン保持することができない?

ECSタスク定義をCloudFormationで管理すると、以前のリビジョン(バージョン)を保持することができない問題があります。つまり、CloudFomrationでデプロイすると、以前のリビジョン(バージョン)が削除されて、最新のリビジョン(バージョン)のみ保持する仕様になっています。

ECSタスク定義のCloudFormationドキュメントを確認すると、各プロパティを更新すると”置換”が発生してしまうことが記載されています。これがリビジョン保持することを妨げる原因となります。

解決策:UpdateReplacePolicyを利用する

“UpdateReplacePolicy”属性を利用して、”Retain”を指定しましょう。
解決方法は、たったこれだけです。思ったより簡単ですね。

完成したCloudFromationテンプレート

以下のテンプレートを使用して、デプロイします。

AWSTemplateFormatVersion: 2010-09-09
Parameters:
  Env:
    Type: String
    AllowedValues:
      - TEST
      - STG
      - PROD  
Resources:
  # ================================
  # ECS (Task Difinition)
  # ================================          
  ECSTaskDefinition:
    Type: "AWS::ECS::TaskDefinition"
    UpdateReplacePolicy: Retain #この記述を追加
    Properties:
      Cpu: 256
      ExecutionRoleArn: !Sub "arn:aws:iam::${AWS::AccountId}:role/ecsTaskExecutionRole"
      Family: !Sub "ECS-${Env}-helloworld-taskdef"
      Memory: 512
      NetworkMode: awsvpc
      RequiresCompatibilities:
        - FARGATE
      ContainerDefinitions:
        - Name: helloworld
          Image: !Sub "${AWS::AccountId}.dkr.ecr.${AWS::Region}.amazonaws.com/helloworld-appliction:v1.0"
          LogConfiguration:
            LogDriver: awslogs
            Options:
              awslogs-group: !Sub "/ecs/ECS-${Env}-helloworld-service"
              awslogs-region: !Ref AWS::Region
              awslogs-stream-prefix: v1.0
          PortMappings:
            - AppProtocol: http
              HostPort: 80
              Protocol: tcp
              ContainerPort: 80
              Name: helloworld-80-tcp
          ReadonlyRootFilesystem: false
      RuntimePlatform: 
        CpuArchitecture: X86_64
        OperatingSystemFamily: LINUX
      Tags:
        - Key: Name
          Value: !Sub "ECS-${Env}-helloworld-taskdef"

ECSタスク定義の更新

上記でデプロイしたタスク定義を更新して、リビジョン2を作成することにします。

以下のテンプレートを使用して、スタックを更新します。

AWSTemplateFormatVersion: 2010-09-09
Parameters:
  Env:
    Type: String
    AllowedValues:
      - TEST
      - STG
      - PROD  
Resources:
  # ================================
  # ECS (Task Difinition)
  # ================================          
  ECSTaskDefinition:
    Type: "AWS::ECS::TaskDefinition"
    UpdateReplacePolicy: Retain
    Properties:
      Cpu: 256
      ExecutionRoleArn: !Sub "arn:aws:iam::${AWS::AccountId}:role/ecsTaskExecutionRole"
      Family: !Sub "ECS-${Env}-helloworld-taskdef"
      Memory: 512
      NetworkMode: awsvpc
      RequiresCompatibilities:
        - FARGATE
      ContainerDefinitions:
        - Name: helloworld
          Image: !Sub "${AWS::AccountId}.dkr.ecr.${AWS::Region}.amazonaws.com/helloworld-appliction:v1.1" #コンテナイメージの更新
          LogConfiguration:
            LogDriver: awslogs
            Options:
              awslogs-group: !Sub "/ecs/ECS-${Env}-helloworld-service"
              awslogs-region: !Ref AWS::Region
              awslogs-stream-prefix: v1.1 #ロググループの更新
          PortMappings:
            - AppProtocol: http
              HostPort: 80
              Protocol: tcp
              ContainerPort: 80
              Name: helloworld-80-tcp
          ReadonlyRootFilesystem: false
      RuntimePlatform: 
        CpuArchitecture: X86_64
        OperatingSystemFamily: LINUX
      Tags:
        - Key: Name
          Value: !Sub "ECS-${Env}-helloworld-taskdef"

タスク定義のリビジョン2が作成され、以前のバージョンも保持されていることが分かります。

注意事項

・タスク定義のファミリー名は、慎重に名前付けを決定した後にデプロイすること

タスク定義のリビジョンは、ファミリー名に基づいています。タスク定義を削除したとしても、内部でファミリー名が記録されているため、リビジョンを以前のものから引き継ぎます。リビジョンを”1″から採番したい場合は、異なるファミリー名で再作成することが必要です。

まとめ

いかがだったでしょうか。以前のリビジョンのタスク定義をCloudFromationでも保持することができました。いざという時に、以前のリビジョンのタスク定義からコンテナを起動したいという要件も満たすことができます。

本記事が皆様のお役にたてば幸いです。

ではサウナラ~🔥

タイトルとURLをコピーしました