无法在 terraform 0.12 的子模块中声明映射变量

can't declare map variables in child modules in terraform 0.12

我曾经在 terraform 中有(工作)地图变量,但在升级到 terraform 0.12 后,我不断收到以下形式的错误:

Error: Invalid value for module argument

  on main.tf line 84, in module "gke":
  84:   gke_label             = "var.gke_label"

The given value is not suitable for child module variable "gke_label" defined
at gke/variables.tf:40,1-19: map of any single type required.

我不明白如何升级这些地图变量。关于这方面的文档不是特别清楚(对我来说)。

我的设置如下: 我有一个 terraform 文件夹结构:

├── infrastructure
│   ├── backend
│   │   ├── subnet
│   │   │   ├── main.tf
│   │   │   ├── outputs.tf
│   │   │   └── variables.tf
│   │   └── vpc
│   │       ├── main.tf
│   │       └── outputs.tf
│   ├── backend.tf
│   ├── backend.tfvars
│   ├── gke
│   │   ├── main.tf
│   │   ├── outputs.tf
│   │   └── variables.tf

│   ├── main.tf
│   ├── outputs.tf
│   ├── variables.tf
│   └── versions.tf

在main.tf之内我有/有(除其他外):

module "gke" {
  source                = "./gke"
  region                = "var.region"
  min_master_version    = "var.min_master_version"
  node_version          = "var.node_version"
  gke_num_nodes         = "var.gke_num_nodes"  # [MAP VARIABLE]
  vpc_name              = "module.vpc.vpc_name"
  subnet_name           = "module.subnet.subnet_name"
  gke_master_user       = "var.gke_master_user"
  gke_master_pass       = "var.gke_master_pass"
  gke_node_machine_type = "var.gke_node_machine_type"
  gke_label             = "var.gke_label"   # [MAP VARIABLE]
}

和 variables.tf(以及其他)

variable "gke_label" {
  default = {
    prod = "prod"
    dev  = "dev"
  }

variable "gke_num_nodes" {
  default = {
    prod = 2
    dev  = 1
  }

  description = "Number of nodes in each GKE cluster zone"
}

在 gke/variables.tf 我有:

variable "gke_num_nodes" {
  type        = map
  description = "Number of nodes in each GKE cluster zone"
}

variable gke_label {
  type        = map
  description = "label"
}

这过去工作正常,但随着升级到 terraform 0.12 这导致:​​

Error: Invalid value for module argument

  on main.tf line 78, in module "gke":
  78:   gke_num_nodes         = "var.gke_num_nodes"

The given value is not suitable for child module variable "gke_num_nodes"
defined at gke/variables.tf:15,1-25: map of any single type required.


Error: Invalid value for module argument

  on main.tf line 84, in module "gke":
  84:   gke_label             = "var.gke_label"

The given value is not suitable for child module variable "gke_label" defined
at gke/variables.tf:40,1-19: map of any single type required.

我在 gke/variables.tf 中进行了更改(num_nodes 也一样)

variable gke_label {
  type        = map(any)
  description = "label"
}

但错误依旧

Error: Invalid value for module argument

  on main.tf line 84, in module "gke":
  84:   gke_label             = "var.gke_label"

The given value is not suitable for child module variable "gke_label" defined
at gke/variables.tf:40,1-19: map of any single type required.

如何将这些地图变量更新为 terraform 0.12?

此 Terraform 0.12 代码将按预期分配值(不是文字字符串):

gke_num_nodes         = var.gke_num_node

在 Terraform 0.11.x 或 Terraform 0.12 中,如果您在变量赋值周围使用引号而不使用插值,它们将被视为字符串。

gke_num_nodes         = "var.gke_num_node"

上面的代码会将文字串"var.gke_num_node"赋值给模块中的gke_num_nodes,而不是赋值var.gke_num_nodes 如您所愿。由于 string 不可分配给 map(any),Terraform 输出您提供的类型错误:

Error: Invalid value for module argument

  on main.tf line 78, in module "gke":
  78:   gke_num_nodes         = "var.gke_num_nodes"

在 Terraform 0.11.x 及更早版本中,您可以使用带有 ${} 的字符串插值来获取变量的值:

gke_num_nodes         = "${var.gke_num_node}"

这种表达式在 Terraform 0.12 中已弃用,但在大多数情况下仍然有效。不要在 Terraform 0.12 中使用字符串插值,除非您从多个变量构建字符串。

您通过删除 ${} 跳到了 Terraform 0.12 的一半。通过删除引号来弥补剩余的差距,以便您的变量分配将按预期工作:

gke_num_nodes         = var.gke_num_node

这是整个模块块,已更正以删除引号:

module "gke" {
  source                = "./gke"
  region                = var.region
  min_master_version    = var.min_master_version
  node_version          = var.node_version
  gke_num_nodes         = var.gke_num_node # [MAP VARIABLE]
  vpc_name              = module.vpc.vpc_name
  subnet_name           = module.subnet.subnet_name
  gke_master_user       = var.gke_master_user
  gke_master_pass       = var.gke_master_pass
  gke_node_machine_type = var.gke_node_machine_type
  gke_label             = var.gke_label   # [MAP VARIABLE]
}