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

Terraform条件表达式类型不一致问题求助(v0.14.8)

Terraform v0.14.8 AWS IAM角色条件表达式类型不一致错误解决求助

问题场景

使用Terraform v0.14.8编写AWS IAM角色资源代码时,在基于var.provision_capi_server_iam的内联三元表达式中执行terraform plan,出现类型不一致错误。已尝试将第75行的[]改为[{}],但问题未解决,求可行的解决建议。

代码片段

resource "aws_iam_role" "aws_iam_role_controllers" {

  assume_role_policy = jsonencode({
    Version = "2012-10-17"
    Statement = flatten([
      {
        Action = "sts:AssumeRole"
        Effect = "Allow"
        Sid    = ""
        Principal = {
          Service = "ec2.amazonaws.com"
        }
      },
      {
        Action = "sts:AssumeRole"
        Effect = "Allow"
        Sid    = ""
        Principal = {
          AWS = "arn:aws:iam::xxxxxxxxxx:role/controllers.cluster-api-provider-aws.sigs.k8s.io"
        }
      },
      var.provision_capi_server_iam ? [
      {
        Action = "sts:AssumeRole"
        Effect = "Allow"
        Sid    = ""
        Principal = {
          AWS = "arn:aws:iam::${var.aws_account_id}:role/controllers.cluster-api-provider-aws.sigs.k8s.io"
        }
      },
      {
        Action = "sts:AssumeRoleWithWebIdentity"
        Effect = "Allow"
        Sid    = ""
        Principal = {
          Federated = "arn:aws:iam::${var.aws_account_id}:oidc-provider/${replace(data.aws_eks_cluster.eks_cluster[0].identity[0].oidc[0].issuer, "https://", "")}"
        }
        Condition = {
          "ForAnyValue:StringEquals" = {
            "${replace(data.aws_eks_cluster.eks_cluster[0].identity[0].oidc[0].issuer, "https://", "")}:sub" = [
              "system:serviceaccount:capa-system:capa-controller-manager",
              "system:serviceaccount:capi-system:capi-controller-manager",
              "system:serviceaccount:capa-eks-control-plane-system:capa-eks-control-plane-controller-manager",
              "system:serviceaccount:capa-eks-bootstrap-system:capa-eks-bootstrap-controller-manager",
            ]
          }
        }
      }
      ] : []

    ])
  })

错误信息

Using a variables file to set an undeclared variable is deprecated and will
become an error in a future release. If you wish to provide certain "global"
settings to all configurations in your organization, use TF_VAR_...
environment variables to set these instead.


Warning: Values for undeclared variables

In addition to the other similar warnings shown, 11 other variable(s) defined
without being declared.


Error: Inconsistent conditional result types

  on ../../../../../modules/capi-roles-and-policies/main.tf line 48, in resource "aws_iam_role" "aws_iam_role_controllers":
  48:       var.provision_capi_server_iam ? [
  ...
  75:       ] : []

The true and false result expressions must have consistent types. The given
expressions are tuple and tuple, respectively.

解决思路与方案

错误原因

Terraform 0.14的类型系统对三元表达式的类型一致性要求严格:true分支是包含两个结构明确的IAM Statement对象的元组,而false分支的空元组[]没有明确的元素类型约束,两者无法被推断为同一类型,从而触发错误。修改为[{}]无效,是因为空对象的结构与true分支的Statement对象结构不匹配(缺少Action、Effect等必填字段),类型依然不一致。

可行方案

方案1:重构代码结构,使用concat合并列表

将固定的Statement和条件性的Statement分别作为列表,用concat合并后再执行flatten,让Terraform更容易统一类型推断:

resource "aws_iam_role" "aws_iam_role_controllers" {
  assume_role_policy = jsonencode({
    Version = "2012-10-17"
    Statement = flatten(concat(
      // 固定的两个Statement
      [
        {
          Action = "sts:AssumeRole"
          Effect = "Allow"
          Sid    = ""
          Principal = {
            Service = "ec2.amazonaws.com"
          }
        },
        {
          Action = "sts:AssumeRole"
          Effect = "Allow"
          Sid    = ""
          Principal = {
            AWS = "arn:aws:iam::xxxxxxxxxx:role/controllers.cluster-api-provider-aws.sigs.k8s.io"
          }
        }
      ],
      // 条件性的Statement列表
      var.provision_capi_server_iam ? [
        {
          Action = "sts:AssumeRole"
          Effect = "Allow"
          Sid    = ""
          Principal = {
            AWS = "arn:aws:iam::${var.aws_account_id}:role/controllers.cluster-api-provider-aws.sigs.k8s.io"
          }
        },
        {
          Action = "sts:AssumeRoleWithWebIdentity"
          Effect = "Allow"
          Sid    = ""
          Principal = {
            Federated = "arn:aws:iam::${var.aws_account_id}:oidc-provider/${replace(data.aws_eks_cluster.eks_cluster[0].identity[0].oidc[0].issuer, "https://", "")}"
          }
          Condition = {
            "ForAnyValue:StringEquals" = {
              "${replace(data.aws_eks_cluster.eks_cluster[0].identity[0].oidc[0].issuer, "https://", "")}:sub" = [
                "system:serviceaccount:capa-system:capa-controller-manager",
                "system:serviceaccount:capi-system:capi-controller-manager",
                "system:serviceaccount:capa-eks-control-plane-system:capa-eks-control-plane-controller-manager",
                "system:serviceaccount:capa-eks-bootstrap-system:capa-eks-bootstrap-controller-manager",
              ]
            }
          }
        }
      ] : []
    ))
  })
}

方案2:显式指定false分支的类型

通过类型构造器,强制将空元组转换为与true分支一致的元素类型:

// 在三元表达式的false分支,显式声明类型
var.provision_capi_server_iam ? [
  // 两个Statement对象
] : list(object({
  Action = string
  Effect = string
  Sid    = string
  Principal = map(string)
  Condition = optional(map(any))
}))([])

这种方式直接告诉Terraform,false分支的空列表元素类型与true分支一致,解决类型推断冲突。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.06 10:11:01