AWS CodePipeline 错误:不允许跨账户传递角色
Posted
技术标签:
【中文标题】AWS CodePipeline 错误:不允许跨账户传递角色【英文标题】:AWS CodePipeline error: Cross-account pass role is not allowed 【发布时间】:2018-06-29 23:05:25 【问题描述】:我正在尝试创建一个将生产代码部署到单独账户的 AWS CodePipeline。该代码包含一个使用 sam 模板和 cloudformation 设置的 lambda 函数。我目前将它部署到同一个帐户而没有错误。我添加了另一个具有手动批准操作的阶段,批准后它应该部署到另一个帐户。它失败并出现以下错误:
不允许跨账户传递角色(服务:AmazonCloudFormation;状态代码:403;错误代码:AccessDenied;请求 ID:d880bdd7-fe3f-11e7-8a8c-7dcffeae19ae)
我在生产帐户中有一个角色,该角色与拥有管道的开发帐户具有信任关系。我给出了管道角色和生产角色管理员策略,只是为了确保这不是策略问题。我使用walkthrough 中的技术编辑了管道。我正在松散地遵循演练,因为他们设置的场景与我所做的略有不同。
我的管道中的部署部分如下所示:
"name": "my-stack",
"actionTypeId":
"category": "Deploy",
"owner": "AWS",
"provider": "CloudFormation",
"version": "1"
,
"runOrder": 2,
"configuration":
"ActionMode": "CHANGE_SET_REPLACE",
"Capabilities": "CAPABILITY_IAM",
"ChangeSetName": "ProductionChangeSet",
"RoleArn": "arn:aws:iam::000000000000:role/role-to-assume",
"StackName": "MyProductionStack",
"TemplatePath": "BuildArtifact::NewSamTemplate.yaml"
,
"outputArtifacts": [],
"inputArtifacts": [
"name": "BuildArtifact"
]
我可以使用控制台担任生产帐户中的角色。我不确定 pas-s-role 有何不同,但从我读过的所有内容来看,它需要相同的假设角色信任关系。
如何为跨账户管道配置 IAM?
【问题讨论】:
【参考方案1】:我认为问题在于您的 CloudFormation 角色在另一个帐户中,但您的操作角色不在。仅允许管道角色在其他帐户中担任操作角色。
动作角色是直接位于 ActionDeclaration 之下的角色。
基本上你的角色应该配置如下:
管道角色:帐户 A 操作角色:帐户 B CloudFormation 角色:账户 B这里有一些关于设置跨账户操作的信息:https://docs.aws.amazon.com/codepipeline/latest/userguide/pipelines-create-cross-account.html
此处定义了操作角色:https://docs.aws.amazon.com/codepipeline/latest/APIReference/API_ActionDeclaration.html
【讨论】:
【参考方案2】:通常,如果您想跨多个帐户执行任何操作,则必须在双方都允许这样做。这是通过角色假设完成的。
管道分布式部件通过管道工件进行通信,这些工件保存在 S3 存储桶中,并使用 KMS 加密密钥进行解密/加密。此密钥必须可以从分发管道的所有帐户访问。
输入 CI 帐户
KMSKey:
Type: AWS::KMS::Key
Properties:
EnableKeyRotation: true
KeyPolicy:
Version: "2012-10-17"
Id: pipeline-kms-key
Statement:
- Sid: Allows admin of the key
Effect: Allow
Principal:
AWS: !Sub "arn:aws:iam::$AWS::AccountId:root"
Action: ["kms:*"]
Resource: "*"
- Sid: Allow use of the key from the other accounts
Effect: Allow
Principal:
AWS:
- !Sub "arn:aws:iam::$DevAccountId:root"
- !GetAtt CodePipelineRole.Arn
Action:
- kms:Encrypt
- kms:Decrypt
- kms:ReEncrypt*
- kms:GenerateDataKey*
- kms:DescribeKey
Resource: "*"
KMSAlias:
Type: AWS::KMS::Alias
Properties:
AliasName: !Sub alias/codepipeline-crossaccounts
TargetKeyId: !Ref KMSKey
S3 存储桶必须通过策略允许不同账户的访问:
CI 帐户中的管道堆栈
S3ArtifactBucketPolicy:
Type: AWS::S3::BucketPolicy
Properties:
Bucket: !Ref S3ArtifactBucket
PolicyDocument:
Statement:
- Action: ["s3:*"]
Effect: Allow
Resource:
- !Sub "arn:aws:s3:::$S3ArtifactBucket"
- !Sub "arn:aws:s3:::$S3ArtifactBucket/*"
Principal:
AWS:
- !GetAtt CodePipelineRole.Arn
- !Sub "arn:aws:iam::$DevAccountId:role/cross-account-role"
- !Sub "arn:aws:iam::$DevAccountId:role/cloudformation-role"
CodePipeline:
Type: AWS::CodePipeline::Pipeline
Properties:
ArtifactStore:
Type: S3
Location: !Ref S3ArtifactBucket
EncryptionKey:
Id: !Ref KMSKey
Type: KMS
...
管道(CI 帐户)必须具有在其他(DEV)帐户中担任角色的权限:
CI 帐户中的管道堆栈
CodePipelinePolicy:
Type: AWS::IAM::Policy
Properties:
PolicyDocument:
Statement:
- Action: ["sts:AssumeRole"]
Resource: !Sub "arn:aws:iam::$DevAccountId:role/cross-account-role
Effect: Allow
...
并且该角色必须允许被假定为管道:
DEV 帐户中的管道堆栈
CrossAccountRole:
Type: AWS::IAM::Role
Properties:
RoleName: cross-account-role
Path: /
AssumeRolePolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Principal:
AWS: !Sub "arn:aws:iam::$CIAccountId:root"
Action: sts:AssumeRole
CrossAccountPolicy:
Type: AWS::IAM::Policy
Properties:
PolicyName: CrossAccountPolicy
PolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Action:
- cloudformation:*
- codebuild:*
- s3:*
- iam:PassRole
Resource: "*"
- Effect: Allow
Action: ["kms:Decrypt", "kms:Encrypt"]
Resource: !Ref KMSKey
Roles: [!Ref CrossAccountRole]
管道(从 CI 帐户管理和执行)必须承担另一个帐户的角色才能在该帐户内执行操作:
CI 帐户中的管道堆栈
CodePipeline:
Type: AWS::CodePipeline::Pipeline
Properties:
Name: pipeline
RoleArn: !GetAtt CodePipelineRole.Arn
Stages:
...
- Name: StagingDev
Actions:
- Name: create-changeset
InputArtifacts:
- Name: BuildArtifact
OutputArtifacts: []
ActionTypeId:
Category: Deploy
Owner: AWS
Version: "1"
Provider: CloudFormation
Configuration:
StackName: app-stack-dev
ActionMode: CHANGE_SET_REPLACE
ChangeSetName: app-changeset-dev
Capabilities: CAPABILITY_NAMED_IAM
TemplatePath: "BuildArtifact::template.yml"
RoleArn: !Sub "arn:aws:iam::$DevAccountId:role/cloudformation-role" # the action will be executed with this role
RoleArn: !Sub "arn:aws:iam::$DevAccountId:role/cross-account-role" # the pipeline assume this role to execute this action
...
上面的代码展示了如何在不同的帐户中执行 CloudFormation 操作,对于 CodeBuild 或 CodeDeploy 等不同的操作,方法是相同的。
AWS 团队有一个很好的示例https://github.com/awslabs/aws-refarch-cross-account-pipeline。
另一个例子在这里https://github.com/adcreare/cloudformation/tree/master/code-pipeline-cross-account
或者你可以在这里查看我的整个工作代码https://github.com/ttulka/aws-samples/tree/master/cross-account-pipeline
【讨论】:
ttulka:谢谢。我看到了你的帖子并做了一些改动,我的管道现在可以工作了 CrossAccountPolicy 需要稍作改动。如果您在代码管道中使用 OutputFileName 从阶段输出工件,则需要额外的 KMS 权限。除了“kms:Decrypt”和“kms:Encrypt”,您还需要“kms:ReEncrypt*”、“kms:GenerateDataKey*”和“kms:DescribeKey”。这遵循 Amazon 推荐的跨账户使用 S3 的权限。以上是关于AWS CodePipeline 错误:不允许跨账户传递角色的主要内容,如果未能解决你的问题,请参考以下文章
在 AWS Codepipeline 中使用 pytest 时导入文件不匹配
Angular 7 应用程序中的 AWS Codepipeline 部署错误
由于权限错误,无法在 AWS CodePipeline 中完成部署阶段
具有 ECS 蓝/绿部署的 AWS CodePipeline 失败并出现内部错误 |拿 2