こんにちは。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でも保持することができました。いざという時に、以前のリビジョンのタスク定義からコンテナを起動したいという要件も満たすことができます。
本記事が皆様のお役にたてば幸いです。
ではサウナラ~🔥