HashiCorp Terraform Associate (004) Question 121
Single answer4g Validate configuration using custom conditionsA platform team maintains a reusable Terraform module that creates an Amazon EC2 security group. The module accepts a variable named "allowed_cidrs" so application teams can provide ingress source ranges. To reduce mistakes, the team wants Terraform to fail during planning if any value in "allowed_cidrs" is not a valid IPv4 CIDR block. Which implementation best enforces this requirement using Terraform custom conditions?
- A
Add a variable validation block: validation { condition = alltrue([for c in var.allowed_cidrs : can(cidrhost(c, 0))]) error_message = "Each entry in allowed_cidrs must be a valid IPv4 CIDR block." }
- B
Add a precondition block inside the aws_security_group resource: precondition { condition = alltrue([for c in var.allowed_cidrs : regex("^[0-9./]+$", c)]) error_message = "Each entry must be a valid CIDR." }
- C
Add a postcondition block to an output that returns var.allowed_cidrs so Terraform validates the values before creating resources.
- D
Add lifecycle { ignore_changes = [ingress] } to the aws_security_group resource so invalid CIDR values are skipped during plan.
Show answer and explanation
Correct answer: A
Explanation
Terraform supports custom conditions through input variable validation, preconditions, and postconditions. For validating whether callers passed acceptable values into a module, variable validation is the recommended approach because it catches errors closest to the source of the problem and typically during terraform plan. In this scenario, validating each entry in allowed_cidrs with a Terraform function that requires a proper CIDR value, such as cidrhost, and wrapping it with can() is a reliable pattern. Preconditions are better suited to assumptions about resources, data sources, or outputs, while postconditions verify results after evaluation. HashiCorp documentation on custom conditions and variable validation emphasizes using variable validation for input constraints and using preconditions/postconditions for broader assumptions and guarantees in configuration.
- A. Correct.
Correct. Variable validation is the most appropriate custom condition when you want to validate input values as early as possible. Using can(cidrhost(c, 0)) is a practical Terraform pattern because cidrhost requires a valid CIDR expression; wrapping it in can() converts any evaluation error into false. alltrue ensures every element in var.allowed_cidrs passes validation. This causes Terraform to fail during plan when invalid input is supplied.
- B. Incorrect.
Incorrect. A precondition is a valid custom condition feature, but this implementation is not the best choice here. First, the regex only checks that the string contains digits, dots, and slashes; it does not prove the value is a valid IPv4 CIDR such as a correct prefix length or octet range. Second, input validation belongs on the variable when the goal is to reject bad module input before resource evaluation.
- C. Incorrect.
Incorrect. Postconditions are used to verify results after Terraform evaluates an object, such as confirming a resource attribute or output meets expectations. They are not the best mechanism for validating raw module input before resources are created. In this scenario, variable validation is simpler and fails earlier.
- D. Incorrect.
Incorrect. ignore_changes is a lifecycle setting that tells Terraform to disregard drift or configuration differences for specific arguments after creation. It does not validate input and does not prevent bad CIDR values from being provided. In fact, it could hide legitimate configuration changes rather than enforce correctness.