过去在多账户 AWS 架构里做数据分析,最头疼的一件事就是:数据在账户 A 的 Athena 里,QuickSight 却部署在账户 B。要么把数据复制一份过来,要么给 VPC Peering / S3 跨账户访问开一堆权限——两种方案都费钱又费时。现在 Amazon QuickSight 正式支持了跨账户 Athena 访问,用 IAM 角色链打通两个账户,查询费用还自动算到数据所在账户。下面拆解这个机制怎么工作,以及怎么一步步配起来。
角色链:跨账户授权的核心机制
所谓"角色链"(role chaining),本质上就是两步 AssumeRole:
- QuickSight 在查询账户(Account B)中用自己的服务角色,先 Assume 到一个本账户的中间角色。
- 这个中间角色再 Assume 到数据账户(Account A)中为目标 Athena 数据源专门创建的角色。
AWS IAM 在连续 AssumeRole 时,会叠加条件约束——后一个角色的有效权限是两个角色权限的交集,这天然形成了一道缩减权限的防线。同时,因为最终执行查询的身份是 Account A 的角色,Athena 的计费自然落在 Account A,不需要再做成本分摊的手工对账。
两个账户各需要配什么
数据账户(Account A)——被访问的一方
需要创建一个角色,允许 Account B 的中间角色来 Assume,并赋予对 Athena 和底层 S3 数据的必要权限。
信任策略(Trust Policy)示例:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::111111111111:role/QuickSightCrossAccountIntermediateRole"
},
"Action": "sts:AssumeRole",
"Condition": {
"StringEquals": {
"aws:SourceAccount": "222222222222"
}
}
}
]
}
111111111111是 Account A(数据账户),222222222222是 Account B(查询账户)。QuickSightCrossAccountIntermediateRole是 Account B 里即将创建的中间角色。
权限策略(Permission Policy)示例——只允许对指定 WorkGroup 和 S3 路径操作:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"athena:StartQueryExecution",
"athena:GetQueryExecution",
"athena:GetQueryResults",
"athena:StopQueryExecution",
"athena:ListDataCatalogs",
"athena:GetDataCatalog",
"athena:ListWorkGroups",
"athena:GetWorkGroup"
],
"Resource": [
"arn:aws:athena:us-east-1:111111111111:workgroup/primary",
"arn:aws:athena:us-east-1:111111111111:datacatalog/AwsDataCatalog"
]
},
{
"Effect": "Allow",
"Action": [
"s3:GetObject",
"s3:ListBucket"
],
"Resource": [
"arn:aws:s3:::my-athena-results-bucket",
"arn:aws:s3:::my-athena-results-bucket/*",
"arn:aws:s3:::my-data-source-bucket",
"arn:aws:s3:::my-data-source-bucket/*"
]
},
{
"Effect": "Allow",
"Action": [
"glue:GetDatabase",
"glue:GetTable",
"glue:GetPartitions",
"glue:BatchGetPartition"
],
"Resource": "*"
}
]
}
Athena 查询涉及三类资源:Athena WorkGroup、S3 查询结果桶、S3 数据源桶,以及 Glue 元数据。权限范围务必收紧到具体桶和 WorkGroup,不要一刀切给
*。
查询账户(Account B)——发起查询的一方
需要创建中间角色,它做两件事:允许 QuickSight 服务角色 Assume 自己,同时允许自己 Assume 到 Account A 的目标角色。
信任策略——允许 QuickSight 服务角色 Assume:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "quicksight.amazonaws.com"
},
"Action": "sts:AssumeRole",
"Condition": {
"StringEquals": {
"aws:SourceAccount": "222222222222"
}
}
}
]
}
权限策略——允许 Assume 到 Account A 的角色:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "sts:AssumeRole",
"Resource": "arn:aws:iam::111111111111:role/QuickSightCrossAccountTargetRole"
}
]
}
在 QuickSight 里挂上跨账户 Athena 数据源
角色配好后,在 QuickSight 控制台操作:
- 进入 Manage Data Sources → New data set → Athena。
- 填写 Data source name,在 AWS account ID 字段填入 Account A 的账户号(
111111111111)。 - 选择 Account A 中的 Athena WorkGroup。
- QuickSight 会自动使用角色链完成跨账户 Assume,验证连接。
如果你习惯用 CLI 或 SDK 批量创建,可以用以下命令(先确保 QuickSight 已启用跨账户权限):
aws quicksight create-data-source \
--aws-account-id 222222222222 \
--data-source-id cross-account-athena-src \
--name "CrossAccountAthena" \
--type ATHENA \
--data-source-parameters AthenaParameters='{WorkGroup="primary",RoleArn="arn:aws:iam::111111111111:role/QuickSightCrossAccountTargetRole"}'
RoleArn指向 Account A 的目标角色。QuickSight 在执行查询时会先 Assume 本账户中间角色,再 Assume 到这个 RoleArn,完成角色链。
费用归属与安全边界
这次更新最值得注意的设计决策是查询费用归属数据账户。实际场景中,这意味着:
- Account A 的 Athena 查询计量、S3 请求费用都会出现在 Account A 的 Cost Explorer 里。
- Account B 的 QuickSight 用户只产生 QuickSight 本身的订阅 / SPICE 容量费用。
- 不需要再在两个账户之间做 AWS Cost Allocation Tags 或 Billing Group 的手工分摊。
安全方面,角色链的叠加约束意味着:
- Account B 的中间角色只能 Assume 你明确列出的目标角色——不能随意跳到 Account A 的其他角色。
- Account A 的目标角色权限只给了指定 WorkGroup 和 S3 桶——即使中间角色被误配了更宽的
sts:AssumeRole权限,最终有效权限仍然被目标角色的权限策略截断。 - 建议在两个角色的信任策略中都加
aws:SourceAccount条件,防止混淆代理人(confused deputy)攻击。
上手前的检查清单
在正式部署之前,逐条确认以下事项:
| 检查项 | 说明 |
|---|---|
| Account A 目标角色已创建 | 信任策略允许 Account B 中间角色 Assume |
| Account A 目标角色权限已收紧 | Athena WorkGroup、S3 桶、Glue 操作限定到具体资源 |
| Account B 中间角色已创建 | 信任策略允许 QuickSight 服务角色 Assume |
| Account B 中间角色有 AssumeRole 权限 | 指向 Account A 目标角色的 ARN |
| S3 查询结果桶策略 | Account A 的结果桶需要允许目标角色写入,Account B 也需要能读取(如果结果桶在 Account B,则反过来配) |
| QuickSight 已启用跨账户访问 | 在 QuickSight 安全设置中确认允许跨账户 Athena |
| Cost Explorer 验证 | 在 Account A 中确认 Athena 查询费用出现,Account B 中确认只有 QuickSight 费用 |
跨账户 Athena 访问把"数据在哪里"和"分析在哪里"这两个决策彻底解耦了。多账户架构下,数据团队继续在各自账户管理数据湖和权限,分析团队在集中部署的 QuickSight 里直接查询——不用搬数据、不用对账、权限边界清晰。如果你的组织已经按数据域拆了多个 AWS 账户,这个功能值得立刻试起来。