TF-Associate-004 domain - 11% of the exam

Terraform fundamentals

Terraform fundamentals is 11% of the TF-Associate-004 exam. These are the objectives it covers, each with practice questions, with every answer explained.

The domain in numbers

33
Practice questions
4
Objectives
9
Easy
24
Medium

Where people go wrong

  • Selecting an aliased provider in the wrong place

    The wrong answers put the choice of an aliased aws configuration somewhere other than the provider meta-argument. They set region on the resource, add an alias argument to it, reach for depends_on, or wrap the reference in quotes. Region and alias belong in the provider block that defines the extra configuration. A resource opts in with provider = aws.sydney, a bare reference of provider type, a dot and the alias.

    See it in a sample question
  • Passing an aliased provider into a module

    The wrong answers pass an aliased provider into a module through something other than the providers map: an alias argument or the singular provider meta-argument on the module block, an export argument on the provider block, or a duplicate provider block inside the child. Default providers are inherited implicitly, but aliased configurations are not. A module block takes a providers map, such as providers = { google = google.europe }, which links the name the child uses to a specific configuration in the caller.

    See it in a sample question
  • Misreading the pessimistic version constraint

    The wrong answers treat ~> as an exact pin, as a plain minimum with no ceiling, or as a reason to take the newest release overall. The operator holds the left-hand segments fixed and lets the rightmost segment rise. With ~> 3.4 that permits 3.4.0 up to but not including 4.0.0, and Terraform selects the highest release inside that range, not the lowest.

    See it in a sample question
  • Giving the dependency lock file another job

    The wrong answers give the dependency lock file jobs that belong elsewhere: tracking real infrastructure, which is the state file; storing plugin binaries, which sit in the plugin cache; or holding version ranges, which required_providers declares. A related slip treats it as the state lock and reaches for terraform force-unlock. The lock file records the exact provider versions and hashes selected. terraform providers lock -platform appends checksums for another operating system without changing those versions, whereas init -upgrade can change them.

    See it in a sample question
  • Naming the wrong baseline for a plan

    The wrong answers compare the configuration against version control history, an apply log, a full scan of the account, the provider schema or cached plugins. None of these records what Terraform applied. A plan diffs the desired configuration against the resource attributes held in state from the last apply, and proposes create, update or destroy actions to close the gap.

    See it in a sample question

Objectives in this domain

Sample questions from this domain

Free sampleTerraform fundamentalsmedium

What is the correct syntax for a resource's provider meta-argument when it must be provisioned by an additional aws configuration declared with alias = "europe"?

  • Aprovider = "aws.europe", supplying the aliased reference as a quoted string literal.
  • Balias = "europe", repeating the alias on the resource so it matches the aliased provider block.
  • Cprovider = aws.europe, referencing the provider type followed by a dot and the alias name. Correct
  • Dprovider = "europe", naming only the alias because the provider type is already implied by the resource type.
A resource binds to an aliased provider using provider = TYPE.ALIAS as an unquoted reference expression. The provider meta-argument expects a reference of the form <PROVIDER_TYPE>.<ALIAS>, written without quotes because it is an expression rather than a string. This links the resource to the specific additional provider configuration carrying that alias.

Why A is wrong: Tempting because most argument values are strings, but the provider meta-argument takes a reference expression, not a quoted string, so quoting it is invalid.

Why B is wrong: Tempting because alias names the configuration, but alias is a provider-block argument; a resource selects a configuration with provider, not alias.

Why C is correct: Correct: the provider meta-argument accepts a <TYPE>.<ALIAS> reference expression, which binds the resource to that additional configuration.

Why D is wrong: Tempting since the resource type implies aws, but the reference must still be the full aws.europe form and must not be a quoted string.

Free sampleTerraform fundamentalsmedium

A configuration defines a default google provider and a google provider aliased as 'europe'. A module named 'network' needs to create resources under the europe configuration while the rest of the root module keeps using the default. How should the practitioner pass the aliased provider into the module?

module "network" {
  source = "./modules/network"
  # provider wiring goes here
}
  • AAdd alias = "europe" as an argument to the module block so the module inherits the aliased provider.
  • BSet provider = google.europe on the module block, matching how a resource selects a provider.
  • CAdd a providers = { google = google.europe } map to the module block so the child receives the aliased configuration. Correct
  • DRedeclare the aliased provider block inside the child module so its resources pick it up automatically.
Pass an aliased provider configuration to a child module using the module block's providers map. A child module receives explicit provider configurations through the providers meta-argument on the module block, which maps each provider name the module expects to a chosen configuration such as an alias in the calling module.

Why A is wrong: There is no alias argument on a module block; provider selection for a child module is done through the providers map, so this is not valid configuration.

Why B is wrong: The singular provider meta-argument works on resource and data blocks, but a module block uses the plural providers map, so this borrows the wrong argument.

