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