我正试图从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-Role
Execution角色,该角色可以完全访问Athena和S3。
有人请引导我。
为了重现这种情况,我做了以下操作:
- 在
Account-A
中,创建了一个Amazon S3存储桶(Bucket-A
(并上传了一个CSV文件 - 在
Account-B
中,创建了一个具有S3和Athena权限的IAM角色(Role-B
( - 关闭阻止
Bucket-A
上的公共访问 - 向引用
Role-B
的Bucket-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