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

Terraform 1.3.7循环传递模块Provider别名时字符串插值报错

Terraform循环传递Provider报错:A provider configuration reference must not be given in quotes.

问题场景

在Terraform 1.3.7版本中,通过for_each循环调用子模块并尝试传递动态生成的Provider时,触发报错:

A provider configuration reference must not be given in quotes.

原错误代码示例

动态生成Provider的配置

resource "local_file" "cluster_provider" {
  filename        = "${path.module}/cluster-provider.tf"
  file_permission = "666"
  content         = <<-EOT
    %{for index, cluster in local.config.cluster_list}
    # Init cluster config for helm and kubernetes providers for each cluster
    data "cloud_container_cluster_config" "cluster_config_c${index + 1}" {
        cluster_name_id   = module.k8s_cluster[cluster_${index + 1}].cluster_id
        resource_group_id = module.k8s_cluster[cluster_${index + 1}].resource_group_id
    }

    # Helm provider
    provider "helm" {
      alias = "helm_cluster_${index + 1}"
      kubernetes {
        host  = data.cloud_container_cluster_config.cluster_config_c${index + 1}.host
        token = data.cloud_container_cluster_config.cluster_config_c${index + 1}.token
      }
    }

    # Kubernetes provider
    provider "kubernetes" {
      alias = "kubernetes_cluster_${index + 1}"
      host  = data.cloud_container_cluster_config.cluster_config_c${index + 1}.host
      token = data.cloud_container_cluster_config.cluster_config_c${index + 1}.token
    }
    %{endfor}
EOT
}

子模块传递Provider的代码

module "k8s_cluster" {
  for_each = {
    for index, cluster in local.config.cluster_list :
    "cluster_${index + 1}" => cluster
  }
  providers = {
    kubernetes = "kubernetes.kubernetes_cluster_${index + 1}" # 报错行
    helm       = "helm.helm_cluster_${index + 1}"
  }
  source                          = "./cluster-child-module"
  cloud_account_key               = var.account_key
  resource_group_id               = local.resource_group_id
  region                          = var.location
  cluster_name                    = var.cluster_name
  # 其他模块属性...
}

报错原因

  1. Provider引用禁止字符串插值:模块providers块中,不能用带插值的字符串(如"kubernetes.kubernetes_cluster_${index + 1}")引用Provider,Terraform要求Provider引用必须是直接的标识符,不能是字符串形式的插值结果。
  2. 动态生成Provider配置无效:通过local_file动态生成.tf文件的方式不符合Terraform的静态解析逻辑——Terraform会在执行前提前解析所有配置文件,动态生成的文件无法被正确识别,导致Provider配置无法加载。

解决方案

步骤1:删除动态生成Provider的local_file资源

直接移除resource "local_file" "cluster_provider"的全部代码,改用静态的多实例Provider配置。

步骤2:用for_each定义多实例Provider

直接为每个集群创建对应的Provider实例,避免动态生成:

# 为每个集群拉取配置数据
data "cloud_container_cluster_config" "cluster_config" {
  for_each = {
    for index, cluster in local.config.cluster_list :
    "cluster_${index + 1}" => cluster
  }
  cluster_name_id   = module.k8s_cluster[each.key].cluster_id
  resource_group_id = module.k8s_cluster[each.key].resource_group_id
}

# 多实例Kubernetes Provider
provider "kubernetes" {
  for_each = data.cloud_container_cluster_config.cluster_config
  alias    = each.key
  host     = each.value.host
  token    = each.value.token
}

# 多实例Helm Provider
provider "helm" {
  for_each = data.cloud_container_cluster_config.cluster_config
  alias    = each.key
  kubernetes {
    host  = each.value.host
    token = each.value.token
  }
}

步骤3:子模块中正确传递Provider

利用each.key直接引用对应的Provider实例,无需字符串插值:

module "k8s_cluster" {
  for_each = {
    for index, cluster in local.config.cluster_list :
    "cluster_${index + 1}" => cluster
  }
  providers = {
    kubernetes = kubernetes[each.key]
    helm       = helm[each.key]
  }
  source                          = "./cluster-child-module"
  cloud_account_key               = var.account_key
  resource_group_id               = local.resource_group_id
  region                          = var.location
  cluster_name                    = var.cluster_name
  # 其他模块属性...
}

核心说明

  • Terraform的Provider配置是静态解析的,必须在执行前就明确存在,不能通过动态生成文件的方式创建。
  • 使用for_each定义多实例Provider时,alias直接复用each.key,保证每个Provider实例与集群标识一一对应,传递时通过provider[each.key]直接引用,完全规避字符串插值的问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 13:17:51