这是我正在尝试做的:
我在账户 A 中有由 AWS 默认加密的访问日志,账户 B 中有 lambda 和 s3 存储桶。我想在账户 A s3 存储桶上出现新对象时触发 lambda,账户 B 中的 lambda 下载数据并将其写入账户 B s3 存储桶。以下是我面临的障碍。
第一种方法:我能够将触发器从账户 A 的 s3 新对象获取到账户 B 中的 lambda,但是,账户 B 中的 lambda 无法下载该对象 - 访问被拒绝错误。寻找几天后,我认为这是因为访问日志默认是加密的,我无法将 lambda 角色添加到加密角色策略中,以便它可以加密/解密日志文件。于是转向第二种方法。
第二种方法:我已将我的 lambda 移动到账户 A。现在,源 s3 存储桶和 lambda 位于账户 A 中,目标 s3 存储桶位于账户 B 中。现在,我可以通过账户 A 中的 Lambda 处理账户 A 中的访问日志,但是当它将文件写入账户 B s3 存储桶时,我在下载/读取文件时收到访问被拒绝错误。
Lambda 角色策略: 除了完全 s3 访问和完全 lambda 访问。
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "Stmt1574387531641",
"Effect": "Allow",
"Action": "s3:*",
"Resource": "*"
},
{
"Sid": "Stmt1574387531642",
"Effect": "Allow",
"Action": "s3:*",
"Resource": [
"arn:aws:s3:::Account-B-bucket",
"arn:aws:s3:::Account-B-bucket/*"
]
}
]
}
信任关系
{ "Version": "2012-10-17", "Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "lambda.amazonaws.com",
"AWS": "arn:aws:iam::Account-B-ID:root"
},
"Action": "sts:AssumeRole"
} ] }
目标 - 账户 B s3 存储桶策略:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": [
"arn:aws:iam::Account-A-ID:role/service-role/lambda-role"
]
},
"Action": "s3:*",
"Resource": [
"arn:aws:s3:::Account-B-Bucket",
"arn:aws:s3:::Account-B-Bucket/*"
]
},
{
"Sid": "Stmt11111111111111",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::Account-A-ID:root"
},
"Action": "s3:*",
"Resource": [
"arn:aws:s3:::Account-B-Bucket",
"arn:aws:s3:::Account-B-Bucket/*"
]
}
] }
我被困在这里。我希望 lambda 能够解密访问日志并读取/处理数据并将其写入不同的账户 s3 存储桶。我错过了什么吗?非常感谢帮助!
添加文件元数据: 文件属性屏幕截图
Lambda Code:
s3 = boto3.client('s3')
# reading access logs from account A. Lambda is also running in account A.
response = s3.get_object(Bucket=access_log_bucket, Key=access_log_key)
body = response['Body']
content = io.BytesIO(body.read())
# processing access logs
processed_content = process_it(content)
# writting to account B s3 bucket
s3.put_object(Body=processed_content,
Bucket=processed_bucket,
Key=processed_key)
与其下载然后上传对象,我建议您使用copy_object()
命令。
使用copy_object()
的好处是对象将由 Amazon S3 直接复制,而无需先下载对象。
执行此操作时,您使用的凭证必须对源存储桶具有读取权限,对目标存储桶具有写入权限。(但是,如果您正在"处理"数据,这当然不适用。
作为此命令的一部分,您可以指定 ACL:
ACL='bucket-owner-full-control'
这是必需的,因为对象是从账户 A 中的凭证写入账户 B 拥有的存储桶。使用bucket-owner-full-control
会将对象的控制权传递给账户 B。 (如果使用账户 B 中的凭证并从账户 A "拉取"对象,则不需要这样做。
感谢约翰·罗滕斯坦的指导。我找到了解决方案。我只需要在put_object中添加 ACL='存储桶所有者完全控制'。以下是完整的 boto3 cmd。
s3.put_object(
ACL='bucket-owner-full-control'
Body=processed_content,
Bucket=processed_bucket,
Key=processed_key)