There are two possible situation where you’d want to move S3 objects between different AWS accounts. You could be trying to copy an object FROM a different AWS account to your account, or you could be trying to copy an object that resides on your account TO a different AWS account. In both cases the approach is similar but slightly different.
OPTION 1 – Copy FROM another account
(you are on the destination account and want to copy the data from a source account)
First, add this POLICY to the source bucket:
- DESTACCOUNT is the destination account ID
- SOURCEACCOUNT: is the source account ID
- YOURROLE: the role on the destination account that is performing the copy
- SOURCEBUCKET is the name of the bucket where the data is
- DESTINATIONBUCKET is the name of the bucket you want to copy the data to
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "DelegateS3Access",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:sts::DESTACCOUNT:assumed-role/YOURROLE"
},
"Action": [
"s3:ListBucket",
"s3:GetObject"
],
"Resource": [
"arn:aws:s3:::SOURCEBUCKET/*",
"arn:aws:s3:::SOURCEBUCKET"
]
}
]
}
Second, add this policy to the role that will perform the copy (YOURROLE):
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:ListBucket",
"s3:GetObject"
],
"Resource": [
"arn:aws:s3:::SOURCEBUCKET",
"arn:aws:s3:::SOURCEBUCKET/*"
]
},
{
"Effect": "Allow",
"Action": [
"s3:ListBucket",
"s3:PutObject",
"s3:PutObjectAcl"
],
"Resource": [
"arn:aws:s3:::DESTINATIONBUCKET",
"arn:aws:s3:::DESTINATIONBUCKET/*"
]
}
]
}
OPTION 2 – Copy TO another account
(for example, a lambda function copies the data from the account it runs to a different account)
First, add this policy to the destination bucket on the Destination Account
{
"Version": "2012-10-17",
"Id": "MyPolicyID",
"Statement": [
{
"Sid": "mySid",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::SOURCEACCOUNT:root"
},
"Action": "s3:PutObject",
"Resource": [
"arn:aws:s3:::DESTINATIONBUCKET/*",
"arn:aws:s3:::DESTINATIONBUCKET"
]
}
]
}
Second, add the exact same policy mentioned on the “second” item above to the role that will perform the copy (YOURROLE);
IMPORTANT: Object Ownership
If you are copying from account A TO account B (a lambda running on A for example), the objects on account B be will be owned by the user that performed the copy on account A. That may (definitely will) cause problems on account B, so make sure to add the “bucket-owner-full-control” ACL when copying the object. For example:
s3 = boto3.resource('s3')
copy_source = {
'Bucket': 'sourceBucket',
'Key': 'sourceKey'
}
bucket = s3.Bucket('destBucket')
extra_args = {'ACL': 'bucket-owner-full-control'}
bucket.copy(copy_source, 'destKey', extra_args)