Terraform 在模块内的模块之间传递地形变量?

Terraform 在模块内的模块之间传递地形变量?,terraform,kubespray,Terraform,Kubespray,我有一个问题,我在从项目中构建模块时遇到了困难 我有以下文件夹结构: terraform/ modules/ kubespray/ modules/ compute/ ips/ network/ main.tf variables.tf roles/ kubespray/ terraform_setup/ main.tf 在kubespray/mai

我有一个问题,我在从项目中构建模块时遇到了困难

我有以下文件夹结构:

terraform/
modules/
   kubespray/
      modules/
         compute/
         ips/
         network/
      main.tf
      variables.tf
roles/
    kubespray/
        terraform_setup/
             main.tf
kubespray/main.tf
模块中,有一些变量正在传递:

module "ips" {
  source = "./modules/ips"

  number_of_k8s_masters         = "${var.number_of_k8s_masters}"
  number_of_k8s_masters_no_etcd = "${var.number_of_k8s_masters_no_etcd}"
  number_of_k8s_nodes           = "${var.number_of_k8s_nodes}"
  floatingip_pool               = "${var.floatingip_pool}"
  number_of_bastions            = "${var.number_of_bastions}"
  external_net                  = "${var.external_net}"
  network_name                  = "${var.network_name}"
  router_id                     = "${module.network.router_id}"
}

module "compute" {
  source = "./modules/compute"
  ...
  k8s_master_fips                              = "${module.ips.k8s_master_fips}"
  k8s_master_no_etcd_fips                      = "${module.ips.k8s_master_no_etcd_fips}"
  k8s_node_fips                                = "${module.ips.k8s_node_fips}"
  bastion_fips                                 = "${module.ips.bastion_fips}"
  ...
}
output "private_subnet_id" {
  value = "${module.network.subnet_id}"
}

output "floating_network_id" {
  value = "${var.external_net}"
}

output "router_id" {
  value = "${module.network.router_id}"
}

output "k8s_master_fips" {
  value = "${concat(module.ips.k8s_master_fips, module.ips.k8s_master_no_etcd_fips)}"
}

output "k8s_node_fips" {
  value = "${module.ips.k8s_node_fips}"
}

output "bastion_fips" {
  value = "${module.ips.bastion_fips}"
}
如果我从
modules/kubespray/
中的子模块内部运行terraform init/apply,它可以正常工作

如果我从我的
角色/kubespray
运行

module "kubespray" {
  source    = "../../../modules/kubespray"
  providers = {
    openstack.src = openstack
  }
}
它失败了

错误:索引无效

在../../../modules/kubespray/modules/compute/main.tf第670行的 资源“openstack\u compute\u floatingip\u associate\u v2”k8s\u节点:670: floating_ip=“${var.k8s_node_fips[count.index]}” |---------------- |count.index为0 |var.k8s_node_fips是动态


如果不询问进一步的信息,我们将非常感谢您的帮助,我猜您正在传入一个空数组(
${var.k8s\u node\u fips[count.index]}
),其中
var.node\u root\u volume\u size\u in\u gb
var.number\u of\u k8s\u nodes\u floating\u ip的值大于0,尝试为资源声明所需的字符串索引空数组时出错

Error: Invalid index

on ../../../modules/kubespray/modules/compute/main.tf line 670, in resource "openstack_compute_floatingip_associate_v2" "k8s_node": 670: floating_ip = "${var.k8s_node_fips[count.index]}" |---------------- | count.index is 0 | var.k8s_node_fips is empty list of dynamic
根据错误,这可能是
${var.k8s\u node\u fips[count.index]}
处的插值错误。 看起来发生的情况是,变量为空,但
计数
被设置为非零数,从而导致
TF
出错

查看原始项目代码,似乎
count
变量取决于
var.node\u root\u volume\u size\u in\u gb
为0设置为0;否则,将把计数设置为
var.number\u of_k8s\u node\u floating\u ip的值

错误似乎发生在以下位置的代码段:

resource "openstack_compute_instance_v2" "k8s_node_no_floating_ip_custom_volume_size" {
  name              = "${var.cluster_name}-k8s-node-nf-${count.index+1}"
  count             = "${var.node_root_volume_size_in_gb > 0 ? var.number_of_k8s_nodes_no_floating_ip : 0}"
  availability_zone = "${element(var.az_list, count.index)}"
  image_name        = "${var.image}"
  flavor_id         = "${var.flavor_k8s_node}"
  key_pair          = "${openstack_compute_keypair_v2.k8s.name}"

  block_device {
    uuid                  = "${data.openstack_images_image_v2.vm_image.id}"
    source_type           = "image"
    volume_size           = "${var.node_root_volume_size_in_gb}"
    boot_index            = 0
    destination_type      = "volume"
    delete_on_termination = true
  }

希望这对您有所帮助

当您运行
terraform
时,目录将成为一个隐式的“根模块”。正如文档中所解释的,根模块可以从CLI或环境访问TF输入,但所有其他调用的模块都需要传入这些输入

我假设发生的情况可能是,您的
~kubespray/variables.tf
输入变量具有指定的默认值,这些值正在生效。如果是这种情况,则应将它们复制到
~terraform\u setup/variables.tf
并传递到调用模块:

module "kubespray" {
  source    = "../../../modules/kubespray"
  providers = {
    openstack.src = openstack
  }
}

非常感谢您查看它,我明白错误告诉我的是什么,我真正的困惑是,当我从模块本身运行terraform时,为什么它工作良好。但是当我从调用模块的东西运行时,它失败了。似乎
var.k8s\u node\u fips
如果我不直接从模块运行,问题就不会解决。我认为这可能是我的根本原因,我恢复了很多更改,并从顶层(根)模块传递了更多内容,事情似乎很好。谢谢QQ我可以从这个根模块传递提供者变量吗?输出“输出openstack\u用户\u域”?@bison我可能没有正确理解。如果不希望子模块继承提供程序,则可以将输入传递给子模块,以使其初始化提供程序。尽管如此,我认为除了资源上的
{provider=name | alias}
之外,没有其他方法可以引用提供程序,因此我认为您需要找到一个合适的资源,为解析的提供程序配置提供输出。