我在同步附加到两个单独 AWS 账户的两个 S3 存储桶时遇到问题。
有两个 AWS 账户 - 由第三方管理的账户 A 和我管理的账户 B。我希望将文件从账户 A 中的 S3 存储桶拉取到账户 B 中的 S3 存储桶。
帐户 A 为我提供了以下说明:
- 在账户 B 中,创建一个名为
LogsUser
的新 IAM 用户。将以下策略附加到用户:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "sts:AssumeRole",
"Resource": "arn:aws:iam::ACCOUNTID:role/12345-LogAccess-role"
}
]
}
配置AWS CLI 以更新配置和凭证文件。具体来说,
~/.aws/config
文件如下所示:[profile LogsUser] role_arn = arn:aws:iam::ACCOUNTID:role/12345-LogAccess-role source_profile = LogsUser
和
~/.aws/credentials
文件看起来像aws_access_key_id = YOUR_ACCESS_KEY_ID aws_secret_access_key = YOUR_SECRET_ACCESS_KEY
从这里,我能够使用
$ aws s3 ls --profile LogsUser s3://bucket-a
成功查询账户 A 存储桶中的日志文件。
我已经在帐户 B 中设置了bucket-b
,但是,我无法查询bucket-b
中的任何文件。例如,$ aws s3 ls --profile LogsUser s3://bucket-b
返回An error occurred (AccessDenied) when calling the AssumeRole operation: Access denied
.
我是否可以向配置文件或我的 IAM 策略添加其他内容以允许使用--profile LogsUser
选项访问bucket-b
?我可以使用其他--profile
设置访问bucket-b
,但我不希望同步到本地文件系统,然后再同步到另一个存储桶。
所需的结果是运行类似aws s3 sync s3://bucket-a s3://bucket-b --profile UserLogs
的命令。
例如,如果要将"账户 A"S3 存储桶对象复制到"账户 B"S3 存储桶,请执行以下操作。
在"账户 A"中为 S3 存储桶创建策略,如以下策略所示。为此,您需要"帐户B"号码,要找到B帐号,请转到支持→支持中心并从那里复制帐号。
设置"账户 A"存储桶策略:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "DelegateS3Access",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::ACCOUNT_B_NUMBER:root"
},
"Action": [
"s3:ListBucket",
"s3:GetObject"
],
"Resource": [
"arn:aws:s3:::ACCOUNT_A_BUCKET_NAME/*",
"arn:aws:s3:::ACCOUNT_A_BUCKET_NAME"
]
}
]
}
登录"账户 B"并创建新的 IAM 用户或为现有用户附加以下策略。
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:ListBucket",
"s3:GetObject"
],
"Resource": [
"arn:aws:s3:::ACCOUNT_A_BUCKET_NAME",
"arn:aws:s3:::ACCOUNT_A_BUCKET_NAME/*"
]
},
{
"Effect": "Allow",
"Action": [
"s3:ListBucket",
"s3:PutObject",
"s3:PutObjectAcl"
],
"Resource": [
"arn:aws:s3:::ACCOUNT_B_BUCKET_NAME",
"arn:aws:s3:::ACCOUNT_B_BUCKET_NAME/*"
]
}
]
}
使用"账户 B"IAM 用户配置 AWS CLI(您已使用上述用户策略创建了 IAM)
aws s3 sync s3://ACCOUNT_A_BUCKET_NAME s3://ACCOUNT_B_BUCKET_NAME --source-region ACCOUNT_A_REGION-NAME --region ACCOUNT_B_REGION-NAME
这样,我们就可以通过不同的 AWS 账户复制 S3 存储桶对象。
如果您有多个 awscli 配置文件,请使用带有配置文件名称--profile
命令末尾。
您的情况是:
- 您希望从
Bucket-A
复制Account-A
- 这些文件需要复制到
Bucket-B
Account-B
Account-A
为您提供了在Account-A
中承担LogAccess-role
的能力,从而可以访问Bucket-A
使用CopyObject()
命令(由 AWS CLIsync
命令使用)在存储桶之间复制文件时,它需要:
- 源存储桶上的读取访问权限 (
Bucket-A
) - 目标存储桶上的写入权限 (
Bucket-B
)
当您承担LogAccess-role
时,您会收到对Bucket-A
具有读取访问权限的凭据。真棒!但是,这些凭据无权写入Bucket-B
,因为它位于单独的帐户中。
要解决此问题,您应该在存储桶 A 上创建一个存储桶策略,该策略授予对来自Account-B
LogAccess-role
的写入访问权限。存储桶策略如下所示:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::ACCOUNT-A:role/12345-LogAccess-role"
},
"Action": [
"s3:ListBucket",
"s3:PutObject"
],
"Resource": [
"arn:aws:s3:::bucket-a",
"arn:aws:s3:::bucket-a/*"
]
}
]
}
(您可能需要其他权限。检查任何错误消息以获取提示。
这样,LogAccess-role
将能够读取Bucket-A
并写入Bucket-B
。
我建议您考虑使用 AWS S3 存储桶复制:
https://docs.aws.amazon.com/AmazonS3/latest/dev/crr.html
如果您只想列出bucket-b
中的对象,请执行此操作。
首先确保 LogsUser IAM 用户具有访问账户 B 中bucket-b
s3 存储桶的适当权限。如果没有,则可以将此策略添加到用户
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:*"
],
"Resource": [
"arn:aws:s3:::bucket-b/*"
]
}
]
}
如果用户附加了权限,并且存储在~/.aws/credentials
存储为[default]
的访问密钥和私有密钥属于 LogsUser IAM 用户,则只需使用以下命令列出bucket-b
中的对象即可。aws s3 ls
如果要运行命令aws s3 sync s3://bucket-a s3://bucket-b --profile UserLogs
,请执行此操作。
请记住,我们将使用具有 LogsUser 永久凭证的角色后使用 STS 创建的临时凭证。这意味着账户 A 中的角色应具有对两个存储桶的适当访问权限以执行操作,而另一个账户(账户 B)中的存储桶(bucket-b
)应具有适当的存储桶策略,以允许该角色执行 S3 操作。
要向角色提供访问bucket-b
的权限,请将以下存储桶策略附加到bucket-b
。
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::ACCOUNTID:role/12345-LogAccess-role"
},
"Action": [
"s3:*"
],
"Resource": [
"arn:aws:s3:::bucket-b/*"
]
}
]
}
同样在账户 A 中,将策略附加到角色,如下所示,以允许访问两个账户中的 S3 存储桶。
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:*"
],
"Resource": [
"arn:aws:s3:::bucket-b/*",
"arn:aws:s3:::bucket-a/*"
]
}
]
}