HashiCorp Terraform Associate (004) Question 109
Single answer4d Understand and use complex typesA platform team wants to standardize how application environments are defined in Terraform. Each environment must include a region, a list of subnet CIDR blocks, and a set of tags. They want Terraform to reject invalid input during planning if any environment is missing one of these attributes or uses the wrong data type. Which variable definition best enforces this requirement while still allowing multiple environments to be declared in a single input value?
- A
variable "environments" { type = map(object({ region = string, subnet_cidrs = list(string), tags = map(string) })) }
- B
variable "environments" { type = object({ region = string, subnet_cidrs = list(string), tags = map(string) }) }
- C
variable "environments" { type = list(map(string)) }
- D
variable "environments" { type = map(any) }
Show answer and explanation
Correct answer: A
Explanation
Terraform complex types are designed to enforce both the shape and data types of module inputs. In this scenario, the team needs one variable containing multiple environments, so the outer type should be a map keyed by environment name such as dev, staging, or prod. Each environment must then be described by a consistent schema, which is why object({ region = string, subnet_cidrs = list(string), tags = map(string) }) is appropriate for each value. Combining these gives map(object(...)). This aligns with Terraform's type constraints documentation and module design best practices: use precise types instead of any when you want early validation, clearer module contracts, and more predictable plans. Using object for a single structured value, map for keyed collections, list for ordered collections, and map/object nesting together is a core skill for working with complex types in Terraform.
- A. Correct.
Correct. A type of map(object({ ... })) allows the caller to provide multiple named environments, where each map value must be an object with exactly the required attributes and expected types: region as a string, subnet_cidrs as a list of strings, and tags as a map of strings. This is the strongest and most practical type constraint for the stated requirement because it validates both structure and element types during planning.
- B. Incorrect.
Incorrect. This defines a single object with region, subnet_cidrs, and tags attributes, not multiple environments. It would work only if the input represented one environment, but the scenario explicitly requires multiple environments in one variable value.
- C. Incorrect.
Incorrect. A list(map(string)) is too loose and also the wrong shape for the requirement. It would allow a list of maps whose values are all strings, which means subnet_cidrs could not be a proper list(string) and tags would not be a distinct map(string) nested within a structured environment object. This reflects a common misunderstanding that map(string) can represent any nested configuration.
- D. Incorrect.
Incorrect. A map(any) permits multiple named entries, but it does not enforce that each value has region, subnet_cidrs, and tags with the proper types. Terraform would accept many invalid shapes until later expression evaluation, reducing the benefit of type checking and making modules harder to use safely.