Terraform Associate Terraform Basics: 197 practice questions
7-day money-back guarantee — full refund within 7 days of purchase if you've completed under 20% of the questions. See pricing →
Certifications Tools Flashcards Career Paths Exam Guides Blog Pricing For Teams About

Language

✓ EnglishDeutschEspañolFrançaisPortuguês
Check readiness — free →

Terraform Associate Understand Terraform Basics: 197 practice questions

Terraform Associate 197 questions 12 shown free

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?

Easy
A developer clones a Terraform project from Git and runs `terraform plan`. The command fails because providers are not installed. Which command downloads and installs the required providers?
  1. 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.
  2. terraform install
    Incorrect. There is no `terraform install` command — this is a common distractor. terraform init handles installation.
  3. terraform get
    Incorrect. terraform get downloads modules, not providers. Providers are downloaded by terraform init.
  4. terraform providers install
    Incorrect. While `terraform providers` is a valid command for listing/managing providers, `terraform providers install` is not a standard command. terraform init downloads providers.
The trap
terraform get = download modules; terraform init = download providers + initialize backend + download modules

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?

Medium
A Terraform configuration contains: `version = "~> 4.0"` for the AWS provider. Which versions does this constraint allow?
  1. Any version from 4.0.0 up to 4.0.9 only, restricting upgrades to patch-level releases within 4.0
    Incorrect. 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.
  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+.
  3. Exactly version 4.0.0 and nothing else, pinning the provider to that one single immutable release
    Incorrect. 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.
  4. Version 4.0.0 and every version above it, including 5.0.0, 6.0.0, and later major releases
    Incorrect. Allowing all higher versions requires `>= 4.0`. The `~>` operator only lets the rightmost component increment, so 5.0.0 and above are excluded.
The trap
~> 4.0 = >=4.0, <5.0 (minor OK); ~> 4.0.0 = >=4.0.0, <4.1.0 (patch only) — component count matters