Why C is correct: The providers meta-argument on a module block maps a provider name used inside the child to a specific configuration in the caller, and google.europe passes the aliased configuration explicitly.

Why D is wrong: Best practice is for child modules to receive provider configurations from the caller rather than declaring their own, and duplicating the block does not connect it to the root credentials as intended.

Free sampleTerraform fundamentalsmedium

A configuration pins a provider with the constraint shown. The latest available releases are 4.9.0, 4.12.3, and 5.1.0. A practitioner runs 'terraform init' in a directory that has no existing lock file. Which version does Terraform select?

required_providers {
  aws = {
    source  = "hashicorp/aws"
    version = "~> 4.9"
  }
}
  • A5.1.0, because it is the newest published release and no lock file yet exists to constrain the choice.
  • B4.9.0, because the ~> operator pins Terraform to the exact minor version named in the constraint.
  • C4.9.0, because with no lock file Terraform always installs the lowest version that satisfies the constraint for stability.
  • D4.12.3, because ~> 4.9 permits any 4.x release at or above 4.9.0 but below 5.0.0. Correct
The ~> operator allows the rightmost version component to increase, so Terraform installs the newest matching release within that bound. The pessimistic constraint operator ~> 4.9 is equivalent to >= 4.9.0 and < 5.0.0, and Terraform always chooses the highest release satisfying the constraint, which is 4.12.3 among the available versions.

Why A is wrong: Without a lock file Terraform still honours the version constraint; the pessimistic operator caps the choice below 5.0.0, so the newest overall release is not eligible.

Why B is wrong: This misreads ~> 4.9 as an exact pin; the operator actually allows the rightmost component to increase, so newer 4.x patch and minor releases remain acceptable.

Why C is wrong: Terraform selects the newest version that satisfies the constraint, not the lowest; the claim about a stability preference for the floor is not how version selection works.

Why D is correct: The pessimistic constraint ~> 4.9 allows increases in the last component, admitting 4.9 and above within the 4 major series, so the highest match is 4.12.3.

Free sampleTerraform fundamentalsmedium

What is the primary purpose of the dependency lock file that Terraform creates during initialisation?

  • AIt records the exact provider versions and hashes selected, so that later initialisations reuse the same versions across machines. Correct
  • BIt stores the current values of resource attributes so that later plans can detect drift against real infrastructure.
  • CIt caches the downloaded provider binaries so that future runs can initialise without contacting any registry.
  • DIt defines the acceptable version ranges for each provider so that constraints do not need to be repeated in configuration.
The dependency lock file records the exact selected provider versions and checksums so initialisations are reproducible across machines. During initialisation Terraform writes the resolved provider versions and their hashes into the lock file, which is committed to version control; subsequent runs honour those locked selections, giving consistent provider versions and verifiable integrity for the whole team.

Why A is correct: Correct: the lock file captures the chosen provider versions and their checksums and is committed to version control so every run and every collaborator resolves to identical provider selections.

Why B is wrong: Tempting because tracking real infrastructure is a genuine Terraform concern, but that is the job of the state file, not the dependency lock file.

Why C is wrong: Tempting because initialisation does cache plugins, but binaries live in the plugin cache directory while the lock file records selections and hashes rather than the binaries themselves.

Why D is wrong: Tempting because it concerns versions, but constraints are declared in required_providers; the lock file records the concrete resolved versions rather than the permitted ranges.

Free sampleTerraform fundamentalsmedium

How does Terraform use state to determine what a 'terraform plan' will change?

  • AIt compares the current configuration files against the previous configuration files stored in the version control history.
  • BIt queries the cloud provider for all objects in the account and rebuilds the entire plan from that live inventory alone.
  • CIt compares the desired configuration against the resources recorded in state and proposes actions to reconcile any differences. Correct
  • DIt replays the most recent apply log and repeats whatever actions that log contains.
A plan is the difference between the desired configuration and the resources recorded in state, expressed as reconciling actions. Terraform computes a plan by diffing the desired state described in configuration against what the state file records as currently provisioned, then lists the create, update, or destroy actions needed to make reality match the configuration.

Why A is wrong: Terraform does not read version control to plan; it diffs configuration against recorded state, so this substitutes the wrong baseline.

Why B is wrong: Terraform refreshes tracked resources but does not enumerate the whole account, and it still needs state to know which objects it manages, so a full inventory scan is not how a plan is formed.

Why C is correct: A plan is a diff between the configuration you want and what state records as current, and Terraform proposes create, update, or destroy actions to close that gap.

Why D is wrong: There is no apply-log replay mechanism; each plan is computed fresh from configuration and state, so this invents a process Terraform does not use.

Other domains in this exam

See also the TF-Associate-004 cert hub, the study guide, and the cheat sheet.

Examworthy is not affiliated with or endorsed by HashiCorp. Original, blueprint-aligned practice material only.