使用代码管道通过NestedStack部署Cloudformation

时间:2019-08-15 13:41:27

标签: amazon-cloudformation aws-codepipeline

我正在使用代码管道来部署Cloudformation模板。问题在于此Cloudformation模板具有一些嵌套堆栈。嵌套堆栈模板必须位于S3存储桶中。因此,在触发主(父)CF模板之前,我需要将CF嵌套堆栈上传到S3。

我找不到使用代码管道执行此操作的方法。

有什么建议吗?

2 个答案:

答案 0 :(得分:1)

一种方法是使用Git钩子将嵌套堆栈复制到S3,例如接收后钩子。

另一种方法是在管道中添加另一个阶段来调用Lambda函数。您可以按照此article进行配置。设置“输入工件”字段时,CodePipeline将工件zip文件的路径作为事件的一部分传递。然后,Lambda函数提取zip文件,并将您的堆栈上传到存储桶中。

下面是一个示例Python代码,该代码将工件下载并提取到/ tmp:

import boto3
import zipfile

def lambda_handler(event, context):
    s3 = boto3.resource('s3')
    codepipeline = boto3.client('codepipeline')

    artifacts_location = event["CodePipeline.job"]["data"]["inputArtifacts"][0]["location"]["s3Location"]
    jobId = event["CodePipeline.job"]["id"]

    try:
        print("Downloading artifacts")
        s3.Bucket(artifacts_location["bucketName"]).download_file(artifact_location["objectKey"], '/tmp/artifacts.zip')
        zip_ref = zipfile.ZipFile('/tmp/artifacts.zip', 'r')
        zip_ref.extractall('/tmp')
        zip_ref.close()
    except ClientError as e:
        print("Cannot process the artifacts: {}".format(str(e)))
        codepipeline.put_job_failure_result(
           jobId=jobId,
           failureDetails={"type": 'JobFailed', "message": str(e)}
        )
        return

    # Perform the steps to copy your files from /tmp folder.
    codepipeline.put_job_success_result(jobId=jobId)

答案 1 :(得分:1)

我们通过添加一个使用aws cloudformation package来将文件上传到S3的CodeBuild操作来解决了这个问题

这是代码构建的示例buildspec.yml,显示了如何完成此操作:

version: 0.2

phases:
  build:
    commands:
      - CLOUDFORMATION_SRC_DIR="$CODEBUILD_SRC_DIR/cloudformation"
      - CFN_TMP=`mktemp` && aws cloudformation package --template-file "$CLOUDFORMATION_SRC_DIR/template.yml" --s3-bucket "my-s3-bucket" --s3-prefix "cfn_package/$CODEBUILD_BUILD_ID" --output-template-file "$CFN_TMP" && mv "$CFN_TMP" "$CLOUDFORMATION_SRC_DIR/template.yml"

artifacts:
  secondary-artifacts:
    cloudformation:
      base-directory: $CLOUDFORMATION_SRC_DIR
      files:
        - '**/*'