AWS 提供从另一个账户访问代入角色以访问我账户中的 S3
AWS Providing access to assumed role from another account to access S3 in my account
我想要实现的是将一个帐户(A1 - 不受我控制)中的 S3 中的对象复制到另一个帐户(A2 - 由我控制)中的 S3 中。
因为来自 A1 的 OPS 为我提供了一个我可以承担的角色,使用 boto3 库。
session = boto3.Session()
sts_client = session.client('sts')
assumed_role = sts_client.assume_role(
RoleArn="arn:aws:iam::1234567890123:role/organization",
RoleSessionName="blahblahblah"
)
这部分还可以。
问题是从 S3 到 S3 的直接复制失败,因为该假定角色无法访问我的 S3。
s3 = boto3.resource('s3')
copy_source = {
'Bucket': a1_bucket_name,
'Key': key_name
}
bucket = s3.Bucket(a2_bucket_name)
bucket.copy(copy_source, hardcoded_key)
结果我得到
botocore.exceptions.ClientError: An error occurred (403) when calling the HeadObject operation: Forbidden
在这行代码中:
bucket.copy(copy_source, hardcoded_key)
有什么方法可以授予该假定角色访问我的 S3 的权限?
我真的很想直接从 S3 复制到 S3,而无需在本地下载文件,然后再重新上传。
请告知是否有比这更好的方法。
例如,我的想法是每天将此脚本 运行 放入 AWS Data Pipeline 中。
这是使用 boto 3 在具有 2 个不同 AWS 帐户的两个 S3 存储桶之间传输数据的示例代码。
from boto.s3.connection import S3Connection
from boto.s3.key import Key
from Queue import LifoQueue
import threading
source_aws_key = '*******************'
source_aws_secret_key = '*******************'
dest_aws_key = '*******************'
dest_aws_secret_key = '*******************'
srcBucketName = '*******************'
dstBucketName = '*******************'
class Worker(threading.Thread):
def __init__(self, queue):
threading.Thread.__init__(self)
self.source_conn = S3Connection(source_aws_key, source_aws_secret_key)
self.dest_conn = S3Connection(dest_aws_key, dest_aws_secret_key)
self.srcBucket = self.source_conn.get_bucket(srcBucketName)
self.dstBucket = self.dest_conn.get_bucket(dstBucketName)
self.queue = queue
def run(self):
while True:
key_name = self.queue.get()
k = Key(self.srcBucket, key_name)
dist_key = Key(self.dstBucket, k.key)
if not dist_key.exists() or k.etag != dist_key.etag:
print 'copy: ' + k.key
self.dstBucket.copy_key(k.key, srcBucketName, k.key, storage_class=k.storage_class)
else:
print 'exists and etag matches: ' + k.key
self.queue.task_done()
def copyBucket(maxKeys = 1000):
print 'start'
s_conn = S3Connection(source_aws_key, source_aws_secret_key)
srcBucket = s_conn.get_bucket(srcBucketName)
resultMarker = ''
q = LifoQueue(maxsize=5000)
for i in range(10):
print 'adding worker'
t = Worker(q)
t.daemon = True
t.start()
while True:
print 'fetch next 1000, backlog currently at %i' % q.qsize()
keys = srcBucket.get_all_keys(max_keys = maxKeys, marker = resultMarker)
for k in keys:
q.put(k.key)
if len(keys) < maxKeys:
print 'Done'
break
resultMarker = keys[maxKeys - 1].key
q.join()
print 'done'
if __name__ == "__main__":
copyBucket()
要将对象从一个 S3 存储桶复制到另一个 S3 存储桶,您需要使用一组可以访问两个存储桶的 AWS 凭证。
如果这些存储桶位于不同的 AWS 账户中,您需要两件事:
- 目标 存储桶的凭据,以及
- 源存储桶上的存储桶策略允许对目标 AWS 账户进行读取访问。
仅凭这些,您就可以复制对象。您不需要源帐户的凭据。
- 将存储桶策略添加到您的 source 存储桶,允许对目标 AWS 账户进行读取访问。
这是一个示例政策:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "DelegateS3Access",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::123456789012:root"
},
"Action": "s3:*",
"Resource": [
"arn:aws:s3:::BUCKET_NAME",
"arn:aws:s3:::BUCKET_NAME/*"
]
}
]
}
请务必将 BUCKET_NAME
替换为您的 source 存储桶名称。并将 123456789012
替换为您的 target AWS 帐号。
- 使用您的目标 AWS 账户(目标存储桶的所有者)的凭据,执行复制。
补充说明:
你也可以通过颠倒两个要求来复制对象:
- 源 AWS 账户的凭证,以及
- 目标存储桶上的存储桶策略允许 写入 访问源 AWS 账户。
但是,以这种方式完成后,对象元数据无法正确复制。我已经和AWS Support讨论过这个问题,他们建议从国外账户读取而不是写入国外账户来避免这个问题。
我想要实现的是将一个帐户(A1 - 不受我控制)中的 S3 中的对象复制到另一个帐户(A2 - 由我控制)中的 S3 中。 因为来自 A1 的 OPS 为我提供了一个我可以承担的角色,使用 boto3 库。
session = boto3.Session()
sts_client = session.client('sts')
assumed_role = sts_client.assume_role(
RoleArn="arn:aws:iam::1234567890123:role/organization",
RoleSessionName="blahblahblah"
)
这部分还可以。 问题是从 S3 到 S3 的直接复制失败,因为该假定角色无法访问我的 S3。
s3 = boto3.resource('s3')
copy_source = {
'Bucket': a1_bucket_name,
'Key': key_name
}
bucket = s3.Bucket(a2_bucket_name)
bucket.copy(copy_source, hardcoded_key)
结果我得到
botocore.exceptions.ClientError: An error occurred (403) when calling the HeadObject operation: Forbidden
在这行代码中:
bucket.copy(copy_source, hardcoded_key)
有什么方法可以授予该假定角色访问我的 S3 的权限? 我真的很想直接从 S3 复制到 S3,而无需在本地下载文件,然后再重新上传。
请告知是否有比这更好的方法。
例如,我的想法是每天将此脚本 运行 放入 AWS Data Pipeline 中。
这是使用 boto 3 在具有 2 个不同 AWS 帐户的两个 S3 存储桶之间传输数据的示例代码。
from boto.s3.connection import S3Connection
from boto.s3.key import Key
from Queue import LifoQueue
import threading
source_aws_key = '*******************'
source_aws_secret_key = '*******************'
dest_aws_key = '*******************'
dest_aws_secret_key = '*******************'
srcBucketName = '*******************'
dstBucketName = '*******************'
class Worker(threading.Thread):
def __init__(self, queue):
threading.Thread.__init__(self)
self.source_conn = S3Connection(source_aws_key, source_aws_secret_key)
self.dest_conn = S3Connection(dest_aws_key, dest_aws_secret_key)
self.srcBucket = self.source_conn.get_bucket(srcBucketName)
self.dstBucket = self.dest_conn.get_bucket(dstBucketName)
self.queue = queue
def run(self):
while True:
key_name = self.queue.get()
k = Key(self.srcBucket, key_name)
dist_key = Key(self.dstBucket, k.key)
if not dist_key.exists() or k.etag != dist_key.etag:
print 'copy: ' + k.key
self.dstBucket.copy_key(k.key, srcBucketName, k.key, storage_class=k.storage_class)
else:
print 'exists and etag matches: ' + k.key
self.queue.task_done()
def copyBucket(maxKeys = 1000):
print 'start'
s_conn = S3Connection(source_aws_key, source_aws_secret_key)
srcBucket = s_conn.get_bucket(srcBucketName)
resultMarker = ''
q = LifoQueue(maxsize=5000)
for i in range(10):
print 'adding worker'
t = Worker(q)
t.daemon = True
t.start()
while True:
print 'fetch next 1000, backlog currently at %i' % q.qsize()
keys = srcBucket.get_all_keys(max_keys = maxKeys, marker = resultMarker)
for k in keys:
q.put(k.key)
if len(keys) < maxKeys:
print 'Done'
break
resultMarker = keys[maxKeys - 1].key
q.join()
print 'done'
if __name__ == "__main__":
copyBucket()
要将对象从一个 S3 存储桶复制到另一个 S3 存储桶,您需要使用一组可以访问两个存储桶的 AWS 凭证。
如果这些存储桶位于不同的 AWS 账户中,您需要两件事:
- 目标 存储桶的凭据,以及
- 源存储桶上的存储桶策略允许对目标 AWS 账户进行读取访问。
仅凭这些,您就可以复制对象。您不需要源帐户的凭据。
- 将存储桶策略添加到您的 source 存储桶,允许对目标 AWS 账户进行读取访问。
这是一个示例政策:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "DelegateS3Access",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::123456789012:root"
},
"Action": "s3:*",
"Resource": [
"arn:aws:s3:::BUCKET_NAME",
"arn:aws:s3:::BUCKET_NAME/*"
]
}
]
}
请务必将 BUCKET_NAME
替换为您的 source 存储桶名称。并将 123456789012
替换为您的 target AWS 帐号。
- 使用您的目标 AWS 账户(目标存储桶的所有者)的凭据,执行复制。
补充说明:
你也可以通过颠倒两个要求来复制对象:
- 源 AWS 账户的凭证,以及
- 目标存储桶上的存储桶策略允许 写入 访问源 AWS 账户。
但是,以这种方式完成后,对象元数据无法正确复制。我已经和AWS Support讨论过这个问题,他们建议从国外账户读取而不是写入国外账户来避免这个问题。