如何限制仅通过Terraform调用才能访问Terraformer角色?
AWS目前没有提供类似CloudFormation aws:CalledVia的专属条件键,来直接限制角色只能被Terraform上下文调用。这是因为Terraform本质上是通过AWS SDK发起API请求,AWS无法直接区分请求是否来自Terraform还是其他使用SDK的应用。
不过可以通过以下几种间接方式提升角色安全性,限制非Terraform场景下的直接假设:
1. 使用External ID验证
在Terraformer角色的信任策略中添加sts:ExternalId条件,要求假设角色时必须携带预设的外部ID。只有在Terraform配置中指定该ID的请求才能成功假设角色,直接手动调用sts:AssumeRole时如果没有提供正确ID会被拒绝。
角色信任策略示例:
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "AWS": "arn:aws:iam::123456789012:user/YourTerraformRunner" }, "Action": "sts:AssumeRole", "Condition": { "StringEquals": { "sts:ExternalId": "your-unique-external-id" } } } ] }
Terraform Provider配置对应修改:
provider "aws" { assume_role { role_arn = "arn:aws:iam::123456789012:role/Terraformer" external_id = "your-unique-external-id" } }
2. 限制请求来源IP
如果Terraform固定在特定IP环境(比如公司办公网、CI/CD服务器)运行,可以在角色信任策略中添加aws:SourceIp条件,只允许指定IP段的请求假设角色。
信任策略条件示例:
"Condition": { "IpAddress": { "aws:SourceIp": ["192.168.1.0/24", "203.0.113.10/32"] } }
3. 结合会话标签与权限边界
在角色信任策略中要求假设角色时必须携带特定会话标签,同时在角色的权限策略中限制只有带有该标签的会话才能执行操作。这种方式无法阻止角色被直接假设,但能限制假设后的权限使用范围。
信任策略要求标签示例:
"Condition": { "StringEquals": { "sts:SessionTag/TerraformInvocation": "true" } }
Terraform Provider配置添加标签:
provider "aws" { assume_role { role_arn = "arn:aws:iam::123456789012:role/Terraformer" tags = { TerraformInvocation = "true" } } }
角色权限策略限制示例:
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": "ec2:*", "Resource": "*", "Condition": { "StringEquals": { "aws:ResourceTag/TerraformInvocation": "${aws:PrincipalTag/TerraformInvocation}" } } } ] }
需要注意的是,这些方案都有各自局限性:External ID需要妥善保管,IP限制不适用于动态IP场景,会话标签也无法完全阻止知道标签的用户直接假设角色。建议根据你的运行环境选择最合适的组合方案来提升安全性。
内容的提问来源于stack exchange,提问作者Michel Rouly

