跨AWS账户访问Athena:Lambda通过JDBC连接的可行性
跨AWS账户访问Athena(Lambda通过JDBC连接)
核心结论
可以实现账户B的Lambda通过JDBC访问账户A的Athena,核心是完成跨账户权限配置并调整JDBC连接参数。
必要配置步骤
步骤1:账户A配置跨账户资源权限
在账户A中,为Athena工作组、S3查询结果存储桶、Glue数据目录(若使用)添加资源级权限,允许账户B的Lambda执行角色访问:
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "AWS": "arn:aws:iam::账户B-ID:role/你的Lambda执行角色名" }, "Action": [ "athena:StartQueryExecution", "athena:GetQueryResults", "athena:GetQueryExecution", "athena:StopQueryExecution" ], "Resource": "arn:aws:athena:区域名:账户A-ID:workgroup/你的工作组名" }, { "Effect": "Allow", "Principal": { "AWS": "arn:aws:iam::账户B-ID:role/你的Lambda执行角色名" }, "Action": ["s3:GetObject", "s3:PutObject", "s3:ListBucket"], "Resource": [ "arn:aws:s3:::你的Athena查询结果桶/*", "arn:aws:s3:::你的Athena查询结果桶" ] }, { "Effect": "Allow", "Principal": { "AWS": "arn:aws:iam::账户B-ID:role/你的Lambda执行角色名" }, "Action": ["glue:GetDatabase", "glue:GetTable", "glue:GetPartition"], "Resource": [ "arn:aws:glue:区域名:账户A-ID:database/你的数据库名", "arn:aws:glue:区域名:账户A-ID:table/你的数据库名/*" ] } ] }
步骤2:账户B配置Lambda角色权限
在账户B的Lambda执行角色中,添加允许切换到账户A角色的权限(若使用角色切换方式):
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": "sts:AssumeRole", "Resource": "arn:aws:iam::账户A-ID:role/账户A跨访问角色名" } ] }
JDBC连接代码调整
方式1:通过STS AssumeRole获取临时凭证
先获取账户A的临时凭证,再传入JDBC连接属性:
import com.amazonaws.auth.STSAssumeRoleSessionCredentialsProvider; import com.amazonaws.services.securitytoken.AWSSecurityTokenService; import com.amazonaws.services.securitytoken.AWSSecurityTokenServiceClientBuilder; import java.sql.Connection; import java.sql.DriverManager; import java.util.Properties; public class AthenaCrossAccountLambda { public void handleRequest() { // 初始化STS客户端 AWSSecurityTokenService stsClient = AWSSecurityTokenServiceClientBuilder.standard() .withRegion("你的区域") .build(); // 构建跨账户凭证提供者 STSAssumeRoleSessionCredentialsProvider credentialsProvider = new STSAssumeRoleSessionCredentialsProvider.Builder( "arn:aws:iam::账户A-ID:role/账户A跨访问角色名", "lambda-cross-account-session" ).withStsClient(stsClient).build(); // 配置JDBC属性 Properties props = new Properties(); props.setProperty("s3_staging_dir", "s3://账户A的Athena查询结果桶/"); props.setProperty("aws_credentials_provider", credentialsProvider.getClass().getName()); props.setProperty("region", "你的区域"); // 建立连接并执行查询 try { Class.forName("com.simba.athena.jdbc.Driver"); Connection conn = DriverManager.getConnection("jdbc:athena:region=你的区域;", props); // 这里添加查询逻辑 conn.close(); } catch (Exception e) { e.printStackTrace(); } } }
方式2:直接指定账户A资源ARN(基于资源权限)
若已通过账户A的资源策略授权,可直接在JDBC参数中指定账户A的工作组:
import java.sql.Connection; import java.sql.DriverManager; import java.util.Properties; public class AthenaCrossAccountDirect { public void handleRequest() { Properties props = new Properties(); props.setProperty("s3_staging_dir", "s3://账户A的Athena查询结果桶/"); props.setProperty("workgroup", "arn:aws:athena:区域名:账户A-ID:workgroup/你的工作组名"); props.setProperty("catalog", "AwsDataCatalog"); props.setProperty("region", "你的区域"); try { Class.forName("com.simba.athena.jdbc.Driver"); Connection conn = DriverManager.getConnection("jdbc:athena:region=你的区域;", props); // 执行查询逻辑 conn.close(); } catch (Exception e) { e.printStackTrace(); } } }
注意事项
- 确保使用最新版本的Simba Athena JDBC驱动,避免兼容性问题。
- Lambda执行角色需拥有自身账户的STS访问权限(若使用AssumeRole方式)。
- S3查询结果桶必须归属于账户A,且权限配置完整,否则会出现读写失败。
内容的提问来源于stack exchange,提问作者user1555190
相关产品推荐
相关产品推荐

