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

