1
votes

I used to have (working) map variables in terraform, but after upgrading to terraform 0.12 I keep getting errors of the form:

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.

I don't understand how to upgrade these map variables. Documentation on this is not particularly clear (to me).

My set-up is as follows: I have a terraform folder structure:

├── 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

within main.tf I had / have (among others):

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]
}

and in variables.tf (among others)

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"
}

within gke/variables.tf I had:

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

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

This used to work fine, but with the upgrade to terraform 0.12 this results in:

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.

I changed in gke/variables.tf (same for num_nodes)

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

but the error remains

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.

How do I update these map variables to terraform 0.12?

1

1 Answers

2
votes

This Terraform 0.12 code will assign the value as expected (not a literal string):

gke_num_nodes         = var.gke_num_node

In either Terraform 0.11.x or Terraform 0.12, if you use quotes around your variable assignments without interpolation, they will be treated as strings.

gke_num_nodes         = "var.gke_num_node"

The code above will assign the literal string "var.gke_num_node" to gke_num_nodes in the module, instead of assigning the value of var.gke_num_nodes as you intend. Since string is not assignable to map(any), Terraform outputs the type error you presented:

Error: Invalid value for module argument

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

In Terraform 0.11.x and earlier, you would use string interpolation with ${} to get the value of a variable:

gke_num_nodes         = "${var.gke_num_node}"

That kind of expression is deprecated in Terraform 0.12, but will still work in most cases. Do not use string interpolation in Terraform 0.12 unless you are building a string from multiple variable.

You leapt halfway to Terraform 0.12 by removing the ${}. Leap the remaining gap by removing the quotes so your variable assignments will work as expected:

gke_num_nodes         = var.gke_num_node

Here is the entire module block, corrected to remove the quotes:

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]
}