You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过CDK创建CodePipeline部署S3中GitLab CI生成的CFN模板?

GitLab CI合成CFN模板后通过CodePipeline部署的配置方案

场景说明

  • 在GitLab Pipeline中执行cdk synth生成CloudFormation模板文件,上传至S3存储桶
  • 借助AWS CodePipeline完成模板的栈部署
  • 核心优势:GitLab侧先完成代码校验,再利用成本更低的CodePipeline执行部署流程

GitLab CI 配置代码

cdk synth > template.yml
aws s3 cp template.yml s3://testbucket/project

问题

现有CDK Pipeline代码中,CloudFormationCreateUpdateStackAction的template_path要求传入ArtifactPath类型对象,不想通过拉取整个GitLab仓库作为CodePipeline的代码源,需要更简便的配置方式。

原CDK代码片段:

from aws_cdk import Stack
from constructs import Construct
from aws_cdk import pipelines as pipelines
from aws_cdk import aws_codepipeline as codepipeline
from aws_cdk import aws_s3 as s3

class CodePipelineStack(Stack):
    def __init__(self, scope: Construct, id: str, **kwargs) -> None:
        super().__init__(scope, id, **kwargs)
        self.rcs_cdk_pipeline = codepipeline.Pipeline(
            self,
            "rcs-cdk-code-pipeline"
        )
        self.stage_source = self.rcs_cdk_pipeline.add_stage(stage_name="Source")
        self.stage_source.add_action(
            codepipeline_actions.CloudFormationCreateUpdateStackAction(
                action_name="rcs-deploy-stacks",
                stack_name="RcsRootStack",
                admin_permissions=True,
                template_path=??? # 此处应为S3地址
            )
        )

解决方案

核心思路:将S3存储桶作为CodePipeline的源,仅拉取已生成的CFN模板文件作为Artifact,再在部署阶段引用该Artifact路径。

修改后的完整CDK代码

from aws_cdk import Stack
from constructs import Construct
from aws_cdk import aws_codepipeline as codepipeline
from aws_cdk import aws_codepipeline_actions as codepipeline_actions
from aws_cdk import aws_s3 as s3

class CodePipelineStack(Stack):
    def __init__(self, scope: Construct, id: str, **kwargs) -> None:
        super().__init__(scope, id, **kwargs)
        
        # 1. 获取存储模板的S3桶(如果桶是预先创建的,用from_bucket_name导入;如果是CDK创建的,直接引用对象)
        template_bucket = s3.Bucket.from_bucket_name(self, "TemplateBucket", "testbucket")
        
        # 2. 创建一个Artifact用来存放从S3拉取的模板文件
        template_artifact = codepipeline.Artifact("TemplateArtifact")
        
        # 3. 创建CodePipeline实例
        self.rcs_cdk_pipeline = codepipeline.Pipeline(
            self,
            "rcs-cdk-code-pipeline"
        )
        
        # 4. 配置Source阶段:拉取S3中的template.yml
        source_stage = self.rcs_cdk_pipeline.add_stage(stage_name="Source")
        source_stage.add_action(
            codepipeline_actions.S3SourceAction(
                action_name="FetchTemplateFromS3",
                bucket=template_bucket,
                bucket_key="project/template.yml", # 对应GitLab CI上传的路径
                output=template_artifact
            )
        )
        
        # 5. 配置部署阶段:使用拉取到的模板部署CFN栈
        deploy_stage = self.rcs_cdk_pipeline.add_stage(stage_name="Deploy")
        deploy_stage.add_action(
            codepipeline_actions.CloudFormationCreateUpdateStackAction(
                action_name="rcs-deploy-stacks",
                stack_name="RcsRootStack",
                admin_permissions=True,
                template_path=template_artifact.at_path("template.yml") # 引用Artifact中的模板路径
            )
        )

关键细节说明

  1. S3源配置:通过S3SourceAction直接拉取指定路径下的模板文件,无需拉取整个仓库,满足轻量源的需求。
  2. Artifact引用:template_artifact.at_path("template.yml")生成符合要求的ArtifactPath对象,直接传入部署动作的template_path参数。
  3. 权限处理:CDK会自动为CodePipeline角色添加读取目标S3桶的权限;如果桶是外部创建的,需确保桶的权限策略允许CodePipeline角色访问。

可选优化:模板版本化

为避免模板被覆盖,可在GitLab CI上传时添加唯一标识(如Git提交哈希),命令修改为:

cdk synth > template.yml
TEMPLATE_FILE="template-$(git rev-parse HEAD).yml"
aws s3 cp template.yml s3://testbucket/project/${TEMPLATE_FILE}

对应CDK中S3SourceAction的bucket_key需改为动态值,或配合S3事件触发CodePipeline执行(需额外配置S3触发器)。

内容的提问来源于stack exchange,提问作者Zu Jiry

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.14 13:43:29