Why do I get Access Denied errors when I use a Lambda function to upload files to an Amazon S3 bucket in another AWS account?

3 minute read
0

I get an Access Denied error when I use an AWS Lambda function to upload files to an Amazon Simple Storage Service (Amazon S3) bucket. The Amazon S3 bucket is in another AWS account. 

Short description

If the permissions between a Lambda function and an Amazon S3 bucket are incomplete or incorrect, then Lambda returns an Access Denied error.

To set up permissions between a Lambda function in one account (account 1) and an S3 bucket in another account (account 2), do the following:

1.    (In account 1) Create a Lambda execution role that allows the Lambda function to upload objects to Amazon S3.

2.    (In account 2) Modify the S3 bucket's bucket policy to allow the Lambda function to upload objects to the bucket.

Resolution

Important: The following solution requires a Lambda function in one AWS account and an S3 bucket in another account.

Example code for a Lambda function that uploads files to an S3 bucket (Python version 3.8)

import json
            import boto3
            
            s3 = boto3.client('s3')
            
            def lambda_handler(event,context):
            bucket = 'AccountBBucketName'
            transactionToUpload = {}
            transactionToUpload['transactionId'] = '12345'
            transactionToUpload['type'] = 'PURCHASE'
            transactionToUpload['amount'] = 20
            transactionToUpload['customerId'] = 'CID-1111'
            
            filename = 'CID-1111'+'.json'
            uploadByteStream = bytes(json.dumps(transactionToUpload).encode('UTF-8'))
            s3.put_object(Bucket=bucket, Key=filename, Body=uploadByteStream, ACL='bucket-owner-full-control')
            print("Put Complete")

Note: Before passing the bucket-owner-full-control ACL in the upload request, confirm that ACLs aren't deactivated on the bucket. Do this in the ownership settings of the S3 bucket. For more information, see Controlling ownership of objects and disabling ACLs for your bucket

(In account 1) Create a Lambda execution role that allows the Lambda function to upload objects to Amazon S3

1.    Create an AWS Identity and Access Management (IAM) role for your Lambda function.

2.    Copy the IAM role's Amazon Resource Name (ARN).

Note: You must get the IAM role's ARN before you can update the S3 bucket's bucket policy. One way to get the IAM role's ARN is to run the AWS Command Line Interface (AWS CLI) get-role command. If you receive errors when running AWS CLI commands, make sure that you're using the most recent version of the AWS CLI.

3.    Attach a policy to the IAM role that grants the permission to upload objects (s3:PutObject) to the bucket in Account 2.

Example IAM policy that grants an IAM role s3:PutObject and s3:PutObjectAcl permissions

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "s3:PutObject",
        "s3:PutObjectAcl"
      ],
      "Resource": "arn:aws:s3:::AccountBBucketName/*"
    }
  ]
}

4.    Change your Lambda function's execution role to the IAM role that you created. For instructions, see Configuring Lambda function options.

(In account 2) Modify the S3 bucket's bucket policy to allow the Lambda function to upload objects to the bucket

Update the bucket policy so that it specifies the Lambda execution role's ARN as a Principal that has access to the action s3:PutObject.

Example S3 bucket policy that allows a Lambda function to upload objects to the bucket

Note: The following policy also grants the Lambda function's execution role the permission to s3:PutObjectAcl.

{
            "Version": "2012-10-17",
            "Statement": [
            {
            "Effect": "Allow",
            "Principal": {
            "AWS": "arn:aws:iam::AccountA:role/AccountARole"
            },
            "Action": [
            "s3:PutObject",
            "s3:PutObjectAcl"
            ],
            "Resource": "arn:aws:s3:::AccountBBucketName/*",
            "Condition": {
            "StringEquals": {
            "s3:x-amz-acl": "bucket-owner-full-control"
            }
            }
            }
            ]
            }

Related information

How do I troubleshoot 403 Access Denied errors from Amazon S3?

AWS OFFICIAL
AWS OFFICIALUpdated a year ago