设置 IAM 的跨账户访问 user/role

Setting up cross account access of IAM user/role

我有一个主账户用户,我想允许其访问子账户 S3 存储桶。我在我的子账户中设置了以下堆栈

AWSTemplateFormatVersion : '2010-09-09'
Description: 'Skynet stack to allow admin account deploying user to access S3'

Parameters:
  AccountId:
    Type: String
    Description: Account ID of admin account (containing user to allow)
  Username:
    Type: String
    Description: Username to be allowed access
  BucketPrefix:
    Type: String
    Description: Bucket to be allowed (prefix appended with -{AccountId}-{Region})

Resources:
  CrossAccountRole:
    Type: AWS::IAM::Role
    Properties:
      AssumeRolePolicyDocument:
        Statement:
          - Effect: Allow
            Action: sts:AssumeRole
            Principal:
              AWS:
                - !Sub arn:aws:iam::${AccountId}:user/${Username}
      Path: /
      Policies:
        - PolicyName: skynet-s3-delegate
          PolicyDocument:
            Statement:
              - Effect: Allow
                Action:
                  - s3:ListBucket
                  - s3:GetObject
                Resource: "*"

但是我发现当我尝试承担这个角色时仍然会报错:

aws s3 cp skynet-lambda.zip s3://skynet-lambda-TARGET_ACCOUNT_ID-ap-southeast-1 --profile skynetci-cross-account

An error occurred (AccessDenied) when calling the AssumeRole operation: User: arn:aws:iam::MAIN_ACCOUNT_ID:user/circleci-skynet is not authorized to perform: sts:AssumeRole on resource: arn:aws:iam::TARGET_ACCOUNT_ID:role/StackSet-df0e85b0-d6fd-47bf-a0bb-CrossAccountRole-1EW45TXEFAY0D

考虑到我已经为用户制定了以下政策,为什么会这样

    {
        "Effect": "Allow",
        "Action": [
            "sts:AssumeRole"
        ],
        "Resource": "arn:aws:iam::TARGET_ACCOUNT_ID:role/StackSet-df0e85b0-d6fd-47bf-a0bb-CrossAccountRole-1EW45TXEFAY0D"
    }

您需要更新存储桶策略以允许跨账户访问,示例策略如下:

{
   "Version": "2012-10-17",
   "Statement": [
      {
         "Sid": "Example permissions",
         "Effect": "Allow",
         "Principal": {
            "AWS": "arn:aws:iam::AccountB-ID:root"
         },
         "Action": [
            "s3:*"
         ],
         "Resource": [
            "arn:aws:s3:::examplebucket"
         ]
      }
   ]
}

同时确保尝试访问的 IAM 用户附加了此内联策略:

{
   "Version": "2012-10-17",
   "Statement": [
      {
         "Sid": "Example",
         "Effect": "Allow",
         "Action": [
            "s3:*"
         ],
         "Resource": [
            "arn:aws:s3:::examplebucket"
         ]
      }
   ]
}

可以参考AWS Documentation

要实现您的目标,您需要在目标 S3 存储桶中设置存储桶策略:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "DelegateS3Access",
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::MAIN_ACCOUNT_ID:USER_NAME"
            },
            "Action": "s3:*",
            "Resource": [
                "arn:aws:s3:::BUCKET_NAME/*",
                "arn:aws:s3:::BUCKET_NAME"
            ]
        }
    ]
}

并允许此用户具有 S3 权限。

{
   "Version": "2012-10-17",
   "Statement": [
      {
         "Sid": "Example",
         "Effect": "Allow",
         "Action": [
            "s3:*"
         ],
         "Resource": [
             "*"            
         ]
      }
   ]
}

在这种情况下,您不需要在目标帐户上担任角色。用户本身将能够访问另一个帐户中的存储桶。

我附上了一个我使用我的两个帐户测试过的工作示例。

第 1 步:CloudFormation YAML 模板:

AWSTemplateFormatVersion : '2010-09-09'
Description: 'Skynet stack to allow admin account deploying user to access S3'

Parameters:
  AccountId:
    Type: String
    Description: Account ID of admin account (containing user to allow)
  Username:
    Type: String
    Description: Username to be allowed access
  BucketPrefix:
    Type: String
    Description: Bucket to be allowed (prefix appended with -{AccountId}-{Region})

Resources:
  CrossAccountRole:
    Type: AWS::IAM::Role
    Properties:
      AssumeRolePolicyDocument:
        Statement:
          - Effect: Allow
            Action: sts:AssumeRole
            Principal:
              AWS:
                - !Sub arn:aws:iam::${AccountId}:user/${Username}
      Path: /
      Policies:
        - PolicyName: skynet-s3-delegate
          PolicyDocument:
            Statement:
              - Effect: Allow
                Action:
                  - s3:ListBucket
                  - s3:GetObject
                Resource: "*"
  RootInstanceProfile: 
    Type: "AWS::IAM::InstanceProfile"
    Properties: 
      Path: "/"
      Roles: 
          - 
            Ref: "CrossAccountRole"

第 2 步:创建跨帐户配置文件

修改~/.aws/credentials。添加名为 "skynetci-cross-account" 的新配置文件。根据您在步骤 1 中创建的参数进行修改。您将需要角色 arn 来替换下面的角色。您还需要您授予权限的帐户的个人资料名称。在此示例中,配置文件名称为 "default".

此处示例:

[skynetci-cross-account]
role_arn = arn:aws:iam::191070ABCDEF:role/Test-CrossAccountRole-IZDDLRUMABCD
source_profile = default

第 3 步:测试交叉访问

aws --profile skynetci-cross-account s3 ls s3://bucket-name