我有一个跨帐户管道在一个帐户CI中运行,通过另一个帐户DEV中的CloudFormation部署资源。部署之后,我将工件输出保存为JSON文件,并希望通过CodeBuild在另一个管道操作中访问它。 CodeBuild在DOWNLOAD_SOURCE阶段失败,出现以下消息:
CLIENT_ERROR:AccessDenied:拒绝访问状态代码:403,请求ID:123456789,主机ID:xxxxx / yyyy / zzzz / xxxx =主源和源版本arn:aws:s3 ::: my-bucket / my-pipeline / DeployArti / XcUNqOP
问题可能是CloudFormation在不同的帐户中执行时,使用与管道本身不同的密钥加密工件。
是否有可能为CloudFormation提供一个显式的KMS密钥来加密工件,或者以其他方式如何在管道中访问这些工件?
从单个帐户中执行时,一切都有效。
这是我的代码段(部署在CI帐户中):
MyCodeBuild:
Type: AWS::CodeBuild::Project
Properties:
Artifacts:
Type: CODEPIPELINE
Environment: ...
Name: !Sub "my-codebuild"
ServiceRole: !Ref CodeBuildRole
EncryptionKey: !GetAtt KMSKey.Arn
Source:
Type: CODEPIPELINE
BuildSpec: ...
CrossAccountCodePipeline:
Type: AWS::CodePipeline::Pipeline
Properties:
Name: "my-pipeline"
RoleArn: !GetAtt CodePipelineRole.Arn
Stages:
- Name: Source
...
- Name: StagingDev
Actions:
- Name: create-stack-in-DEV-account
InputArtifacts:
- Name: SourceArtifact
OutputArtifacts:
- Name: DeployArtifact
ActionTypeId:
Category: Deploy
Owner: AWS
Version: "1"
Provider: CloudFormation
Configuration:
StackName: "my-dev-stack"
ChangeSetName: !Sub "my-changeset"
ActionMode: CREATE_UPDATE
Capabilities: CAPABILITY_NAMED_IAM
# this is the artifact I want to access from the next action
# within this CI account pipeline
OutputFileName: "my-DEV-output.json"
TemplatePath: !Sub "SourceArtifact::stack/my-stack.yml"
RoleArn: !Sub "arn:aws:iam::${DevAccountId}:role/dev-cloudformation-role"
RoleArn: !Sub "arn:aws:iam::${DevAccountId}:role/dev-cross-account-role"
RunOrder: 1
- Name: process-DEV-outputs
InputArtifacts:
- Name: DeployArtifact
ActionTypeId:
Category: Build
Owner: AWS
Version: "1"
Provider: CodeBuild
Configuration:
ProjectName: !Ref MyCodeBuild
RunOrder: 2
ArtifactStore:
Type: S3
Location: !Ref S3ArtifactBucket
EncryptionKey:
Id: !GetAtt KMSKey.Arn
Type: KMS
CloudFormation生成输出工件,对其进行拉链,然后将文件上传到S3。它不会添加ACL,后者授予对存储桶拥有者的访问权限。因此,当您尝试在管道中进一步使用CloudFormation输出工件时,会得到403。
解决方法是在ex之后的CLoudFormation操作之后立即在管道中再执行一个操作:Lambda函数可以承担目标帐户角色并更新对象acl ex:bucket-owner-full-control。
CloudFormation应使用管道工件存储定义中提供的KMS加密密钥:https://docs.aws.amazon.com/codepipeline/latest/APIReference/API_ArtifactStore.html#CodePipeline-Type-ArtifactStore-encryptionKey
因此,只要您在那里给它一个自定义密钥并允许其他帐户也使用该密钥它应该工作。
这主要包含在这个文档中:https://docs.aws.amazon.com/codepipeline/latest/userguide/pipelines-create-cross-account.html