如何在不更新ECS服务任务定义的情况下更新CloudFormation堆栈

时间:2020-07-01 23:42:09

标签: amazon-cloudformation amazon-ecs

我有一个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服务?我尝试使用堆栈策略来防止对该服务进行更新,但这只会导致整个更新操作失败。

1 个答案:

答案 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等的不同版本。