TF-Associate-004 - Terraform configuration (21% of the exam) - Section 4e
Write dynamic configuration using expressions and functions.
Built-in functions, conditional expressions, for expressions, splat expressions and dynamic blocks generate configuration from data. Candidates should predict the result of a function or for expression and know dynamic blocks produce repeated nested blocks, not top-level resources.
A module receives a variable named ingress_ports holding a list of port numbers. The author wants a single aws_security_group resource to generate one ingress block per port without duplicating the block by hand. Which construct should populate the repeated ingress blocks?
variable "ingress_ports" {
type = list(number)
default = [22, 80, 443]
}
resource "aws_security_group" "web" {
name = "web"
# repeated ingress blocks go here
}
AA dynamic "ingress" block that iterates with for_each over var.ingress_ports and sets the port fields from each.value.check_circle Correct
BA count = length(var.ingress_ports) argument on the aws_security_group resource, indexing var.ingress_ports[count.index] inside one ingress block.
CA for expression written directly as ingress = [for p in var.ingress_ports : p], assigning the list to the ingress argument.
DA separate aws_security_group_rule resource with for_each, leaving the aws_security_group with no ingress blocks at all.
Use a dynamic block with for_each to generate repeated nested configuration blocks from a collection. A dynamic block is the mechanism Terraform provides for producing multiple nested blocks programmatically; its for_each drives one generated block per element, and the iterator exposes each.value for the block body.
Why A is correct: A dynamic block generates a nested configuration block once per element of its for_each collection, so it produces one ingress block per port using each.value, which is exactly the requirement.
Why B is wrong: count on the resource would create several separate security groups rather than several ingress blocks inside one group, so it multiplies the wrong object.
Why C is wrong: A for expression builds a value such as a list or map, but ingress is a nested block rather than an argument that accepts a list, so this assignment is invalid here.
Why D is wrong: Splitting rules into a separate resource can work but changes the design away from repeating nested blocks within the group, which is what the question asks the practitioner to achieve.
Answers that look right on this material and are not. Each one is a distractor from a different question in the TF-Associate-004 bank for this domain.
It defines a new custom function that other blocks in the module can call to generate repeated argument values.
errorWhy it is wrong: Tempting because it sounds like reusable logic, but Terraform does not support user-defined functions, and a dynamic block does not create one.
Only during apply, because data sources are always deferred until managed resources have been created.
errorWhy it is wrong: Deferral to apply happens only when the data block's arguments depend on unknown values; here the arguments are all known, so this is tempting but wrong.
Terraform evaluates both branches eagerly and then discards the value of the branch that the condition did not select.
errorWhy it is wrong: Tempting because many imperative languages appear to compute sub-expressions before choosing, but Terraform returns only the selected result value rather than requiring both to produce a usable result.