You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Terraform v0.12.9:IAM策略文档传递IP变量报错的解决问询

问题:Terraform v0.12.9中IAM策略文档传递IP变量报错

使用Terraform v0.12.9,尝试通过IAM策略文档自定义策略来条件创建S3桶策略,相关配置及遇到的问题如下:

原配置代码

IAM策略文档

data "aws_iam_policy_document" "my_policy" {
  statement {
    sid     = "IPALLOW"
    effect  = "Deny"
    actions = ["s3:*"]
    resources = [
      "arn:aws:s3:::${var.my_bucket}/*",
      "arn:aws:s3:::${var.my_bucket}"
    ]
    principals {
      type        = "AWS"
      identifiers = ["*"]
    }
    condition {
      test     = "NotIpAddress"
      variable = "aws:SourceIp"
      values = [
        "${concat(var.ip_one,
        var.ip_two,
        var.ip_three)}"
      ]
    }
  }
}

S3桶策略资源

resource "aws_s3_bucket_policy" "my-bucket-policy" {
  count  = length(var.buckets)
  bucket = element(values(var.buckets[count.index]), 0)
  policy = (
    element(values(var.buckets[count.index]), 0) == "bar_bucket" ?
    data.aws_iam_policy_document.my_policy.json : <<POLICY
  {
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "HTTP",
      "Effect": "Deny",
      "Principal": "*",
      "Action": "*",
    REST OF POLICY REDACTED
    POLICY
   )
 }

报错信息

运行时抛出类型不匹配错误:

Inappropriate value for attribute "values": element 0: string required.

硬编码IP地址(如["100.0.0.100","100.0.0.101","100.0.0.102/24","100.0.0.103/24","100.0.0.104"])时可正常工作,尝试用jsonencode处理values会生成大量转义符,导致策略失效。

变量定义

variable "ip_one" {
  type = list(string)
  default = [
    "100.0.0.100",
    "100.0.0.101"
  ]
}

variable "ip_two" {
  type = list(string)
  default = [
    "100.0.0.102/24",
    "100.0.0.103/24"
  ]
}

variable "ip_three" {
  type = list(string)
  default = [
    "100.0.0.104"
  ]
}

错误原因

concat(var.ip_one, var.ip_two, var.ip_three)本身返回的是一个扁平化的字符串列表,但你将其包裹在了额外的[]中,导致values变成了列表嵌套列表(即[[...]]),而Terraform要求condition的values必须是字符串列表,因此触发类型不匹配错误。

解决方案

直接将concat的结果赋值给values,去掉外层多余的方括号:

修改后的IAM策略文档代码:

data "aws_iam_policy_document" "my_policy" {
  statement {
    sid     = "IPALLOW"
    effect  = "Deny"
    actions = ["s3:*"]
    resources = [
      "arn:aws:s3:::${var.my_bucket}/*",
      "arn:aws:s3:::${var.my_bucket}"
    ]
    principals {
      type        = "AWS"
      identifiers = ["*"]
    }
    condition {
      test     = "NotIpAddress"
      variable = "aws:SourceIp"
      # 直接使用concat的结果,无需外层[]
      values = concat(var.ip_one, var.ip_two, var.ip_three)
    }
  }
}

调整后values会成为符合要求的字符串列表,既解决了类型错误,又避免了硬编码或转义符问题。

内容的提问来源于stack exchange,提问作者Metro

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.18 10:55:14