我正在尝试创建一个AWS CodePipeline,将生产代码部署到一个单独的帐户。代码由lambda函数组成,该函数使用sam模板和cloudformation进行设置。我目前正在部署到同一帐户而没有错误。我添加了另一个具有手动批准操作的阶段,在批准后,它应该部署到另一个帐户。它失败并出现以下错误:
不允许跨帐户传递角色(服务: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"
}
]
}
我可以使用控制台假设进入生产帐户中的角色。我不确定passrole是如何不同的,但是从我读过的所有东西都需要相同的假设角色信任关系。
如何为跨账户管道配置IAM?
答案 0 :(得分:5)
通常,如果您想在多个帐户中执行任何操作,则必须在双方都允许这样做。这是通过角色假设完成的。
管道分布式部件通过管道工件进行通信,这些工件保存在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
答案 1 :(得分:0)
我认为问题在于您的CloudFormation角色位于其他帐户中,但您的操作角色却不是。只允许管道角色在其他帐户中承担操作角色。
动作角色是直接位于ActionDeclaration下的角色。
基本上您的角色应配置如下:
有关于在此设置跨帐户操作的一些信息:https://docs.aws.amazon.com/codepipeline/latest/userguide/pipelines-create-cross-account.html
此处定义了操作角色:https://docs.aws.amazon.com/codepipeline/latest/APIReference/API_ActionDeclaration.html