I have a terraform map of set objects as given below
variable "BName" {
type = string
}
variable "type_names" {
type = map(object({
name = string
type = string
stream = string
grp = optional(string)
}))
}
I'm also trying to use the type_name in the following resource. How we can refer the value from map of sets during the resource creation
resource "azure_resource" "reso" {
id = az_resource.B_Name.id
name = var.type_names.name
}
resource "az_resource" "B_Name" {
name = var.BName
}
How I can pass this value in terraform.tfvars file to create following resource. Now I'm trying to pass the following way
BName = "Test"
type_names = {
name = "cooper"
type = "senior"
stream= "developer"
grp = "Mid"
}
{
name = "Mike"
type = "Junior"
stream= "tester"
grp = "entry"
}
CodePudding user response:
For creating multiple resources with a single definition with a map(object)
variable input, there exists a general algorithm and pattern. First, we need the variable structure definition from the declaration. For your example, we have:
variable "type_names" {
type = map(object({
name = string
type = string
stream = string
grp = optional(string)
}))
}
where I assume the use of the experimental feature for optional object keys given the appearance of the keyword optional
. In this situation, it is helpful for the resource to have a descriptive identifier. That would most likely be the name
, so we can remove it from the object
value and refactor it to be the map
key. Updated definition with an example default
that conforms to the type definition would be:
variable "type_names" {
type = map(object({
type = string
stream = string
grp = optional(string)
}))
default = {
"cooper" = {
type = "senior"
stream = "developer"
grp = "Mid"
},
"Mike" = {
type = "Junior"
stream = "tester"
grp = "entry"
}
}
}
We can then easily use this to manage multiple resources with a single definition and input variable. Since the example resource in the question is using different keys than the provided variable possesses, we will modify the example resource slightly:
resource "azure_resource" "this" {
for_each = var.type_names
# value is the object, so we access object values with standard `.key` syntax
name = each.key
type = each.value.type
stream = each.value.stream
grp = each.value.grp
}
and the namespace of each resource will be azure_resource.this["<key>"]
e.g. azure_resource.this["Mike"]
, and you can access its attributes normally.