AWS跨账号S3桶数据同步操作

记录如何实现跨账号同步两个S3桶数据的操作.

逻辑梳理

数据源

  1. 需要设置桶策略, 允许指定ARN的Role/User访问桶内资源, 权限如下:
    • s3:GetObject
    • s3:ListBucket
    • s3:GetObjectAcl

目的地

  1. 需要创建IAM Policy, 策略权限如下:
    • 本账号权限:
      • s3:PutObject
      • s3:GetObject
      • s3:ListBucket
      • s3:PutObjectAcl
    • 数据源桶权限:
      • s3:GetObject
      • s3:ListBucket
      • s3:GetObjectAcl
  2. 策略无法作为实体单独使用, 因此需要针对不同情况, 创建IAM Role(For EC2/Lambda/etc)或IAM User(For API)

实际案例

背景介绍

我们以账号B需要从账号A复制 S3 存储桶数据为例, 信息整理如下:

类型 账号 桶名 桶策略 IAM 备注
数据源 111111111111(A) bucket_A 只需要修改桶策略
目的地 222222222222(B) bucket_B 需要创建IAM Policy & IAM Role/User

配置好后使用 AWS CLI(aws s3 sync)/SDK 进行数据复制即可,该命令类似rsync命令

操作过程

  1. 账号B中创建s3桶bucket_B, 此处==强烈建议==使用与bucket_A相同的Region

    跨Region传输数据会产生额外费用, 尤其使用了TransitGW服务, 更多细节, 见:

    1. Amazon S3 价格其中Amazon S3 数据传输定价部分
    2. Amazon Transit Gateway 定价

    截止2022-08-19, AWS S3 北京与宁夏互传价格为¥0.6/GB, TGW的流量处理费为¥0.143/GB

  2. 账号B中创建IAM Policy, 模板如下:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    {
    "Version": "2012-10-17",
    "Statement": [
    {
    "Sid": "VisualEditor0",
    "Effect": "Allow",
    "Action": [
    "s3:PutObject",
    "s3:GetObject",
    "s3:ListBucket",
    "s3:PutObjectAcl"
    ],
    "Resource": [
    "arn:aws-cn:s3:::bucket_B",
    "arn:aws-cn:s3:::bucket_B/*"
    ]
    },
    {
    "Sid": "VisualEditor1",
    "Effect": "Allow",
    "Action": [
    "s3:GetObjectAcl",
    "s3:GetObject",
    "s3:ListBucket"
    ],
    "Resource": [
    "arn:aws-cn:s3:::bucket_A",
    "arn:aws-cn:s3:::bucket_A/*"
    ]
    }
    ]
    }

  3. 账号B创建IAM Role / User, 并关联上述Policy

  4. 账号A创建/修改S3桶bucket_B的存储桶策略, 模板如下:

    • Role

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      {
      "Version": "2012-10-17",
      "Id": "Policy1519803342802",
      "Statement": [
      {
      "Sid": "Statement1",
      "Effect": "Allow",
      "Principal": {
      "AWS": "arn:aws-cn:iam::222222222222:role/RoleName"
      },
      "Action": [
      "s3:GetObject",
      "s3:ListBucket",
      "s3:GetObjectAcl"
      ],
      "Resource": [
      "arn:aws-cn:s3:::bucket_A",
      "arn:aws-cn:s3:::bucket_A/*"
      ]
      }
      ]
      }

    • User

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      {
      "Version": "2012-10-17",
      "Id": "Policy1519803342802",
      "Statement": [
      {
      "Sid": "Statement1",
      "Effect": "Allow",
      "Principal": {
      "AWS": "arn:aws-cn:iam::222222222222:user/UserName"
      },
      "Action": [
      "s3:GetObject",
      "s3:ListBucket",
      "s3:GetObjectAcl"
      ],
      "Resource": [
      "arn:aws-cn:s3:::bucket_A",
      "arn:aws-cn:s3:::bucket_A/*"
      ]
      }
      ]
      }

  5. 执行数据同步任务aws s3 sync s3://bucket_A s3://bucket_B

Q&A

使用一个挂载了上述Role的EC2执行同步操作, 报错

The provided token is malformed or otherwise invalid.

无法列出桶内文件

原因是由于默认新建的EC2是没有配置默认Region信息的, 执行aws configure后即可解决, 如下图

配置AWS默认Region信息

其中AK/SK/Format都可以不填

可以列出桶内文件了