HashiCorp Terraform Associate (004) Question 108
Single answer4d Understand and use complex typesA platform team wants to standardize how application environments are defined in Terraform. They want a single input variable that can describe multiple environments, where each environment must include a CIDR block and a list of subnet names. They also want to create one module instance per environment using for_each and ensure invalid input is rejected during terraform plan.
Which variable definition best satisfies these requirements?
- A
variable "environments" { type = map(object({ cidr_block = string subnets = list(string) })) }
- B
variable "environments" { type = list(map(string)) }
- C
variable "environments" { type = object({ cidr_block = string subnets = list(string) }) }
- D
variable "environments" { type = map(any) }
Show answer and explanation
Correct answer: A
Explanation
The best answer is map(object({ cidr_block = string, subnets = list(string) })) because it combines two important Terraform concepts: complex types and strong input validation. A map is ideal when you want instances keyed by meaningful names and then consumed with for_each, for example for_each = var.environments. Each map value is an object with a fixed schema, which lets Terraform validate that every environment definition contains the expected attributes and types.
This is a common real-world pattern for reusable modules: define a collection of consistently structured objects, then iterate over them. In Terraform type constraints, object is used to describe a value with named attributes, list(string) enforces an ordered collection of strings, and map(...) enforces a set of values indexed by string keys. Using any is generally discouraged when the expected structure is known, because it reduces Terraform's ability to catch mistakes early.
This aligns with Terraform documentation on input variable type constraints and complex types, especially the use of collection and structural types such as map, list, and object to validate module inputs and support predictable iteration with for_each.
- A. Correct.
Correct.
map(object({...}))is a complex type that allows each environment to be keyed by name, such asdev,stage, orprod, while enforcing that every value has the same required structure: acidr_blockstring and asubnetslist of strings. This works well withfor_eachbecause maps are a common and predictable collection type for creating one resource or module instance per key. Terraform will also validate the shape of the input during planning. - B. Incorrect.
Incorrect.
list(map(string))does not model the requirement well. It allows a list of maps whose values are all strings, so it cannot correctly enforce thatsubnetsis a list of strings. It also does not naturally support naming environments by key for straightforwardfor_eachusage, since a list is indexed numerically unless transformed. - C. Incorrect.
Incorrect.
object({...})defines only a single object withcidr_blockandsubnets, not multiple environments. This would be appropriate only if the team wanted exactly one environment definition, not a collection of environment definitions keyed by environment name. - D. Incorrect.
Incorrect.
map(any)is flexible, but it does not enforce the required internal structure of each environment. While it could technically hold the data, it weakens type safety and allows malformed values to pass initial type checks, which is not aligned with the requirement to reject invalid input early duringterraform plan.