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

AWS CDK 2.63.2中CodeBuild阶段报“指定键不存在”错误

问题描述

使用以下CDK代码创建包含S3存储桶、CodeCommit和CodePipeline的CloudFormation栈:

assets = s3d.BucketDeployment(
    self,
    "codeassets",
    destination_bucket=pipeline_bucket,
    role=reader_role,
    cache_control=[
s3d.CacheControl.from_string(
    "max-age=0,no-cache,no-store,must-revalidate"
)
    ],
    memory_limit=2048,
    sources=[s3d.Source.asset(assetspath)],
)


q = codecommit.CfnRepository(
    scope=self,
    code={
        "branch_name": "main",
        "s3": {"bucket": pipeline_bucket.bucket_name, "key": "code.zip"},
    },
    id="coderepo",
    repository_name=pipeline.repo,
)
q.node.add_dependency(assets)

p = codepipeline.Pipeline(
    scope=self,
    id=f"{pipeline.name}",
    pipeline_name=f"{pipeline.name}",
    restart_execution_on_update=True,
    artifact_bucket=pipeline_bucket,
)
p.node.add_dependency(q)

尽管已正确添加依赖,但每次更新CloudFormation栈后,CodePipeline阶段都会失败,报错如下:

[Container] 2023/10/17 10:01:14 Waiting for agent ping
[Container] 2023/10/17 10:01:26 Waiting for DOWNLOAD_SOURCE
NoSuchKey: The specified key does not exist.

status code: 404, request id: 3Z90D1YGC46ZQTXZ, host id: sgsg+kiejfbfbhj+sgrf+/sg= for primary source and source version arn:aws:s3:::pipeline-name-us-east-1-63bd58d0/pipeline-name/Artifact_S/SJKGDS

出现错误的阶段代码如下:

Source阶段代码

p.add_stage(
    stage_name="Source",
    actions=[
        codepipeline_actions.CodeCommitSourceAction(
            action_name="CodeCommit",
            branch="main",
            output=source_artifact,
            trigger=codepipeline_actions.CodeCommitTrigger.EVENTS,
            repository=codecommit.Repository.from_repository_name(
                self, "source_glue_repo", repository_name=pipeline.repo
            ),
        )
    ],
)

p.add_stage(
    stage_name="UnitTests",
    actions=[
        codepipeline_actions.CodeBuildAction(
            action_name="UnitTests",
            input=source_artifact,
            project=build_project_run_tests,
            outputs=[build_artifact_run_tests],
        )
    ],
)

build_artifact_run_tests = codepipeline.Artifact()

查看S3时找不到pipeline-name/Artifact_S/文件夹,但在AWS控制台点击“Release Change”按钮后,工件文件夹会创建且流水线执行成功。需要确保Source输出工件在CodePipeline的UnitTests阶段使用前已存在于S3中。


解决方案

1. 禁用流水线自动更新触发

将restart_execution_on_update=True改为restart_execution_on_update=False。栈更新时自动触发流水线执行,此时CodeCommit仓库刚完成代码初始化,Source阶段还未生成并上传工件到S3,后续UnitTests阶段就开始读取,导致404错误。关闭自动更新后,栈部署完成后手动触发流水线,能保证Source阶段先完成工件生成。

2. 给Source动作添加显式依赖

确保CodePipeline的Source动作等待CodeCommit仓库初始化完成。修改Source阶段代码,给CodeCommitSourceAction添加依赖:

source_action = codepipeline_actions.CodeCommitSourceAction(
    action_name="CodeCommit",
    branch="main",
    output=source_artifact,
    trigger=codepipeline_actions.CodeCommitTrigger.EVENTS,
    repository=codecommit.Repository.from_repository_name(
        self, "source_glue_repo", repository_name=pipeline.repo
    ),
)
# 添加依赖,确保Source动作等待CodeCommit仓库初始化完成
source_action.node.add_dependency(q)

p.add_stage(
    stage_name="Source",
    actions=[source_action],
)

3. 用自定义资源触发流水线(保留自动触发场景)

如果需要保留自动启动逻辑,可通过自定义资源在CodeCommit仓库初始化完成后,调用API触发流水线执行:

from aws_cdk import custom_resources as cr

# 创建自定义资源,触发流水线执行
trigger_pipeline = cr.AwsCustomResource(self, "TriggerPipeline",
    on_create=cr.AwsSdkCall(
        service="CodePipeline",
        action="startPipelineExecution",
        parameters={
            "name": p.pipeline_name
        },
        physical_resource_id=cr.PhysicalResourceId.of(f"Trigger-{p.pipeline_name}")
    ),
    policy=cr.AwsCustomResourcePolicy.from_statements([
        iam.PolicyStatement(
            actions=["codepipeline:StartPipelineExecution"],
            resources=[p.pipeline_arn]
        )
    ])
)
# 确保自定义资源在CodeCommit仓库初始化后执行
trigger_pipeline.node.add_dependency(q)
# 关闭流水线自动更新,避免重复触发
p.restart_execution_on_update = False

4. 调整工件定义顺序

代码中build_artifact_run_tests = codepipeline.Artifact()在UnitTests阶段之后定义,会导致引用错误。需先定义工件再使用:

# 先定义工件
build_artifact_run_tests = codepipeline.Artifact()

p.add_stage(
    stage_name="Source",
    actions=[
        codepipeline_actions.CodeCommitSourceAction(
            action_name="CodeCommit",
            branch="main",
            output=source_artifact,
            trigger=codepipeline_actions.CodeCommitTrigger.EVENTS,
            repository=codecommit.Repository.from_repository_name(
                self, "source_glue_repo", repository_name=pipeline.repo
            ),
        )
    ],
)

p.add_stage(
    stage_name="UnitTests",
    actions=[
        codepipeline_actions.CodeBuildAction(
            action_name="UnitTests",
            input=source_artifact,
            project=build_project_run_tests,
            outputs=[build_artifact_run_tests],
        )
    ],
)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.08 12:55:58