Terraform Plan未检测Bucket/IAM Policy错误?是否为Bug或特性
这不是Terraform的Bug,而是AWS服务端校验的特性——Terraform在plan阶段仅负责生成配置并模拟变更,但不会对AWS特定的策略语法/规则做深度校验,所有针对策略合法性的严格校验都是由AWS服务在apply阶段接收配置时执行的。
场景1:S3桶策略Condition的Bool误写为bool
你在aws_iam_policy_document里把Condition的test值写成了小写的bool,Terraform的这个数据源只会把你输入的内容转换成JSON格式,不会校验IAM策略语法中Condition测试名的大小写要求。AWS的IAM策略语法明确要求测试名使用驼峰式(比如Bool而非bool),但这个规则只有当策略提交到AWS服务端(即terraform apply时)才会被校验,所以plan阶段不会报错,直到apply时才会触发服务端的语法错误提示。
对应的错误配置代码:
data "aws_iam_policy_document" "alb_log" { statement { effect = "Allow" actions = ["s3:PutObject"] resources = ["${aws_s3_bucket.alb_log.arn}/*"] principals { type = "AWS" identifiers = [data.aws_elb_service_account.main.arn] } } statement { sid = "AllowSSLRequestsOnly" effect = "Deny" actions = ["s3:*"] resources = [ aws_s3_bucket.alb_log.arn, "${aws_s3_bucket.alb_log.arn}/*" ] condition { test = "bool" # 此处应为大写Bool values = [ "false" ] variable = "aws:SecureTransport" } principals { type = "*" identifiers = ["*"] } } } resource "aws_s3_bucket_policy" "alb_log" { bucket = aws_s3_bucket.alb_log.id policy = data.aws_iam_policy_document.alb_log.json }
场景2:IAM Policy中包含Principals字段
附加到IAM用户/角色/组的IAM Policy不允许包含Principal字段——因为Principal是由被附加的实体(用户/角色/组)本身决定的,而Bucket Policy这类资源级策略才需要指定Principal。但aws_iam_policy_document是通用的策略生成工具,它不会判断你生成的策略是给IAM用还是给S3桶用,所以plan阶段不会检测这个问题。只有当你把包含Principal的策略提交给AWS IAM服务(terraform apply创建aws_iam_policy资源时),服务端才会校验并报错。
对应的错误配置代码:
data "aws_iam_policy_document" "artifact2" { statement { sid = "AllowSSLRequestsOnly" effect = "Deny" actions = ["s3:*"] resources = [ "arn:aws:s3:::${aws_s3_bucket.artifact2.id}", "arn:aws:s3:::${aws_s3_bucket.artifact2.id}/*" ] condition { test = "Bool" values = [ "false" ] variable = "aws:SecureTransport" } principals { # IAM Policy不允许包含该字段 type = "*" identifiers = ["*"] } } } resource "aws_iam_policy" "firehose" { policy = data.aws_iam_policy_document.artifact2.json }
总结
Terraform的aws_iam_policy_document仅负责生成结构合法的JSON策略文档,不会针对不同AWS服务的策略规则做业务层面的校验。所有和AWS服务特定规则相关的校验,都由对应的AWS服务在资源创建/更新阶段执行,这就是为什么问题只会在apply阶段暴露。
内容的提问来源于stack exchange,提问作者Jatin Mehrotra

