AWS CodePipeline错误:不允许跨账户传递角色

joh*_*oop 2 amazon-web-services aws-cloudformation amazon-iam aws-codepipeline

我正在尝试创建一个将生产代码部署到一个单独账户的AWS CodePipeline。该代码包含一个lambda函数,该函数使用sam模板和cloudformation进行设置。我目前将它部署到同一帐户,没有错误。我添加了另一个阶段,该阶段具有手动批准操作,批准后应该部署到另一个帐户。失败并显示以下错误:

不允许跨帐户传递角色(服务:AmazonCloudFormation;状态代码:403;错误代码:AccessDenied;请求ID:d880bdd7-fe3f-11e7-8a8c-7dcffeae19ae)

我在生产帐户中扮演一个角色,该帐户与建立管道的开发帐户具有信任关系。我提供了管道角色和生产角色管理员策略,只是为了确保这不是策略问题。我在本演练中使用该技术编辑了管道。由于他们设置的场景与我正在做的稍有不同,因此我会随意地浏览本演练。

我的管道中的deploy部分如下所示:

{
   "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"
      }
   ]
}
Run Code Online (Sandbox Code Playgroud)

我可以使用控制台承担生产帐户中的角色。我不确定passrole有何不同,但是从我读过的所有内容来看,它都需要相同的假定角色信任关系。

如何为跨帐户管道配置IAM?

ttu*_*lka 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
Run Code Online (Sandbox Code Playgroud)

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
    ...
Run Code Online (Sandbox Code Playgroud)

管道(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
          ...
Run Code Online (Sandbox Code Playgroud)

而且必须让这个角色扮演管道的角色:

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]
Run Code Online (Sandbox Code Playgroud)

管道(通过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
  ...
Run Code Online (Sandbox Code Playgroud)

上面的代码显示了如何在不同的帐户中执行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


Tim*_*imB 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