Reputation: 131
terraform gurus,
Please advice how to use different pre-configured variables (preferably maps) based on user-provided variables.
For example, user executes terraform apply -var="dc=dc1"
and terraform uses vsphere variables (server, credentials, vm names, etc) specified for dc1.
Currently I tried this code:
# Variable for dc provided by user
variable "vsphere" {
type = string
description = "VSphere DC: dc1 or dc2"
validation {
condition = var.dc == "dc1" || var.dc == "dc2"
error_message = "The dc value must be dc1 or dc2"
}
}
# Provide dc details based on user input
variable "vsphere_data" {
type = map(string)
default = {
user = "terraform"
password = ""
server = var.vsphere_dc == "dc1" ? "vcenter" : "vcenter2"
host_ip = var.vsphere_dc == "dc1" ? "192.168.1.1" : "192.168.2.1"
datacenter = var.vsphere_dc == "dc1" ? "DC1" : "DC2"
datastore = var.vsphere_dc == "dc1" ? "dc1-ssd" : "dc2-ssd"
dvs = var.vsphere_dc == "dc1" ? "dc1-dvs" : "dc2-dvs"
}
}
# Provider
provider "vsphere" {
user = var.vsphere_data.user
password = var.vsphere_data.password
vsphere_server = var.vsphere_data.server
}
But when running terraform validate
I experience this error:
│ Error: Variables not allowed
│
│ on main.tf line 22, in variable "vsphere_data":
│ 22: datacenter = var.vsphere_dc == "dc1" ? "DC1" : "DC2"
│
│ Variables may not be used here.
Please advice how to better implement such case and why do I experience this error? Is locals or removing ternary operation will be a solution to the scenario above?
Upvotes: 0
Views: 2147
Reputation: 16775
Use locals
instead of variables.
# Variable for dc provided by user
variable "vsphere" {
type = string
description = "VSphere DC: dc1 or dc2"
validation {
condition = var.vsphere == "dc1" || var.vsphere == "dc2"
error_message = "The dc value must be dc1 or dc2."
}
}
# Provide dc details based on user input
locals {
vsphere_data = {
user = "terraform"
password = ""
server = var.vsphere == "dc1" ? "vcenter" : "vcenter2"
host_ip = var.vsphere == "dc1" ? "192.168.1.1" : "192.168.2.1"
datacenter = var.vsphere == "dc1" ? "DC1" : "DC2"
datastore = var.vsphere == "dc1" ? "dc1-ssd" : "dc2-ssd"
dvs = var.vsphere == "dc1" ? "dc1-dvs" : "dc2-dvs"
}
}
provider "vsphere" {
user = local.vsphere_data.user
password = local.vsphere_data.password
vsphere_server = local.vsphere_data.server
}
You can run a plan for this code with:
terraform plan -var="vsphere=dc1"
There are a few additional problems with your initial code:
variable "vsphere" {
type = string
description = "VSphere DC: dc1 or dc2"
validation {
condition = var.dc == "dc1" || var.dc == "dc2" # # THIS IS WRONG!!!
error_message = "The dc value must be dc1 or dc2"
}
}
For validation of a variable, you can not reference another variable. The validation should reference only itself. Correctly would be:
variable "vsphere" {
type = string
description = "VSphere DC: dc1 or dc2"
validation {
condition = var.vsphere == "dc1" || var.vsphere == "dc2"
error_message = "The dc value must be dc1 or dc2."
}
}
Please note, you don't need the var.dc
variable.
Moreover, you don't have this variable var.vsphere_dc
. I assume this is a typo or something, otherwise it makes no sense. The is the local value we compute.
Upvotes: 1