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

AWS CodePipeline 不遵守 CodeBuild 设置

AWS Elastic Beanstalk - CodePipeline 部署不工作 - 健康状况 - 严重