`~> 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

Easy
How does Terraform communicate with cloud provider APIs (AWS, Azure, GCP)?
  1. By calling cloud APIs with AWS, Azure, and GCP credentials that are hardcoded directly into the Terraform binary
    Incorrect. Credentials are supplied by the operator through environment variables, config files, or IAM roles — they are never hardcoded inside the Terraform binary.
  2. Through a central HashiCorp gateway server that receives and proxies all outbound cloud API requests
    Incorrect. Terraform communicates directly with cloud provider APIs through the provider plugin — no HashiCorp proxy or gateway sits in that path.
  3. 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.
  4. By directly embedding the full AWS, Azure, and GCP SDKs inside the single Terraform core binary
    Incorrect. Terraform core is provider-agnostic — providers are separate plugin binaries downloaded during terraform init, not SDKs baked into the core binary.
The trap
Terraform core and provider versions are independent — you can run new Terraform core with old provider versions

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

Easy
A Terraform configuration needs to reference an existing AWS VPC that was NOT created by this Terraform project. Which Terraform block type allows reading attributes of an existing resource without managing it?
  1. A module block, which packages and then calls a reusable collection of Terraform resources together as one single unit
    Incorrect. Module blocks call reusable groups of Terraform resources — they do not read the attributes of an existing resource that lives outside Terraform management.
  2. A resource block, which declares and then fully manages the lifecycle of the infrastructure it creates
    Incorrect. 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.
  3. A variable block, which defines a typed input parameter passed into the configuration at apply run time
    Incorrect. Variable blocks define input parameters passed into the configuration — they never query provider APIs to read attributes of existing infrastructure.
  4. 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.
The trap
resource = create/manage; data = read existing; mixing them up causes unintended resource creation

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?

Hard
A Terraform configuration defines a variable `region` with default `us-east-1`. The same variable is set to `eu-west-1` in `terraform.tfvars`, `eu-central-1` via environment variable `TF_VAR_region`, and `ap-southeast-1` via `-var="region=ap-southeast-1"` on the command line. Which value is used?
  1. 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.
  2. 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.
  3. 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.
  4. 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.
The trap
CLI -var is HIGHEST precedence — it overrides tfvars files and env vars (useful for one-off overrides)

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?

Easy
After running `terraform apply`, a developer wants to display the public IP address of a newly created EC2 instance in the terminal and make it available to other Terraform configurations. Which block type enables this?
  1. A locals block, which computes reusable values that stay private to the module and are never displayed
    Incorrect. Locals define values computed within a module for reuse — they are private to the module and are neither exposed externally nor printed after apply.
  2. 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.
  3. A variable block, which defines input parameters that are passed into a module before it runs
    Incorrect. Variable blocks define input parameters passed INTO a module — they cannot expose computed values FROM a module after it runs.
  4. A provider block, which configures authentication and endpoint settings for a target provider
    Incorrect. Provider blocks configure provider authentication and settings — they have no mechanism for surfacing resource attribute values after apply.
The trap
locals = private to module; outputs = public, exposed to parent module and remote state consumers

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

Medium
A Terraform module uses the expression `"${var.environment}-${var.project}"` in 15 different resource tags. A developer wants to avoid repeating this expression. Which feature centralizes this computed value within the module without exposing it externally?
  1. 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>.
  2. terraform.tfvars — store the computed value in the vars file
    Incorrect. terraform.tfvars stores literal values for input variables — it cannot contain computed expressions that reference other variables.
  3. 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.
  4. variable block — define a new variable with a computed default value
    Incorrect. Variable defaults cannot reference other variables — `default = "${var.environment}-${var.project}"` is not valid. Locals support arbitrary expression references.
The trap
Variable defaults are static; locals can reference other variables, data, and resources dynamically

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?

Medium
A Terraform configuration needs to merge two maps: `{"env": "prod"}` and `{"region": "us-east-1"}` into a single map. Which built-in function accomplishes this?
  1. 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.
  2. join(",", {"env": "prod"}, {"region": "us-east-1"})
    Incorrect. join() concatenates list elements into a string — it does not combine maps.
  3. concat({"env": "prod"}, {"region": "us-east-1"})
    Incorrect. concat() joins lists/tuples, not maps. Passing maps to concat() will cause a type error.
  4. 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.
The trap
concat() = join lists; merge() = combine maps — type matters in Terraform functions

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

Medium
In Terraform, which function returns the number of elements in a list, map, or string?
  1. 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.
  2. count(), which returns the total number of resource instances created by a count meta-argument block
    Incorrect. count is a meta-argument on resource blocks (count = 3 creates 3 instances), not a function — there is no count() function in Terraform.
  3. size(), which returns the number of stored elements found inside a given list, a map, or a string value
    Incorrect. size() is not a Terraform built-in function — the function that returns element counts is length().
  4. len(), which returns the count of items held in a given list, map, or string passed to it as input
    Incorrect. len() belongs to languages like Python and Go, not Terraform — Terraform uses length() instead.
The trap
count = resource meta-argument (creates N copies); length() = function that returns collection size

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?

Medium
A Terraform configuration needs to create resources in both us-east-1 and eu-west-1 within the same AWS account. How is this achieved?
  1. 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 once
    Incorrect. The region argument in the AWS provider accepts a single string, not a list — multiple regions require multiple provider configurations via aliases.
  2. 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`.
  3. Create two entirely separate Terraform root projects and run each one independently so that every AWS region is provisioned fully on its own
    Incorrect. While technically possible, this is the more complex path — provider aliases let you manage both regions within one configuration, which is the recommended approach.
  4. Set the AWS_REGION environment variable to both region strings separated by a comma so that the provider automatically fans out across each of them
    Incorrect. AWS_REGION accepts a single region string and does not parse a comma-separated list — multi-region deployment requires provider aliases in the configuration.
The trap
A provider block with only `alias` is NOT the default — the un-aliased provider block is the default

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

Medium
Resource B depends on Resource A, but B does not reference any attribute of A in its configuration. How can the dependency be explicitly defined to ensure A is created before B?
  1. Add a lifecycle block with create_before_destroy = true so that resource A is built before resource B
    Incorrect. create_before_destroy controls replacement ordering for a single resource during updates — it does not establish a creation-order dependency between two separate resources.
  2. Declare resource A nested inside the resource B block so Terraform builds the inner one first
    Incorrect. HCL does not support nesting one resource block inside another — resources are defined at the module level, so this is not valid syntax.
  3. 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.
  4. Run terraform plan -target=resource_a first so that resource A is applied before resource B
    Incorrect. -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.
The trap
Implicit dependency = reference to another resource's attribute; explicit = depends_on for non-obvious dependencies

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

Medium
A Terraform configuration uses `count = 3` to create 3 S3 buckets. A new requirement adds a 4th bucket in the middle of the list (index 1). What is the risk of using count vs for_each for this scenario?
  1. With count, Terraform quietly reorders all of the existing bucket resources in place without ever destroying or recreating any of them
    Incorrect. Terraform cannot reorder count resources in place — shifting indices change the state mapping, which forces destroy and recreate for the affected resources.
  2. With for_each, the very same numeric index-shifting problem still occurs whenever a new bucket key is inserted into the middle of the map
    Incorrect. 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.
  3. 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 all
    Incorrect. count uses position-sensitive numeric indices while for_each uses position-insensitive keys — that difference is significant when inserting or removing items.
  4. 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.
The trap
count = order-sensitive (avoid for ordered lists); for_each = key-based (safe for insertions/deletions)

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 — free

Other Terraform Associate domains

Part of the Certsqill Terraform Associate question bank · Understand Terraform Basics · Every answer, right and wrong, comes with its own explanation.