使用 Code Pipeline 通过 NestedStack 部署 Cloudformation
Using Code Pipeline to deploy Cloudformation with NestedStack
我正在使用代码管道部署 Cloudformation 模板。问题是这个 Cloudformation 模板有一些嵌套堆栈。 Nested Stacks 模板需要位于 S3 存储桶中。因此,在触发主(父)CF 模板之前,我需要将 CF 嵌套堆栈上传到 S3。
我没有找到使用代码管道执行此操作的方法。
有什么建议吗?
一种方法是使用 Git 挂钩将嵌套堆栈复制到 S3,例如post-接收挂钩。
另一个是在管道中添加另一个阶段来调用 Lambda 函数。您可以按照此 article 配置此步骤。当您设置 "input artifacts" 字段时,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)
我们通过添加一个使用 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:
- '**/*'
我正在使用代码管道部署 Cloudformation 模板。问题是这个 Cloudformation 模板有一些嵌套堆栈。 Nested Stacks 模板需要位于 S3 存储桶中。因此,在触发主(父)CF 模板之前,我需要将 CF 嵌套堆栈上传到 S3。
我没有找到使用代码管道执行此操作的方法。
有什么建议吗?
一种方法是使用 Git 挂钩将嵌套堆栈复制到 S3,例如post-接收挂钩。
另一个是在管道中添加另一个阶段来调用 Lambda 函数。您可以按照此 article 配置此步骤。当您设置 "input artifacts" 字段时,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)
我们通过添加一个使用 aws cloudformation package
将文件上传到 S3
这里是代码构建的示例 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:
- '**/*'