Reputation: 4259
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?
Upvotes: 1
Views: 6493
Reputation: 21686
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]
}
Upvotes: 3