跨AWS账号:Airflow无法通过AssumeRole访问S3桶问题排查
问题场景
账号A部署了AWS Batch,账号B部署Airflow,需要让账号B的Airflow扮演账号A的IAM角色,列出账号A的S3桶对象,但配置后无法生效。提供的Terraform代码如下:
locals { trusted_account = "arn:aws:iam::11223344:root" } resource "aws_iam_role" "new_role" { name = "role_name assume_role_policy = jsonencode({ Version = "2012-10-17" Statement = [ { Effect = "Allow" Principal = { "AWS" : local.trusted_account } Action = "sts:AssumeRole" } ] }) } resource "aws_iam_role_policy" "new_role_policy" { name = "role_policy_name role = aws_iam_role.new_role.name policy = jsonencode({ Version = "2012-10-17" Statement = [ { Effect = "Allow" Action = [ "s3:ListAllMyBuckets", "s3:ListBucket" ] Resource = "*" } ] }) }
遗漏的关键配置点
字符串语法错误
角色名称和策略名称的字符串未闭合(name = "role_name缺少结尾引号),这会导致Terraform部署失败,即使手动创建角色也可能出现名称不匹配的问题,先修正语法:name = "role_name" # ... name = "role_policy_name"信任策略的主体范围过宽且未明确Airflow角色
当前信任策略允许账号B的root用户扮演角色,但实际Airflow是使用账号B中专属的IAM角色运行的,应该将信任策略的Principal指定为该Airflow角色的ARN,而不是整个账号的root。如果要允许账号B内的多个角色,也可以用账号B的ARN并配合条件限制,但更安全的是直接指定Airflow角色:Principal = { "AWS" : "arn:aws:iam::11223344:role/airflow-execution-role" }或者保持账号root但添加条件,只允许特定角色:
Statement = [ { Effect = "Allow" Principal = { "AWS" : local.trusted_account } Action = "sts:AssumeRole" Condition = { "StringEquals" : { "aws:PrincipalArn" : "arn:aws:iam::11223344:role/airflow-execution-role" } } } ]账号B的Airflow角色缺少
sts:AssumeRole权限
你只配置了账号A的待扮演角色,但账号B中Airflow使用的IAM角色必须被允许调用sts:AssumeRole去访问账号A的这个角色。需要在账号B的Airflow角色中添加如下权限策略:{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": "sts:AssumeRole", "Resource": "arn:aws:iam::[账号A-ID]:role/role_name" } ] }S3权限的精准性(可选但推荐)
当前策略中Resource="*"虽然能生效,但为了遵循最小权限原则,应该将Resource指定为账号A的目标S3桶ARN,比如:Resource = [ "arn:aws:s3:::your-target-bucket-name", "arn:aws:s3:::your-target-bucket-name/*" ]注意:
s3:ListBucket作用于桶本身(arn:aws:s3:::bucket-name),而如果需要获取对象的元数据,可能还需要补充s3:GetObject等权限(如果有需求)。S3桶策略的冲突检查
如果账号A的S3桶配置了桶策略,需要确保桶策略没有拒绝该角色的访问请求。默认情况下,桶策略不会限制同一账号内角色的访问,但如果有自定义拒绝规则,需要添加允许该角色访问的条目。
内容的提问来源于stack exchange,提问作者blackstorm

