在不同帐户中从Lambda内的AWS Athena查询S3文件时访问被拒绝



我正试图从Lambda代码中查询Athena View。为不同帐户中的S3文件创建了Athena表。Athena Query编辑器给了我以下错误:

拒绝访问(服务:Amazon S3;状态代码:403;错误代码:拒绝访问;

我尝试从Lambda代码访问Athena View。创建了Lambda执行角色,并在另一个账户S3 Bucket的Bucket策略中允许该角色,如下所示:

{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::2222222222:role/BAccountRoleFullAccess"
},
"Action": [
"s3:PutObject",
"s3:PutObjectAcl",
"s3:GetObject"
],
"Resource": "arn:aws:s3:::s3_bucket/*"
},
{
"Effect": "Allow",
"Principal": {
"AWS": [
"arn:aws:iam::111111111:role/A-Role",
"arn:aws:iam::111111111:role/B-Role"
]
},
"Action": "s3:*",
"Resource": [
"arn:aws:s3:::s3_bucket",
"arn:aws:s3:::s3_bucket/*"
]
}
]
}

来自Lambda,得到以下错误:

'Status': {'State': 'FAILED', 'StateChangeReason': 'com.amazonaws.services.s3.model.AmazonS3Exception: 
Access Denied (Service: Amazon S3; Status Code: 403; Error Code: AccessDenied; Request ID: 3A8953784EC73B17; 
S3 Extended Request ID: LfQZdTCj7sSQWcBqVNhtHrDEnJuGxgJQxvillSHznkWIr8t5TVzSaUwNSdSNh+YzDUj+S6aOUyI=), 
S3 Extended Request ID: LfQZdTCj7sSQWcBqVNhtHrDEnJuGxgJQxvillSHznkWIr8t5TVzSaUwNSdSNh+YzDUj+S6aOUyI=
(Path: s3://s3_bucket/Input/myTestFile.csv)'

此Lambda函数使用arn:aws:iam::111111111:role/B-RoleExecution角色,该角色可以完全访问Athena和S3。

有人请引导我。

为了重现这种情况,我做了以下操作:

  • Account-A中,创建了一个Amazon S3存储桶(Bucket-A(并上传了一个CSV文件
  • Account-B中,创建了一个具有S3和Athena权限的IAM角色(Role-B(
  • 关闭阻止Bucket-A上的公共访问
  • 向引用Role-BBucket-A添加bucket策略
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::[ACCOUNT-B]:role/role-b"
},
"Action": [
"s3:Get*",
"s3:List*"
],
"Resource": [
"arn:aws:s3:::bucket-a",
"arn:aws:s3:::bucket-a/*"
]
}
]
}
  • Account-B中,在Amazon Athena控制台中手动定义
  • 对雅典娜表进行了查询。不出所料,收到了Access Denied,因为我使用IAM用户访问控制台,而不是Bucket-A上Bucket Policy中定义的IAM角色
  • Account-B中创建了一个AWS Lambda函数,该函数使用Role-B
import boto3
import time
def lambda_handler(event, context):
athena_client = boto3.client('athena')
query1 = athena_client.start_query_execution(
QueryString='SELECT * FROM foo',
ResultConfiguration={'OutputLocation': 's3://my-athena-out-bucket/'}
)
time.sleep(10)
query2 = athena_client.get_query_results(QueryExecutionId=query1['QueryExecutionId'])
print(query2)
  • 运行Lambda函数。它成功地从CSV文件返回了数据

请将您的配置与我采取的上述步骤进行比较。希望你能找到一个差异,使你的跨账户访问由雅典娜。

参考资料:跨账户访问-亚马逊Athena

最新更新