AWS Cross Account S3 Access Through Lambda Functions
In this article, you will learn about how to set up AWS Cross Account S3 access through Lambda Functions, covering the configuration process in detail.

- An AWS account.
- Python 3, preferably the latest version.
- Basic knowledge of AWS SDK for Python (boto3).
- Create S3 Bucket
- Setup S3 bucket policy
- Setup KMS key



1
2
3
4
5
6
7
8
9
10
11
12
13
14
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "Enforce HTTPS Connections",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:I am::<<AWS Account B ID>>:role/lambda-s3-access-role"
},
"Action": "s3:*",
"Resource": "arn:aws:s3::<<AWS Account B ID>>:demo-s3-cross-account-bucket/*"
}
]
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"kms:Encrypt",
"kms:Decrypt",
"kms:DescribeKey",
"kms:GenerateDataKey*",
"kms:ReEncrypt*"
],
"Resource": [
"arn:aws:iam::<<AWS Account B ID>>:role/lambda-s3-access-role",
]
}
]
}

- Create IAM Policy and Role
- Create Lambda function
- Test Lambda and Verify



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:GetObject",
"s3:PutObject",
"s3:PutObjectAcl",
"s3:List*"
],
"Resource": [
"arn:aws:s3::<<AWS Account B ID>>:demo-s3-cross-account-bucket",
"arn:aws:s3::<<AWS Account B ID>>:demo-s3-cross-account-bucket/*"
],
"Condition": {
"StringEquals": {
"aws:SourceArn": "arn:aws:lambda:<<region>>:<<AWS Account B ID>>:function:s3-cross-account-lambda"
}
}
},
{
"Effect": "Allow",
"Action": [
"kms:Encrypt",
"kms:Decrypt",
"kms:DescribeKey",
"kms:GenerateDataKey*"
],
"Resource": [
"arn:aws:kms::<<AWS Account B ID>>:key/demo-s3-cross-account-kms-key",
]
}
]
]
}






1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
import logging
import boto3
from botocore.exceptions import ClientError
import os
def lambda_handler(event, context):
upload_file(event['file_name'], event['bucket'], event['object_name']):
def upload_file(file_name, bucket, object_name=None):
"""Upload a file to an S3 bucket
:param file_name: File to upload
:param bucket: Bucket to upload to
:param object_name: S3 object name. If not specified then file_name is used
:return: True if file was uploaded, else False
"""
# If S3 object_name was not specified, use file_name
if object_name is None:
object_name = os.path.basename(file_name)
# Upload the file
s3_client = boto3.client('s3')
try:
response = s3_client.upload_file(file_name, bucket, object_name)
except ClientError as e:
logging.error(e)
return False
return True


