Terraform Associate Understand Terraform Basics: 197 practice questions
12 of the 197 Understand Terraform Basics questions in the Certsqill Terraform Associate bank, shown in full below. Each one carries an explanation for every option, not just the correct one — the wrong answers are where the marks go.
Preparing for Terraform Associate? Take the free 5-min readiness check →
1. terraform init: Which command downloads and installs the required providers?
- terraform init ✓Correct. terraform init initializes the working directory, downloads the required providers specified in required_providers blocks, and sets up the backend — it must be run before plan or apply.
- terraform installIncorrect. There is no `terraform install` command — this is a common distractor. terraform init handles installation.
- terraform getIncorrect. terraform get downloads modules, not providers. Providers are downloaded by terraform init.
- terraform providers installIncorrect. While `terraform providers` is a valid command for listing/managing providers, `terraform providers install` is not a standard command. terraform init downloads providers.
terraform init must be run first — it downloads providers, initializes the backend, and prepares the working directory for plan and apply.
2. 4.0.0 and above: Which versions does this constraint allow?
- Any version from 4.0.0 up to 4.0.9 only, restricting upgrades to patch-level releases within 4.0Incorrect. A three-part `~> 4.0.0` would restrict to patch versions (4.0.x). With two parts, `~> 4.0` also permits minor increments such as 4.1 and 4.2.
- 4.0.0 and above, but NOT 5.0.0 or higher (allows patch and minor increments only within 4.x) ✓Correct. The `~>` pessimistic constraint operator allows only rightmost version component to increment. `~> 4.0` allows >=4.0, <5.0 — any 4.x version but not 5.0+.
- Exactly version 4.0.0 and nothing else, pinning the provider to that one single immutable releaseIncorrect. Pinning to a single exact version requires `= 4.0.0`. The `~> 4.0` constraint permits any 4.x.x release, not just 4.0.0.
- Version 4.0.0 and every version above it, including 5.0.0, 6.0.0, and later major releasesIncorrect. Allowing all higher versions requires `>= 4.0`. The `~>` operator only lets the rightmost component increment, so 5.0.0 and above are excluded.
`~> 4.0` means >=4.0, <5.0 — allows any 4.x minor/patch release but prevents jumping to major version 5.
3. Through provider plugins that translate Terraform resource: How does Terraform communicate with cloud provider
- By calling cloud APIs with AWS, Azure, and GCP credentials that are hardcoded directly into the Terraform binaryIncorrect. Credentials are supplied by the operator through environment variables, config files, or IAM roles — they are never hardcoded inside the Terraform binary.
- Through a central HashiCorp gateway server that receives and proxies all outbound cloud API requestsIncorrect. Terraform communicates directly with cloud provider APIs through the provider plugin — no HashiCorp proxy or gateway sits in that path.
- Through provider plugins that translate Terraform resource definitions into API calls specific to each cloud ✓Correct. Terraform uses a plugin-based architecture where provider plugins (separate binaries) handle all API communication. The Terraform core orchestrates plugins but doesn't talk to APIs directly.
- By directly embedding the full AWS, Azure, and GCP SDKs inside the single Terraform core binaryIncorrect. Terraform core is provider-agnostic — providers are separate plugin binaries downloaded during terraform init, not SDKs baked into the core binary.
Terraform uses provider plugins — separate binaries downloaded by terraform init that translate resource definitions into cloud-specific API calls.
4. A data source: Which Terraform block type allows reading attributes of an existing resource without managing i
- A module block, which packages and then calls a reusable collection of Terraform resources together as one single unitIncorrect. Module blocks call reusable groups of Terraform resources — they do not read the attributes of an existing resource that lives outside Terraform management.
- A resource block, which declares and then fully manages the lifecycle of the infrastructure it createsIncorrect. Resource blocks CREATE and MANAGE infrastructure. Using one for the existing VPC would make Terraform try to create a new VPC rather than reference the current one.
- A variable block, which defines a typed input parameter passed into the configuration at apply run timeIncorrect. Variable blocks define input parameters passed into the configuration — they never query provider APIs to read attributes of existing infrastructure.
- A data source (data block), which reads attributes of existing infrastructure not managed by this configuration ✓Correct. Data sources (data blocks) read existing infrastructure that is not managed by the current Terraform configuration — they are read-only references to external or pre-existing resources.
Data sources (data blocks) read attributes of existing resources not managed by the current config — they are read-only and don't create or modify infrastructure.
5. ap-southeast-1: Which value is used?
- ap-southeast-1 (CLI -var flag takes highest precedence) ✓Correct. Variable precedence from highest to lowest: -var/-var-file (CLI) > *.auto.tfvars > terraform.tfvars > TF_VAR_ env vars > default. CLI flags always win.
- eu-west-1 (terraform.tfvars overrides everything)Incorrect. terraform.tfvars is overridden by *.auto.tfvars, CLI -var flags, and -var-file arguments. It does not take highest precedence.
- eu-central-1 (environment variables have highest precedence)Incorrect. TF_VAR_ environment variables have lower precedence than terraform.tfvars, *.auto.tfvars, and CLI -var flags.
- us-east-1 (the default value is always used when multiple sources conflict)Incorrect. The default value has the LOWEST precedence — any other source overrides it. It's only used when no other value is provided.
CLI -var flags have the highest precedence. Full order: CLI > *.auto.tfvars > terraform.tfvars > TF_VAR_ env vars > default.
6. An output block: Which block type enables this?
- A locals block, which computes reusable values that stay private to the module and are never displayedIncorrect. Locals define values computed within a module for reuse — they are private to the module and are neither exposed externally nor printed after apply.
- An output block, which prints selected values after apply and exposes them to other configurations ✓Correct. Output blocks display specified values in the terminal after apply and expose them to parent modules or other configurations that reference this module's state via terraform_remote_state.
- A variable block, which defines input parameters that are passed into a module before it runsIncorrect. Variable blocks define input parameters passed INTO a module — they cannot expose computed values FROM a module after it runs.
- A provider block, which configures authentication and endpoint settings for a target providerIncorrect. Provider blocks configure provider authentication and settings — they have no mechanism for surfacing resource attribute values after apply.
Output blocks expose resource attribute values after apply — displayed in terminal, accessible to parent modules, and queryable via terraform output command.
7. locals block — define the expression once and reference it: Which feature centralizes this computed value with
- output block — define the expression as an output and reference it as self.<name>Incorrect. Outputs expose values externally — they are not for DRY (Don't Repeat Yourself) within a module. Outputs cannot be referenced internally with self.<name>.
- terraform.tfvars — store the computed value in the vars fileIncorrect. terraform.tfvars stores literal values for input variables — it cannot contain computed expressions that reference other variables.
- locals block — define the expression once and reference it as local.<name> ✓Correct. Locals define named computed values within a module. `local.env_prefix` can be referenced in all 15 resource tags, centralizing the expression and making it easy to update.
- variable block — define a new variable with a computed default valueIncorrect. Variable defaults cannot reference other variables — `default = "${var.environment}-${var.project}"` is not valid. Locals support arbitrary expression references.
Locals define computed values inside a module for reuse — `locals { env_prefix = "${var.environment}-${var.project}" }` can be referenced as `local.env_prefix` anywhere in the module.
8. merge: Which built-in function accomplishes this?
- lookup({"env": "prod"}, "region", "us-east-1")Incorrect. lookup() retrieves a value from a single map by key with an optional default — it doesn't merge two maps.
- join(",", {"env": "prod"}, {"region": "us-east-1"})Incorrect. join() concatenates list elements into a string — it does not combine maps.
- concat({"env": "prod"}, {"region": "us-east-1"})Incorrect. concat() joins lists/tuples, not maps. Passing maps to concat() will cause a type error.
- merge({"env": "prod"}, {"region": "us-east-1"}) ✓Correct. The merge() function combines multiple maps into one — later arguments' keys override earlier arguments' keys if there are conflicts.
merge() combines multiple maps into one, with later arguments overriding earlier ones on key conflicts.
9. length , which returns the element count of a list,: In Terraform, which function returns the number of elemen
- length(), which returns the element count of a list, the pair count of a map, or a string's characters ✓Correct. length() returns the number of elements in a list, the number of key-value pairs in a map, or the number of characters in a string.
- count(), which returns the total number of resource instances created by a count meta-argument blockIncorrect. count is a meta-argument on resource blocks (count = 3 creates 3 instances), not a function — there is no count() function in Terraform.
- size(), which returns the number of stored elements found inside a given list, a map, or a string valueIncorrect. size() is not a Terraform built-in function — the function that returns element counts is length().
- len(), which returns the count of items held in a given list, map, or string passed to it as inputIncorrect. len() belongs to languages like Python and Go, not Terraform — Terraform uses length() instead.
length() returns the count of elements in a list/map or characters in a string — a commonly used function in Terraform for dynamic resource creation.
10. Define two AWS provider blocks with different `alias`: How is this achieved?
- Use a single AWS provider block and set region = ["us-east-1", "eu-west-1"] as a list so that it targets both regions at onceIncorrect. The region argument in the AWS provider accepts a single string, not a list — multiple regions require multiple provider configurations via aliases.
- Define two AWS provider blocks with different `alias` values and reference the appropriate alias in each resource using `provider = aws.<alias>` ✓Correct. Provider aliases allow multiple configurations of the same provider. Each alias can specify a different region, and resources reference their target provider via `provider = aws.eu`.
- Create two entirely separate Terraform root projects and run each one independently so that every AWS region is provisioned fully on its ownIncorrect. While technically possible, this is the more complex path — provider aliases let you manage both regions within one configuration, which is the recommended approach.
- Set the AWS_REGION environment variable to both region strings separated by a comma so that the provider automatically fans out across each of themIncorrect. AWS_REGION accepts a single region string and does not parse a comma-separated list — multi-region deployment requires provider aliases in the configuration.
Provider aliases allow multiple configurations of the same provider (different regions/accounts). Resources reference their target with `provider = aws.<alias>`.
11. Use the depends_on meta-argument in resource B's: How can the dependency be explicitly defined to ensure A is
- Add a lifecycle block with create_before_destroy = true so that resource A is built before resource BIncorrect. create_before_destroy controls replacement ordering for a single resource during updates — it does not establish a creation-order dependency between two separate resources.
- Declare resource A nested inside the resource B block so Terraform builds the inner one firstIncorrect. HCL does not support nesting one resource block inside another — resources are defined at the module level, so this is not valid syntax.
- Use the depends_on meta-argument in resource B's configuration to declare the ordering explicitly ✓Correct. depends_on creates explicit dependencies when no reference exists in the configuration. Terraform uses it to enforce creation order.
- Run terraform plan -target=resource_a first so that resource A is applied before resource BIncorrect. -target selects specific resources for a single run — it is not a persistent dependency declaration, and the question asks how to define the dependency in configuration.
depends_on creates explicit dependencies when resources don't reference each other's attributes — Terraform uses it to enforce creation ordering.
12. With count, inserting a bucket at index 1 shifts indices: What is the risk of using count vs for_each for this
- With count, Terraform quietly reorders all of the existing bucket resources in place without ever destroying or recreating any of themIncorrect. Terraform cannot reorder count resources in place — shifting indices change the state mapping, which forces destroy and recreate for the affected resources.
- With for_each, the very same numeric index-shifting problem still occurs whenever a new bucket key is inserted into the middle of the mapIncorrect. for_each uses named keys rather than numeric indices, so adding a new key only creates the new resource and leaves the existing ones untouched.
- count and for_each behave in an identical way in this scenario, so there is genuinely no meaningful risk difference between the two available approaches at allIncorrect. count uses position-sensitive numeric indices while for_each uses position-insensitive keys — that difference is significant when inserting or removing items.
- With count, inserting a bucket at index 1 shifts indices for all subsequent buckets, potentially triggering destruction and recreation of those resources ✓Correct. count uses numeric indices (0, 1, 2). Inserting at index 1 renumbers existing resources, causing Terraform to plan destroy+recreate for the shifted resources.
count uses numeric indices — inserting at index 1 shifts all subsequent resources, causing unintended destroy+recreate. for_each uses named keys, avoiding this problem.
185 more Understand Terraform Basics questions
The remaining 185 questions in this domain are part of the full Terraform Associate bank — 495 questions, every option explained. Start with the free five-minute check and see your score per domain.
Test your Terraform Associate readiness — freeOther Terraform Associate domains
- Implement and Maintain State — 77 questions →
- Interact with Terraform Modules — 50 questions →
- Use and Apply the Terraform Workflow — 49 questions →
- Understand Infrastructure as Code (IaC) Concepts — 45 questions →
- Understand Terraform's Purpose (vs Other IaC) — 40 questions →
- All 495 Terraform Associate questions →