我有一个CloudFormation堆栈,该堆栈代表了我们应用程序的整个环境(包括VPC,子网,安全组,角色,lambda函数,负载平衡器,S3存储桶和CloudFront发行版)。
除了这些以外,它还会创建带有ECS服务且具有初始任务定义的ECS集群:
Resources:
# ...snip...
Cluster:
Type: AWS::ECS::Cluster
Properties:
ClusterName: !Sub 'cluster-${Environment}'
APITaskDefinition:
Type: AWS::ECS::TaskDefinition
DependsOn:
- APIExecutionRole
Properties:
Family: !Sub 'api-${Environment}'
Cpu: 512
Memory: 1024
ExecutionRoleArn: !Ref APIExecutionRole
NetworkMode: awsvpc
RequiresCompatibilities:
- FARGATE
ContainerDefinitions:
# ...snip...
APIService:
Type: AWS::ECS::Service
DependsOn:
- LoadBalancerListenerApiHttps
- TargetGroupApi
Properties:
ServiceName: !Sub 'service-${Environment}-api'
Cluster: !Ref Cluster
TaskDefinition: !Ref APITaskDefinition
LaunchType: FARGATE
DeploymentConfiguration:
MinimumHealthyPercent: 100
MaximumPercent: 200
DesiredCount: 1
EnableECSManagedTags: true
PropagateTags: SERVICE
# ...snip...
上面的模板将服务的任务定义设置为初始/占位符任务,但是一旦创建了环境,我们就将应用程序的新版本部署到ECS(使用AWS CLI),这涉及创建新的任务定义和更新ECS服务以使用新的任务定义。
但是,当我要对CloudFormation堆栈进行与ECS不相关的更改(例如,更改CloudFront分布的属性之一)并创建更改集时,它将始终重置ECS服务以使用初始任务模板中定义的定义。
无论如何,执行堆栈更新时是否可以告诉CloudFormation不要更新ECS服务?我尝试使用堆栈策略来防止对该服务进行更新,但这只会导致整个更新操作失败。
答案 0 :(得分:1)
将最新部署的映像参考存储在SSM参数存储中,并在使用CLI部署过程成功部署后更新此SSM参数。
然后将SSM参数作为CloudFormation中的参数进行引用,例如
Parameters:
ContainerDefaultImage:
Type: AWS::SSM::Parameter::Value<String>
Description: The name of the parameter containing the image definition file to be used.
Default: /some/param/name
CloudFormation将在模板部署时解析SSM参数值。
我使用这种技术允许在不同环境中使用不同的容器版本,同时仍使用相同的模板。我的容器是在不同的管道中构建和部署的,不同的环境中部署了用于测试,UAT等的不同版本。