I'd love to be able to do this:
variable "amis" {
default = {
app1 = {
us-west-2 = "ami-abc123"
}
app2 = {
us-west-2 = "ami-cba321"
}
}
}
Currently, you'd get an error like Variable 'amis': must be string or mapping
Interestingly, I can cheat a bit:
variable "amis" {
default = {
app.us-west-2 = "ami-abc123"
app2.us-west-2 = "ami-cba321"
}
}
+1
+1
+1, I didn't realize this was not possible.
+1
+1
+1
:+1: really need to be able to pass data types other than strings in the DSL.
+1
+1 really need this one
+1
+1
+1
+1
+1
+1
Being able to have a list as a value would also be very nice
+1
:+1:
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
pleaseeeeeeeeee
+1
+1
+1
+1
+1
+1
+1
+1
+1 any closer to this with 0.7 additional support for maps?
so we have lists and maps (+ maps of lists works?)
+1
+1
Adding my vote for this.
related: #3690 #8384 #5841 #8153
+1
+1
+1
+1
+1
+1
+1
+1
gosh! :)
+1
+1
+1
+1
👍
+1
+1
+1
+1
+1
+1
+1 This would be really helpful when it comes to tags.
+1
+1
+1
+1
What are people doing to work around this?
@tomstockton it's been two years, had to drop terraform originally and then brought it back in a lesser capacity
Here is what I would do as an alternative for this map of map issue:
variable amis {
app1 = "app1_map"
app2 = "app2_map"
}
app1_map = {
us-west-2 = "ami-abc123"
}
app2_map = {
us-west-2 = "ami-cba321"
}
}
Here's what I did for multi-environment in one variables.tf file symlinked into each environment folder
variable "subnets" {
type = "map"
default = {
dev = "10.104.0.0/16"
qa = "10.103.0.0/16"
stage = "10.102.0.0/16"
prod = "10.101.0.0/16"
app.dev = "10.104.20.0/23"
app.qa = "10.103.20.0/23"
app.stage = "10.102.20.0/23"
app.prod = "10.101.20.0/23"
app_1.dev = "10.104.20.0/24"
app_1.qa = "10.103.20.0/24"
app_1.stage = "10.102.20.0/24"
app_1.prod = "10.101.20.0/24"
app_2.dev = "10.104.21.0/24"
app_2.qa = "10.103.21.0/24"
app_2.stage = "10.102.21.0/24"
app_2.prod = "10.101.21.0/24"
public.dev = "10.104.10.0/23"
public.qa = "10.103.10.0/23"
public.stage = "10.102.10.0/23"
public.prod = "10.101.10.0/23"
public_1.dev = "10.104.10.0/24"
public_1.qa = "10.103.10.0/24"
public_1.stage = "10.102.10.0/24"
public_1.prod = "10.101.10.0/24"
public_2.dev = "10.104.11.0/24"
public_2.qa = "10.103.11.0/24"
public_2.stage = "10.102.11.0/24"
public_2.prod = "10.101.11.0/24"
private_1.dev = "10.104.xx.0/24"
private_1.qa = "10.103.xx.0/24"
private_1.stage = "10.102.xx.0/24"
private_1.prod = "10.101.xx.0/24"
private_2.dev = "10.104.xx.0/24"
private_2.qa = "10.103.xx.0/24"
private_2.stage = "10.102.xx.0/24"
private_2.prod = "10.101.xx.0/24"
}
}
and then call it like
module "vpc" {
source = "../modules/aws_vpc/"
# we call the environment 'variable' here for the vpc name
name = "vpc-${var.environment}"
cidr = "${lookup(var.subnets, var.environment)}"
private_subnets = ["${lookup(var.subnets, "private_1.${var.environment}")}", "${lookup(var.subnets, "private_2.${var.environment}")}"]
public_subnets = ["${lookup(var.subnets, "public_1.${var.environment}")}", "${lookup(var.subnets, "public_2.${var.environment}")}"]
app_subnets = ["${lookup(var.subnets, "app_1.${var.environment}")}", "${lookup(var.subnets, "app_2.${var.environment}")}"]
enable_dns_hostnames = true
enable_dns_support = true
enable_nat_gateway = "true"
}
+1
+1
+1
I just verified that the example given in the original comment on this issue works in Terraform v0.12-alpha1:
variable "amis" {
default = {
app1 = {
us-west-2 = "ami-abc123"
}
app2 = {
us-west-2 = "ami-cba321"
}
}
}
output "amis" {
value = var.amis
}
In addition, Terraform v0.12 introduces the idea of _object types_ which allow specification of variables that expect a specific set of attributes that may be of different types:
variable "regions" {
type = map(map(object({
ami = string
})))
default = {
app1 = {
us-west-2 = {
ami = "ami-abc123"
}
}
app2 = {
us-west-2 = {
ami = "ami-cba321"
}
}
}
}
output "regions" {
value = var.regions
}
Although there is still a remaining small issue to fix over in #19141, this feature request is now complete. Thanks for your patience, everyone!
Here's what I did for multi-environment in one variables.tf file symlinked into each environment folder
variable "subnets" { type = "map" default = { dev = "10.104.0.0/16" qa = "10.103.0.0/16" stage = "10.102.0.0/16" prod = "10.101.0.0/16" app.dev = "10.104.20.0/23" app.qa = "10.103.20.0/23" app.stage = "10.102.20.0/23" app.prod = "10.101.20.0/23" app_1.dev = "10.104.20.0/24" app_1.qa = "10.103.20.0/24" app_1.stage = "10.102.20.0/24" app_1.prod = "10.101.20.0/24" app_2.dev = "10.104.21.0/24" app_2.qa = "10.103.21.0/24" app_2.stage = "10.102.21.0/24" app_2.prod = "10.101.21.0/24" public.dev = "10.104.10.0/23" public.qa = "10.103.10.0/23" public.stage = "10.102.10.0/23" public.prod = "10.101.10.0/23" public_1.dev = "10.104.10.0/24" public_1.qa = "10.103.10.0/24" public_1.stage = "10.102.10.0/24" public_1.prod = "10.101.10.0/24" public_2.dev = "10.104.11.0/24" public_2.qa = "10.103.11.0/24" public_2.stage = "10.102.11.0/24" public_2.prod = "10.101.11.0/24" private_1.dev = "10.104.xx.0/24" private_1.qa = "10.103.xx.0/24" private_1.stage = "10.102.xx.0/24" private_1.prod = "10.101.xx.0/24" private_2.dev = "10.104.xx.0/24" private_2.qa = "10.103.xx.0/24" private_2.stage = "10.102.xx.0/24" private_2.prod = "10.101.xx.0/24" } }
and then call it like
module "vpc" { source = "../modules/aws_vpc/" # we call the environment 'variable' here for the vpc name name = "vpc-${var.environment}" cidr = "${lookup(var.subnets, var.environment)}" private_subnets = ["${lookup(var.subnets, "private_1.${var.environment}")}", "${lookup(var.subnets, "private_2.${var.environment}")}"] public_subnets = ["${lookup(var.subnets, "public_1.${var.environment}")}", "${lookup(var.subnets, "public_2.${var.environment}")}"] app_subnets = ["${lookup(var.subnets, "app_1.${var.environment}")}", "${lookup(var.subnets, "app_2.${var.environment}")}"] enable_dns_hostnames = true enable_dns_support = true enable_nat_gateway = "true" }
FYI: Terraform v0.12 will complain about the ' . ' in the subnet variables (e.g app.dev) with this error:
Error: Ambiguous attribute key
I changed the ' . ' delimiter and works fine.
I'm going to lock this issue because it has been closed for _30 days_ ⏳. This helps our maintainers find and focus on the active issues.
If you have found a problem that seems similar to this, please open a new issue and complete the issue template so we can capture all the details necessary to investigate further.
Most helpful comment
I just verified that the example given in the original comment on this issue works in Terraform v0.12-alpha1:
In addition, Terraform v0.12 introduces the idea of _object types_ which allow specification of variables that expect a specific set of attributes that may be of different types:
Although there is still a remaining small issue to fix over in #19141, this feature request is now complete. Thanks for your patience, everyone!