Cloudformation嵌套堆栈,没有回滚根堆栈

时间:2019-03-07 18:33:49

标签: amazon-web-services amazon-cloudformation

我目前有一个“ master.yaml”模板,该模板运行“ service-a.yaml”和“ service-b.yaml”,然后运行“ service-c.yaml”,这依赖于service-a和service-b的输出

有没有办法将此嵌套堆栈拆分为多个嵌套堆栈?这样,当“ service-c”内部的某件事失败时,它不会在整个链中引起回滚吗?我想并行启动A + B,然后以自动方式启动C。

我可以有一个master.yaml,它可以构建“ service-a”和“ service-b”,然后在完成后手动启动“ service-c”,但是我想以某种方式使其自动化?

1 个答案:

答案 0 :(得分:1)

您可以使用Codebuild项目和Codepipeline(基本执行CI / CD)创建一个堆栈,以一个接一个地触发另一个堆栈,因此每个堆栈都会失败并分别回滚。

例如cloudformation模板将具有一个Codebuld项目,如下所示

  CodeBuildProject:
    Type: AWS::CodeBuild::Project
    Properties:
      Artifacts:
        Type: CODEPIPELINE
      Environment:
        ComputeType: BUILD_GENERAL1_LARGE
        Image: aws/codebuild/python:3.6.5
        Type: LINUX_CONTAINER
        EnvironmentVariables:
        - Name: bucket
          Value: !Ref ArtifactStoreBucket
          Type: PLAINTEXT
        - Name: prefix
          Value: build
          Type: PLAINTEXT
      Name: !Ref AWS::StackName
      ServiceRole: !Ref CodeBuildRole
      Source:
        Type: CODEPIPELINE
        BuildSpec: stack/buildspec.yaml
      Tags:
      - Key: owner
        Value: !Ref StackOwner
      - Key: task
        Value: !Ref RepositoryName

在buildspec.yaml文件中,您可以如下打包cloudfromation模板:

  - aws cloudformation package --template-file master.yaml
                               --s3-bucket $bucket --s3-prefix $prefix
                               --output-template-file master-template.yaml

  - aws cloudformation package --template-file service-a.yaml
                               --s3-bucket $bucket --s3-prefix $prefix
                               --output-template-file service-a-template.yaml

最后,是将所有内容链接在一起的代码管道阶段。例如,在下面提供的代码段中,您可以通过codecommit触发源代码。因此,每次推送到存储库都会自动建立您的管道。

  Pipeline:
    Type: AWS::CodePipeline::Pipeline
    Properties:
      ArtifactStore:
        Location: !Ref ArtifactStoreBucket
        Type: S3
      DisableInboundStageTransitions: []
      Name: !Sub "${AWS::StackName}"
      RoleArn: !GetAtt [PipelineRole, Arn]
      Stages:
      # Stage 1 - CodeUpdate Stage
      - Name: CodeUpdate
        Actions:
        - Name: SourceCodeUpdate
          ActionTypeId:
            Category: Source
            Owner: AWS
            Version: '1'
            Provider: CodeCommit
          OutputArtifacts:
          - Name: SourceCode
          Configuration:
            PollForSourceChanges: 'false'
            RepositoryName: !Ref RepositoryName
            BranchName: !Ref BranchName
          RunOrder: '1'
      # Stage 2 - Build Stage
      - Name: Build
        Actions:
        - Name: UpdateLambda
          ActionTypeId:
            Category: Build
            Owner: AWS
            Version: '1'
            Provider: CodeBuild
          InputArtifacts:
          - Name: SourceCode
          OutputArtifacts:
          - Name: BuildArtifact
          Configuration:
            ProjectName: !Ref 'CodeBuildProject'
          RunOrder: '1'
      # Stage 3 - Build master stack
      - Name: MasterSetup
        Actions:
        - Name: CreateMasterChangeset
          ActionTypeId:
            Category: Deploy
            Owner: AWS
            Version: '1'
            Provider: CloudFormation
          InputArtifacts:
          - Name: BuildArtifact
          Configuration:
            ActionMode: CHANGE_SET_REPLACE
            StackName: !Sub "${AWS::StackName}-master"
            ChangeSetName: !Sub "${AWS::StackName}-master-update"
            RoleArn: !GetAtt [CFNRole, Arn]
            TemplatePath: BuildArtifact::master-template.yaml
            Capabilities: CAPABILITY_IAM
            ParameterOverrides: !Sub
            - |
              {
                "MasterStack": "${w}",
                "StackOwner": "${x}",
                "Task": "${y}"
              }
            - {
              w: !Sub '${AWS::StackName}',
              x: !Sub '${StackOwner}',
              y: !Sub '${RepositoryName}'
            }
          RunOrder: '1'
        - Name: ExecuteMasterChangeset
          ActionTypeId:
            Category: Deploy
            Owner: AWS
            Version: '1'
            Provider: CloudFormation
          Configuration:
            ActionMode: CHANGE_SET_EXECUTE
            StackName: !Sub "${AWS::StackName}-master"
            ChangeSetName: !Sub "${AWS::StackName}-master-update"
          RunOrder: '2'
      # Stage 4 - Build service-a stack
      - Name: ServiceASetup
        Actions:
        - Name: CreateServiceAChangeset
          ActionTypeId:
            Category: Deploy
            Owner: AWS
            Version: '1'
            Provider: CloudFormation
          InputArtifacts:
          - Name: BuildArtifact
          Configuration:
            ActionMode: CHANGE_SET_REPLACE
            StackName: !Sub "${AWS::StackName}-service-a"
            ChangeSetName: !Sub "${AWS::StackName}-service-a-update"
            RoleArn: !GetAtt [CFNRole, Arn]
            TemplatePath: BuildArtifact::service-a-template.yaml
            Capabilities: CAPABILITY_IAM
            ParameterOverrides: !Sub
            - |
              {
                "MasterStack": "${w}",
                "StackOwner": "${x}",
                "Task": "${y}"
              }
            - {
              w: !Sub '${AWS::StackName}',
              x: !Sub '${StackOwner}',
              y: !Sub '${RepositoryName}'
            }
          RunOrder: '1'
        - Name: ExecuteServiceAChangeset
          ActionTypeId:
            Category: Deploy
            Owner: AWS
            Version: '1'
            Provider: CloudFormation
          Configuration:
            ActionMode: CHANGE_SET_EXECUTE
            StackName: !Sub "${AWS::StackName}-service-a"
            ChangeSetName: !Sub "${AWS::StackName}-service-a-update"
          RunOrder: '2'

如果要并行执行堆栈,则可以在每个阶段添加多个1个以上的堆栈。

很显然,您需要自己设置角色并进行存储,这应该为您提供入门的基本思路。

有关更多信息,您可以阅读有关代码管道的更多信息,如下所示: https://docs.aws.amazon.com/AmazonECS/latest/developerguide/ecs-cd-pipeline.html https://docs.aws.amazon.com/codepipeline/latest/userguide/reference-pipeline-structure.html