0
votes

I have used the following 'go' code (Lambda) to copy a file, 'Sample.txt', from S3 bucket on one account to S3 bucket on another account. It works as expected i.e., it copies 'Sample.txt' from source bucket and uploads 'NewSample.txt' in the target bucket. However, I am not able to make the 'NewSample.txt' file in the destination bucket public. Due to this, I am not able to open/download that file. This is because the owner of the 'NewSample.txt' file in destination bucket is still same as the owner of 'Sample.txt' file in source bucket. If I upload another file in destination bucket manually, I could see that the new file has a different owner. Could you let me know how to copy file from S3 to S3 in another account (with owner in the destination bucket) please?

package main

import (
    "fmt"

    "github.com/aws/aws-sdk-go/aws"
    "github.com/aws/aws-sdk-go/aws/awserr"
    "github.com/aws/aws-sdk-go/aws/session"
    "github.com/aws/aws-sdk-go/service/s3"
)

// main comment
func main() {
    svc := s3.New(session.New())
    input := &s3.CopyObjectInput{
        Bucket:     aws.String("target-bucket"),
        CopySource: aws.String("/source-bucket/Sample.txt"),
        Key:        aws.String("NewSample.txt"),
    }
    result, err := svc.CopyObject(input)
    if err != nil {
        if aerr, ok := err.(awserr.Error); ok {
            switch aerr.Code() {
            case s3.ErrCodeObjectNotInActiveTierError:
                fmt.Println(s3.ErrCodeObjectNotInActiveTierError, aerr.Error())
            default:
                fmt.Println(aerr.Error())
            }
        } else {
            fmt.Println(err.Error())
        }
        return
    }

    fmt.Println(result)
}

Update#1:

NewSample.txt --> Overview tab --> Server-side encryption = Access denied

Update#2:

I used the following bucket policy

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "Test",
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::<SourceAccountId>:role/<LambdaRole>"
            },
            "Action": "s3:*",
            "Resource": [
                "arn:aws:s3:::target-bucket/*",
                "arn:aws:s3:::target-bucket"
            ]
        }
    ]
}

Update#3:

Policy summary of - arn:aws:iam::<SourceAccountId>:role/<LambdaRole>:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "s3:*"
            ],
            "Resource": [
                "arn:aws:s3:::source-bucket/*",
                "arn:aws:s3:::target-bucket/*"
            ]
        }
    ]
}

Update#4:

As @John Rotenstein told in his comment, I created a Lambda (using the exact same 'go' code but without ACL) in the account where target bucket is in and added the following bucket policy the source bucket:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "Test",
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::<TargetAccountId>:role/<LambdaRole>"
            },
            "Action": "s3:*",
            "Resource": [
                "arn:aws:s3:::source-bucket/*",
                "arn:aws:s3:::source-bucket"
            ]
        }
    ]
}

This time, without using ACL, I am able to access the object from the destination account as we are 'pulling' the object from another account. Also, the local AWS (destination) account is the owner of NewSample.txt file this time.

Update#5:

Policy summary of - arn:aws:iam::<TargetAccountId>:role/<LambdaRole>:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "s3:*"
            ],
            "Resource": [
                "arn:aws:s3:::source-bucket/*",
                "arn:aws:s3:::target-bucket/*"
            ]
        }
    ]
}
1

1 Answers

0
votes

I solved it by adding ACL as below:

input := &s3.CopyObjectInput{
        Bucket:     aws.String("target-bucket"),
        CopySource: aws.String("/source-bucket/Sample.txt"),
        Key:        aws.String("NewSample.txt"),
        ACL:        aws.String("bucket-owner-full-control"),
    }