First 50 of 200 questions. Each one lists the choices, the correct answer, and an explanation. The checker at the top of this page saves progress in this browser when it is available.
Continue in the practice tool above to load more questions, 50 at a time.
Question 1Author and refactor Terraform configuration (expressions, functions, dynamic blocks, validation, lifecycle)
Given var.ids = [1, 2, 3], what value does the expression [for n in var.ids : n * 2] produce?
- {2, 4, 6}
- [2, 4, 6] Correct answer.
- "246"
- [1, 2, 3, 1, 2, 3]
Explanation
A for expression wrapped in square brackets produces a tuple (ordered list) with one element per source element, preserving order. Here each element is doubled, giving [2, 4, 6].
Question 2Author and refactor Terraform configuration (expressions, functions, dynamic blocks, validation, lifecycle)
A resource uses count = 3 and is referenced as aws_instance.web[*].id. What does that splat expression return?
- A list of the three IDs in count order Correct answer.
- A set of the three IDs with duplicates removed
- A comma-separated string of the three IDs
- A map of IDs keyed by instance index
Explanation
The splat operator over a counted resource produces a tuple of attribute values for each instance, ordered by index. It never joins values or converts the result to a set.
Question 3Author and refactor Terraform configuration (expressions, functions, dynamic blocks, validation, lifecycle)
What requirement applies to the two result expressions in a conditional expression cond ? a : b?
- Both results must be literal values
- Both results must have the same type, or types that convert to a common one Correct answer.
- The false result must be a collection
- The true result must always be a string
Explanation
Terraform must be able to determine a single result type at plan time, so the two arms must share a type or be convertible to one. Mixing unrelated types such as string and number in incompatible ways raises an error.
Question 4Author and refactor Terraform configuration (expressions, functions, dynamic blocks, validation, lifecycle)
A resource is declared with lifecycle { prevent_destroy = true }. What happens when a plan would remove that resource?
- Terraform skips the destroy and continues with other changes
- Terraform converts the destroy into an in-place update
- Terraform returns an error and blocks the operation Correct answer.
- Terraform marks the resource as orphaned in state
Explanation
prevent_destroy causes Terraform to fail the plan or apply with an error whenever the resource would be destroyed. It does not silently alter the plan or remove the object from state.
Question 5Author and refactor Terraform configuration (expressions, functions, dynamic blocks, validation, lifecycle)
Which pair of arguments is required inside a variable validation block?
- value and error_message
- condition and error_message Correct answer.
- condition and message
- expression and error
Explanation
A validation block must contain a condition expression that evaluates to true or false and an error_message string shown when it is false. Any other argument names are not part of the schema.
Question 6Author and refactor Terraform configuration (expressions, functions, dynamic blocks, validation, lifecycle)
A module block includes depends_on = [aws_iam_role_policy.app]. What does this accomplish?
- It exports the module outputs to the policy resource
- It passes the policy object into the module as an input
- It makes everything in the module wait until the named resource is complete Correct answer.
- It forces the module to be replaced whenever the policy changes
Explanation
depends_on on a module block creates an explicit dependency on the whole module, so all of its resources are processed after the referenced object. It does not pass values or force replacement.
Question 7Author and refactor Terraform configuration (expressions, functions, dynamic blocks, validation, lifecycle)
What does the can(expression) function return?
- The error message produced by the expression
- null if the expression fails and the value otherwise
- A boolean reporting whether the expression evaluated without error Correct answer.
- The expression result wrapped in a warning
Explanation
can() evaluates its argument and returns true if evaluation succeeds and false if it raises an error. It discards the actual value and never propagates the error.
Question 8Author and refactor Terraform configuration (expressions, functions, dynamic blocks, validation, lifecycle)
Which construct generates zero or more repeated nested blocks from a collection inside a resource?
- Using a for expression as a block body
- A dynamic block with for_each and content Correct answer.
- Setting for_each on the resource itself
- Using count inside the nested block
Explanation
A dynamic block iterates a collection and renders a nested block per element using its content block. Resource-level for_each and count control whole resource instances, not nested blocks.
Question 9Author and refactor Terraform configuration (expressions, functions, dynamic blocks, validation, lifecycle)
In dynamic "ingress" { for_each = var.rules ... iterator = rule ... content { from_port = rule.value.from } }, what does rule.value refer to?
- The block label as a string
- The numeric index of the current element
- The current element of var.rules Correct answer.
- The parent security group resource
Explanation
The iterator argument renames the loop variable, and .value on that iterator gives the current element of the for_each collection. The default iterator name would be the block label, ingress.
Question 10Author and refactor Terraform configuration (expressions, functions, dynamic blocks, validation, lifecycle)
In the expression [for s in var.names : upper(s) if s != ""], what role does the if clause play?
- It must appear before the value expression to be valid
- It filters out elements for which the condition is false Correct answer.
- It raises an error when the condition is false
- It converts the resulting tuple into a set
Explanation
An if clause in a for expression acts as a filter: only source elements whose condition is true produce an output element. It always appears after the value expression.
Question 11Author and refactor Terraform configuration (expressions, functions, dynamic blocks, validation, lifecycle)
What does the grouping form {for k, v in var.items : k => v...} produce when several elements share a key?
- An error because duplicate keys are not allowed
- A list of single-entry maps
- A map keeping only the last value for each key
- A map whose values are lists of all matching elements Correct answer.
Explanation
The trailing ellipsis enables grouping mode, so repeated keys are collected into a list of values rather than overwriting. Without the ellipsis, duplicate keys would cause an error.
Question 12Author and refactor Terraform configuration (expressions, functions, dynamic blocks, validation, lifecycle)
When does try(var.settings.advanced.mode, "default") return "default"?
- Never, because try always returns its first argument
- When evaluating the first argument raises an error Correct answer.
- Only when var.settings is null
- Whenever the first argument evaluates to an empty string
Explanation
try() returns the first argument that evaluates successfully and falls through to later arguments only on error, such as accessing an attribute of a null value. An empty string is a successful result, not an error.
Question 13Author and refactor Terraform configuration (expressions, functions, dynamic blocks, validation, lifecycle)
Given coalesce(var.primary, var.secondary, "fallback"), which argument is returned?
- The first argument that is not null, even if empty
- The last argument that is not null
- The first argument that is neither null nor an empty string Correct answer.
- All arguments concatenated in order
Explanation
coalesce returns its first argument that is not null and not an empty string, so empty strings are skipped. If every argument is null or empty it raises an error.
Question 14Author and refactor Terraform configuration (expressions, functions, dynamic blocks, validation, lifecycle)
What is the result of lookup(var.tags, "env", "dev") when var.tags is {team = "core"}?
- The full map {team = "core"}
- An error for a missing key
- "dev" Correct answer.
- null
Explanation
The third argument of lookup is a default returned when the key is absent. An error only occurs when the key is missing and no default is supplied.
Question 15Author and refactor Terraform configuration (expressions, functions, dynamic blocks, validation, lifecycle)
What does setproduct(["a", "b"], [1, 2]) return?
- ["a1", "a2", "b1", "b2"]
- [["a", 1], ["a", 2], ["b", 1], ["b", 2]] Correct answer.
- A four-element tuple of numbers
- {a = 1, b = 2}
Explanation
setproduct computes the Cartesian product and returns a list of lists, each inner list holding one element from every input set. Elements are not concatenated or paired into a map.
Question 16Author and refactor Terraform configuration (expressions, functions, dynamic blocks, validation, lifecycle)
What is the effect of lifecycle { ignore_changes = all } on a resource?
- It ignores only out-of-band tag changes
- It prevents the resource from ever being replaced
- It ignores all attribute changes made outside Terraform Correct answer.
- It disables every lifecycle meta-argument for the resource
Explanation
The special keyword all tells Terraform to disregard any differences between configuration and remote state for every attribute of that resource. Configuration changes to the resource itself are still applied.
Question 17Author and refactor Terraform configuration (expressions, functions, dynamic blocks, validation, lifecycle)
Which statement describes create_before_destroy = true during a replacement?
- It forces a replacement on every apply run
- The replacement object is created before the original is destroyed Correct answer.
- The original is destroyed first, then the replacement is created
- It only affects resources deleted at the end of an apply
Explanation
create_before_destroy reverses the usual order so the new object exists before the old one is removed, reducing downtime. It can fail when both objects would need the same unique name.
Question 18Author and refactor Terraform configuration (expressions, functions, dynamic blocks, validation, lifecycle)
A resource declares lifecycle { replace_triggered_by = [aws_instance.base.id] }. What behavior does this produce?
- An ordering dependency is added without any recreation
- Changes to the listed expression are ignored for drift detection
- The resource is recreated whenever the listed expression changes value Correct answer.
- A taint is applied to the resource on each destroy
Explanation
replace_triggered_by forces replacement of the resource when any referenced expression changes between plan runs. It creates a replacement dependency rather than a plain ordering dependency.
Question 19Author and refactor Terraform configuration (expressions, functions, dynamic blocks, validation, lifecycle)
Which keyword lets a resource postcondition inspect the resource's own computed attributes?
- self Correct answer.
- value
- resource
- this
Explanation
Inside a postcondition, self refers to the object being validated, giving access to attributes computed during apply. Preconditions cannot use self because the object does not yet exist.
Question 20Author and refactor Terraform configuration (expressions, functions, dynamic blocks, validation, lifecycle)
You need to rename a resource in configuration without destroying and recreating the real object. What should you add?
- A moved block mapping the old address to the new address Correct answer.
- A lifecycle ignore_changes argument on the resource
- A terraform import command after applying
- A terraform state rm command before applying
Explanation
A moved block records the address change so Terraform rewrites state instead of planning a destroy and create. It keeps the same remote object associated with the new address.
Question 21Author and refactor Terraform configuration (expressions, functions, dynamic blocks, validation, lifecycle)
Which reference is permitted inside a variable validation condition?
- Another variable in the same module
- An attribute of a managed resource
- A local value derived from other inputs
- The variable being validated Correct answer.
Explanation
Validation conditions may only refer to the variable they belong to, so checks stay self-contained and can run before other values exist. Referencing other variables, locals, or resources is rejected.
Question 22Author and refactor Terraform configuration (expressions, functions, dynamic blocks, validation, lifecycle)
An object type constraint declares optional(string, "t3.micro") for the size attribute. What does this do?
- It substitutes the default when the attribute is omitted or null Correct answer.
- It forces the caller to pass an empty string
- It makes the attribute required in every call
- It only documents intent and has no runtime effect
Explanation
The second argument of optional() supplies a default that Terraform applies when the attribute is absent or explicitly null. The attribute becomes optional while still defaulting to a known value.
Question 23Author and refactor Terraform configuration (expressions, functions, dynamic blocks, validation, lifecycle)
A resource uses for_each = { for s in aws_subnet.private : s.id => s }. Why does this fail at plan time?
- for_each requires a set of objects rather than a map
- Maps cannot be used with for_each on managed resources
- The keys are unknown until apply, but for_each keys must be known at plan Correct answer.
- Map keys must be strings and subnet IDs are not
Explanation
Each for_each key becomes part of the resource address, so Terraform needs all keys during planning. Subnet IDs are computed only after apply, making the key set unknown and the plan invalid.
Question 24Author and refactor Terraform configuration (expressions, functions, dynamic blocks, validation, lifecycle)
An output must expose, as plain text, a value that originates from a variable marked sensitive. Which function accomplishes this?
- sensitive()
- tostring()
- base64decode()
- nonsensitive() Correct answer.
Explanation
nonsensitive() removes the sensitive marking from a value so it can be rendered in an output or log. It should be used deliberately, since it exposes data Terraform would otherwise redact.
Question 25Author and refactor Terraform configuration (expressions, functions, dynamic blocks, validation, lifecycle)
Which of these block types can be produced by a dynamic block?
- A provisioner block inside a resource
- A terraform settings block at the top level
- A lifecycle block inside a resource
- A nested block defined by the resource type, such as ingress Correct answer.
Explanation
Dynamic blocks generate repeated nested blocks that belong to the resource type's schema, such as ingress rules. Meta-blocks like lifecycle and provisioner cannot be generated dynamically.
Question 26Author and refactor Terraform configuration (expressions, functions, dynamic blocks, validation, lifecycle)
An expression `aws_instance.web[*].id` is used where `aws_instance.web` has `count = 2`. What type of value does it produce?
- A map keyed by each instance index
- A set containing the two IDs in no fixed order
- A tuple of two IDs, in index order Correct answer.
- A single string joining both IDs with commas
Explanation
The splat operator applied to a resource with count produces a tuple holding that attribute for each instance, ordered by index. It always yields a collection, even when only one instance exists.
Question 27Author and refactor Terraform configuration (expressions, functions, dynamic blocks, validation, lifecycle)
What does `flatten([["a", "b"], ["c", ["d"]]])` return?
- ["a", "b", "c", "d"] Correct answer.
- An error, because the input mixes nesting depths
- [["a", "b"], ["c", ["d"]]]
- ["a", "b", "c", ["d"]]
Explanation
flatten recursively unwraps nested lists at every depth and returns a single flat list. Mixed nesting depth is acceptable input.
Question 28Author and refactor Terraform configuration (expressions, functions, dynamic blocks, validation, lifecycle)
Given `var.azs = ["us-east-1a", "us-east-1b", "us-east-1c"]`, what does `element(var.azs, 4)` return?
- null
- us-east-1c
- us-east-1b Correct answer.
- An error, because index 4 is out of range
Explanation
element wraps the index around the length of the list using modulo, so 4 modulo 3 selects position 1. It never raises an out-of-range error for a non-empty list.
Question 29Author and refactor Terraform configuration (expressions, functions, dynamic blocks, validation, lifecycle)
A resource declares `lifecycle { prevent_destroy = true }`. What happens when a plan would delete that object?
- The object is deleted after a manual confirmation prompt
- The object is deleted and immediately recreated from state
- Terraform removes the object from state without deleting it
- The plan fails with an error protecting the resource Correct answer.
Explanation
prevent_destroy makes any plan that would destroy the object fail, so the lifecycle rule must be removed before the destroy can proceed. The protection applies at plan time.
Question 30Author and refactor Terraform configuration (expressions, functions, dynamic blocks, validation, lifecycle)
A variable block declares `type = string`, `default = "small"` and `nullable = false`. The caller passes `size = null`. What value does the variable receive?
- small Correct answer.
- null
- An empty string
- A plan-time error about an invalid default
Explanation
With nullable = false, a null argument is replaced by the declared default when one exists. Only variables with no default reject null outright.
Question 31Author and refactor Terraform configuration (expressions, functions, dynamic blocks, validation, lifecycle)
What does `zipmap(["a", "b"], [1, 2])` produce?
- {a = 1, b = 2} Correct answer.
- {1 = "a", 2 = "b"}
- [["a", 1], ["b", 2]]
- [{a = 1}, {b = 2}]
Explanation
zipmap pairs the two lists positionally, using the first list as keys and the second as values. Both lists must be the same length.
Question 32Author and refactor Terraform configuration (expressions, functions, dynamic blocks, validation, lifecycle)
A resource uses count over a list of subnet names. A new name is inserted at the beginning of the list. What is the plan result?
- Terraform errors and demands a moved block before planning
- The whole resource block is destroyed and recreated
- Every existing instance is planned for replacement Correct answer.
- Only the new subnet is created; existing instances are untouched
Explanation
count addresses instances by list position, so inserting an element shifts every later index and each shifted index is treated as a new object. Keying instances with for_each avoids this positional churn.
Question 33Author and refactor Terraform configuration (expressions, functions, dynamic blocks, validation, lifecycle)
What does `one(var.ids)` return when `var.ids` is an empty list?
- The number 0
- An empty list
- null Correct answer.
- An error, because the list has no elements
Explanation
one() returns null for an empty collection, the single element for a one-element collection, and raises an error only when more than one element is present.
Question 34Author and refactor Terraform configuration (expressions, functions, dynamic blocks, validation, lifecycle)
How do you make a resource optional based on `var.enabled`, so that no instance exists when it is false?
- for_each = var.enabled ? {} : { one = true }
- lifecycle { enabled = var.enabled }
- count = var.enabled ? 1 : 0 Correct answer.
- count = var.enabled
Explanation
count accepts a number, so a conditional yielding 1 or 0 creates exactly one instance when enabled and none when disabled. The resource is then referenced with an index such as [0].
Question 35Author and refactor Terraform configuration (expressions, functions, dynamic blocks, validation, lifecycle)
A variable declares `validation { condition = can(regex("^[a-z]+$", var.name)) ; error_message = "lowercase letters only" }`. A caller passes `"Web1"`. What happens?
- Terraform reports the error_message and stops the plan Correct answer.
- The validation is skipped because regex only inspects numbers
- The value is silently converted to lowercase
- The variable falls back to its default value
Explanation
A validation condition that evaluates to false causes Terraform to raise error_message and halt before any resource changes. can() converts the regex failure into false rather than an error.
Question 36Author and refactor Terraform configuration (expressions, functions, dynamic blocks, validation, lifecycle)
What does `compact(["a", "", "b", null])` return?
- ["a", "b"] Correct answer.
- ["a", "", "b", null]
- An error, because null is not a string
- ["a", "b", null]
Explanation
compact removes both null and empty-string elements, returning only the non-empty strings. It accepts null elements by design.
Question 37Author and refactor Terraform configuration (expressions, functions, dynamic blocks, validation, lifecycle)
What does `cidrsubnet("10.0.0.0/16", 8, 2)` return?
- 10.0.2.0/16
- 10.0.0.2/24
- 10.0.2.0/24 Correct answer.
- 10.2.0.0/24
Explanation
cidrsubnet(prefix, newbits, netnum) extends the prefix by 8 bits, turning a /16 into a /24, and places subnet number 2 in the new bits.
Question 38Author and refactor Terraform configuration (expressions, functions, dynamic blocks, validation, lifecycle)
Given `local.a = { x = 1, y = 2 }` and `local.b = { y = 3, z = 4 }`, what is `merge(local.a, local.b)`?
- {y = 3}
- An error, because the maps share the key y
- {x = 1, y = 3, z = 4} Correct answer.
- {x = 1, y = 2, z = 4}
Explanation
merge combines all keys from every argument map, and when keys collide the value from the later argument wins. Duplicate keys are permitted and resolved by precedence.
Question 39Author and refactor Terraform configuration (expressions, functions, dynamic blocks, validation, lifecycle)
A resource declares `lifecycle { precondition { condition = ... ; error_message = "..." } }`. When is the condition evaluated, and what does a false result do?
- Only during terraform validate; a false result is reported as a warning
- After the resource is created; a false result is only a warning
- Before the resource is created or updated; a false result stops the apply Correct answer.
- After every plan; a false result cancels the plan before any change
Explanation
Preconditions run during apply before the resource is created or updated, and a false condition fails the apply using error_message. Postconditions run after the change instead.
Question 40Author and refactor Terraform configuration (expressions, functions, dynamic blocks, validation, lifecycle)
`var.enabled` is true. The expression `var.enabled ? "enabled" : []` is evaluated. What is the result?
- null, because Terraform cannot unify the two branch types
- A one-element list containing "enabled"
- The string "enabled"
- An error: inconsistent conditional result types Correct answer.
Explanation
Terraform unifies the types of both branches before evaluating the condition, so a string branch and a tuple branch cannot be reconciled. The error occurs even though the failing branch would not be selected.
Question 41Author and refactor Terraform configuration (expressions, functions, dynamic blocks, validation, lifecycle)
An existing S3 bucket with the real-world name `logs-prod` must be brought under management declaratively. Which configuration does this?
- lifecycle { import = "logs-prod" } inside the resource
- An import block with to = aws_s3_bucket.logs and id = "logs-prod" Correct answer.
- A terraform import command invoked from a null_resource provisioner
- terraform state mv aws_s3_bucket.logs aws_s3_bucket.logs["logs-prod"]
Explanation
An import block names the configuration address in to and the real-world identifier in id, and the object is adopted on the next apply. This keeps the adoption in version-controlled configuration.
Question 42Author and refactor Terraform configuration (expressions, functions, dynamic blocks, validation, lifecycle)
Given `var.azs = { a = "us-east-1a", b = "us-east-1b" }`, what does `[for k, v in var.azs : v]` produce?
- A list of the two zone names in key-sorted order Correct answer.
- A set of the two zone names
- An error, since iterating a map requires an index
- A map from each key to its zone name
Explanation
A for expression written with brackets builds a tuple, and iterating a map visits keys in lexical order. Braces would be required to build a map result.
Question 43Author and refactor Terraform configuration (expressions, functions, dynamic blocks, validation, lifecycle)
A variable `var.ingress` defaults to null, and a dynamic block sets `for_each = var.ingress`. What happens when the variable is null?
- Terraform substitutes an empty map automatically
- An error: for_each cannot accept a null value Correct answer.
- The dynamic block is skipped without any message
- The dynamic block produces a single block whose arguments are all null
Explanation
The for_each argument of a dynamic block must be a non-null collection, and a null value raises an invalid for_each error. The usual guard is `for_each = var.ingress == null ? [] : var.ingress`.
Question 44Author and refactor Terraform configuration (expressions, functions, dynamic blocks, validation, lifecycle)
A data source declares `depends_on = [aws_instance.bootstrap]`. How does this affect a plan?
- The data source is still read during plan as usual; depends_on has no effect on data sources
- The data source is read twice, once during plan and once during apply
- The read is deferred to apply, so attributes may be unknown at plan Correct answer.
- The data source is converted into a managed resource that Terraform creates
Explanation
depends_on on a data source forces the read to be postponed until the dependencies have been applied, so its attributes cannot be known during plan. References to those attributes therefore stay unknown until apply.
Question 45Manage Terraform state, backends, and state operations
What is the primary purpose of Terraform state?
- To record the Terraform version used to create each module
- To store the provider credentials used during the last apply
- To cache the results of every plan for later comparison
- To map configured resources to the real objects that exist remotely Correct answer.
Explanation
State binds each resource address in the configuration to a real remote object and records that object's attribute values, which lets Terraform compute diffs and detect drift on later runs.
Question 46Manage Terraform state, backends, and state operations
A configuration contains no backend block. Where does Terraform keep its state by default?
- In the user's home directory under ~/.terraform/state
- In memory only, until terraform state push is run
- In the .terraform/modules directory of the root module
- In a local file named terraform.tfstate in the working directory Correct answer.
Explanation
With no backend block Terraform uses the implicit local backend, which writes the state to terraform.tfstate in the current working directory alongside a backup file.
Question 47Manage Terraform state, backends, and state operations
Which AWS service does the S3 backend traditionally use to provide state locking?
- AWS CloudTrail
- AWS IAM
- AWS KMS
- Amazon DynamoDB Correct answer.
Explanation
The S3 backend supports locking through a DynamoDB table named in the dynamodb_table argument; newer Terraform versions can also use an S3 lock file via use_lockfile.
Question 48Manage Terraform state, backends, and state operations
Which command lists the resource addresses currently recorded in state?
- terraform state show
- terraform providers
- terraform show -list
- terraform state list Correct answer.
Explanation
terraform state list prints one resource or instance address per line from the current state, which is useful for finding addresses to pass to other state commands.
Question 49Manage Terraform state, backends, and state operations
Which command writes the current remote state to standard output in JSON format?
- terraform state pull Correct answer.
- terraform state list -json
- terraform output -json
- terraform state show -json
Explanation
terraform state pull fetches the state from the configured backend and prints the raw JSON, which is commonly used for backups or inspection scripts.
Question 50Manage Terraform state, backends, and state operations
A resource attribute is marked sensitive in the provider schema. How does that value appear in the state file?
- It is stored in plaintext like any other attribute Correct answer.
- It is replaced with a hash of the value
- It is encrypted with the provider's default key
- It is omitted from the state file entirely
Explanation
Marking a value sensitive only suppresses it in CLI output; the raw value is still persisted in state, which is why remote state must be protected with encryption and access controls.