【问题标题】:AWS CodePipeline error: Cross-account pass role is not allowedAWS CodePipeline 错误:不允许跨账户传递角色
【发布时间】: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"
      }
   ]
}

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

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

【问题讨论】:

    标签: amazon-web-services amazon-cloudformation amazon-iam aws-codepipeline


    【解决方案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 的权限。
      猜你喜欢
      • 1970-01-01
      • 2018-01-08
      • 2017-03-16
      • 2016-11-02
      • 1970-01-01
      • 1970-01-01
      • 2020-10-07
      • 2015-07-11
      • 1970-01-01
      相关资源
      最近更新 更多