Terraform Provider Interview Questions

Reviewed by Mark Dickie · Last updated

10 questions on this page you can answer and see marked on the spot. Go to the first one

Terraform providers are plugins that let Terraform communicate with cloud platforms, SaaS services, and other APIs by exposing resources and data sources for those systems to manage. A provider acts as the bridge between Terraform's declarative configuration and the real API it talks to. For interview purposes, you need to know how providers are declared in a required_providers block, how the source address string maps to a registry namespace, and what happens when a provider is initialized with terraform init. You should also understand the difference between resource and data source blocks, how provider configuration blocks supply credentials and region settings, and how provider version constraints work.

How do you declare a provider in a Terraform configuration?

You declare a provider in two parts. First, the required_providers block inside the terraform block registers the provider source and optional version constraint. Second, a provider block (e.g. provider "aws") supplies configuration arguments like region or credentials.

terraform {
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 5.0"
    }
  }
}

provider "aws" {
  region = "us-east-1"
}

What does the provider source address mean?

The source string follows the format namespace/name. For official HashiCorp providers the namespace is hashicorp, so hashicorp/aws points to the AWS provider on the Terraform Registry. Community providers use a different namespace (e.g. hashicorp-education/aws). The full address is registry.terraform.io/hashicorp/aws, but the registry hostname is implied and usually omitted.

ConceptWhat it doesExample
required_providers blockRegisters a provider and pins a versionaws = { source = "hashicorp/aws", version = "~> 5.0" }
provider blockConfigures credentials, region, endpointsprovider "aws" { region = "us-east-1" }
terraform initDownloads the provider plugin to .terraform/Run once after adding or changing a provider
Version constraintLimits which provider versions are accepted~> 5.0 allows 5.x but not 6.0

What should you know about provider versioning?

  1. Version constraints use operators like ~> (pessimistic), >=, <=, and = to control which releases Terraform will install.
  2. ~> 5.0 means any 5.x release but blocks 6.0; ~> 5.1 is tighter and allows 5.1.x but not 5.2.0.
  3. If you omit the version constraint, Terraform downloads the latest version at init time, which can introduce breaking changes without warning.
  4. Running terraform init -upgrade replaces the locked version in .terraform.lock.hcl with the newest available release matching the constraint.
  5. The lock file should be committed to version control so every teammate and CI run uses the same provider versions.

Use the quiz below to test your understanding of provider declaration, source addressing, initialization, and version constraints before your interview.

Key facts

  • Tarmac has 36 Terraform interview questions on this topic, 25 of them on this page, at difficulty 1–5 of 5.
  • Tarmac tracked 1,687 job postings asking for Terraform in September 2026.
  • Roles asking for Terraform advertise a median base salary of £80,000, across 613 job postings as of September 2026.
  • Tarmac last reviewed these Terraform interview questions on 13 October 2026.

At a glance

Questions25 shown · 36 in the bank
Difficulty1–5 of 5
FormatsTrue / false, Fill in the blank, Short answer, Multiple choice, Flashcard, Multiple answer, Ordering

What you'll review

  1. providers

Practice questions

Try one before you open the answer. Pick an option and press Check; it's marked on the spot.

True or false: Terraform core can create and manage real infrastructure on a target platform (such as a cloud or SaaS API) without any provider plugin installed.#

Options

Show answer

False. Terraform core cannot create or manage cloud or SaaS infrastructure by itself. It only parses configuration, builds the dependency graph, and manages state, while each resource type is implemented by a provider plugin that calls the platform's API. A provider must be installed and initialized with terraform init.

Why:

False. Terraform core only handles the configuration language, builds the dependency graph, and manages state. Every resource type and data source is implemented by a provider plugin, which contains the logic to call the target platform's API. Without a provider that implements the needed resource types, Terraform has no way to create, read, update, or delete that infrastructure, so a provider must be installed and initialized with terraform init.

The command you run first in a new or freshly-cloned configuration to initialize the working directory and download providers is terraform _____.#

Show answer

The command you run first in a new or freshly-cloned configuration to initialize the working directory and download providers is terraform **init**.

Why:

terraform init initializes the working directory: it downloads the required provider plugins and modules and configures the backend, writing the .terraform directory and the dependency lock file. It must run before plan or apply, and it's safe to re-run when you add a provider, change a module source, or reconfigure the backend.

In Terraform, a provider is a _____ that encapsulates the API logic for creating, reading, updating, and deleting resources on a specific cloud or SaaS service.#

Show answer

In Terraform, a provider is a plugin that encapsulates the API logic for creating, reading, updating, and deleting resources on a specific cloud or SaaS service.

Why:

A Terraform provider is a plugin: a separate binary that implements the gRPC interface Terraform uses. It maps each resource type and data source to the underlying service's API, which is how Terraform creates, reads, updates, and deletes those resources declaratively. Providers are released by HashiCorp or the community and are declared in the required_providers block.

In a Terraform configuration, the required_providers block — where you declare which providers your configuration depends on along with their source addresses and version constraints — must be nested inside the _____ meta-block.#

Show answer

In a Terraform configuration, the required_providers block — where you declare which providers your configuration depends on along with their source addresses and version constraints — must be nested inside the **terraform** meta-block.

Why:

The required_providers block is a child of the terraform meta-block, which also holds settings like required_version and backend configuration. Placing required_providers at the top level of a module, outside the terraform block, would produce a validation error.

Which Terraform CLI command downloads and installs the provider plugins declared in your Terraform configuration?#

Show answer

terraform init

Why:

terraform init initializes a working directory by downloading and installing the provider plugins listed in required_providers, configuring the backend, and preparing the directory for other commands such as plan and apply. The question asks for the single command that performs provider installation, which is terraform init.

What does terraform init do with providers?#

Show answer

terraform init reads the required_providers block and each provider's version constraints, then selects a version that satisfies them. It downloads and installs those provider plugins into the working directory's .terraform/ folder so that later commands like plan and apply can use them. Providers are fetched from the Terraform Registry by default, or from a network or filesystem mirror if one is configured in the CLI configuration. It also creates or updates .terraform.lock.hcl, which records the selected versions and their checksums so that later runs use the same provider builds.

Why:

terraform init is an open question about behaviour, so it stays a short answer graded against a reference. The core behaviour is that init reads the required_providers declarations and version constraints, picks matching versions, and installs the provider plugins into the .terraform/ directory so that plan and apply can use them. Providers come from the Terraform Registry by default or from a mirror set in the CLI configuration, not from a local path in the provider source address. Init also writes .terraform.lock.hcl to pin the selected versions and checksums for reproducible runs.

What is the purpose of the required_providers block in a Terraform configuration? Name the parts each entry declares and what Terraform does with them during terraform init.#

Show answer

The required_providers block, declared inside the terraform meta-block, specifies which provider plugins the configuration depends on. Each entry includes a local name, a source address (e.g., hashicorp/aws), and an optional version constraint. This tells Terraform which providers to download during terraform init and which versions are acceptable.

Why:

The required_providers block lives inside the terraform block and declares, for each provider, a local name, a source address, and an optional version constraint. During terraform init, Terraform uses these entries to download the matching provider plugins and to reject versions that fall outside the constraint, which makes runs reproducible across environments. Without the block, Terraform can fall back to inferring a default provider, but declaring it explicitly pins the source address and version.

True or false: a single Terraform configuration can declare and use resources from multiple different providers (for example, AWS and GitHub) at the same time.#

Options

Show answer

A single Terraform configuration can use multiple providers at the same time. You declare each one in the required_providers block, such as hashicorp/aws and hashicorp/github, and Terraform plans and applies their resources together in one dependency graph.

Why:

This is true. A configuration can list several providers in the required_providers block and then declare resources from each of them. Each resource type is tied to its own provider plugin, and Terraform builds one dependency graph across all of them during plan and apply. For example, one configuration can provision AWS infrastructure and create GitHub repositories together.

True or false: after you change a provider's version constraint in the required_providers block, you must run terraform init again before terraform plan or terraform apply will use the new constraint.#

Options

Show answer

Running terraform init again is required after you change a provider's version constraint in required_providers. Plan and apply only use the provider plugins that init installed, so init must download or switch to a version matching the new constraint first.

Why:

The statement is true. terraform plan and terraform apply do not download or change provider plugins; they use the plugins that terraform init installed in the working directory. When the version constraint changes, init must run again so Terraform selects and installs a provider version that satisfies the new constraint. Re-running init is safe because it only changes what differs from the current configuration.

Which option correctly matches each Terraform concept to its description?#

Options

Show answer

The correct pairing is 1-b, 2-a, 3-c. A provider plugin bridges Terraform to a cloud or platform API, a resource block declares a single piece of infrastructure in configuration, and a state file records the mapping between your configuration and the real-world resources Terraform has provisioned.

Why:

A provider plugin bridges Terraform to a specific cloud or platform API, so concept 1 matches the description about bridging to an API (b). A resource block declares a single piece of infrastructure, such as a virtual machine or database, in configuration, so concept 2 matches the description about declaring one piece of infrastructure (a). A state file records the mapping between configuration and the real-world resources Terraform has provisioned, so concept 3 matches the description about that mapping (c). The only pairing that gets all three right is 1-b, 2-a, 3-c.

What is a provider in Terraform?#

Show answer

A provider is a plugin that lets Terraform manage a specific platform's API — AWS, Azure, GCP, Kubernetes, Cloudflare, and so on. It defines the resource types and data sources you can use and translates Terraform's create/read/update/delete operations into that platform's API calls. You declare which providers and versions you need in a required_providers block, and terraform init downloads them. Without a provider, Terraform has no resources to manage.

Why:

Providers are how Terraform stays platform-agnostic at its core while managing almost anything: each provider plugin supplies the resource/data-source schemas and does the API translation. Knowing that providers are versioned plugins downloaded at init explains why required_providers and the lock file matter for reproducible runs.

A provider source address in Terraform follows the format [hostname]/[namespace]/[name]. In a required_providers block you can write just hashicorp/aws. Terraform implicitly prepends the default public registry hostname, so the full resolved source address is _____/hashicorp/aws.#

Show answer

A provider source address in Terraform follows the format [hostname]/[namespace]/[name]. In a required_providers block you can write just hashicorp/aws. Terraform implicitly prepends the default public registry hostname, so the full resolved source address is registry.terraform.io/hashicorp/aws.

Why:

When a required_providers entry omits the hostname, Terraform assumes the default public registry at registry.terraform.io, resolving hashicorp/aws to the full address registry.terraform.io/hashicorp/aws.

True or false: in Terraform, the alias meta-argument in a provider block creates an additional named configuration of the same provider type, and a resource selects that configuration by passing a provider argument in the form <provider_type>.<alias> (for example, provider = aws.west).#

Options

Show answer

The statement is true: the alias meta-argument in a Terraform provider block defines an additional named configuration of the same provider type. A resource selects it with a reference such as provider = aws.west, while resources without a provider argument use the unaliased default configuration.

Why:

The statement is true. The alias meta-argument lets you declare multiple configurations of one provider type, such as a default unaliased aws provider for us-east-1 and a second aws provider aliased as west for us-west-2. A resource targets the alternate configuration with provider = aws.west. Without an alias, a provider type has exactly one default (un-aliased) configuration, which resources use when they specify no provider argument.

Complete the Terraform snippet by filling in the blank so that the aws provider is fetched from the hashicorp/aws registry address. Write only the argument name in place of _____.#

Show answer

Complete the Terraform snippet by filling in the blank so that the aws provider is fetched from the hashicorp/aws registry address. Write only the argument name in place of source.

terraform {
  required_providers {
    aws = {
      **source** = "hashicorp/aws"
      version = "~> 5.0"
    }
  }
}
Why:

Inside a required_providers entry, the source argument gives the provider's address in the form namespace/name (here hashicorp/aws), which Terraform uses to locate and download the plugin from the registry during terraform init. The version argument in the same block only constrains which released versions are acceptable; it does not say where the plugin comes from, so the blank must be source.

In a Terraform 1.x configuration you need to manage resources across two AWS regions simultaneously. Which set of configuration blocks correctly defines an aliased provider for the second region and assigns an S3 bucket resource to it?#

Options

Show answer

Option B

Why:

In Terraform, the provider meta-argument on a resource expects an unquoted reference to a provider configuration — aws.west — not a string literal like "aws.west" (Option A is wrong). There is no alias argument valid inside a resource block; the alias is declared only in the provider block and referenced via the dot syntax (Option C is wrong). The provider block's type label must be a bare type name without a dot; you cannot write provider "aws.west" (Option D is wrong). Option B correctly defines alias = "west" in the provider block and references it as provider = aws.west in the resource block.

In a Terraform root module you define an aliased provider configuration, provider "aws" { alias = "west" ... }, and you call a child module whose resources use the default (non-aliased) aws provider. Terraform does not pass aws.west into the child automatically. Explain what you add in the root module to make the child's resources use aws.west, and why redefining a provider block inside the child module is not the same thing.#

Show answer

In the module block in the root module, add a providers meta-argument that maps the child module's provider name to the root's aliased configuration, for example providers = { aws = aws.west }. Terraform only passes the default (non-aliased) provider configuration to child modules implicitly, so an aliased configuration must be passed explicitly this way. Declaring a new provider "aws" block inside the child module would create a separate configuration with its own settings and credentials, not reuse the root's aws.west configuration.

Why:

Terraform implicitly inherits only the default provider configuration into child modules; aliased configurations are never inherited automatically. The fix is the providers meta-argument on the module block, which maps the provider name the child expects (here the default aws) to the parent's aliased configuration aws.west. A provider block written inside the child module is a new, independent configuration with its own arguments, so it does not reuse the parent's aws.west settings. The parent's alias is only usable inside the child when it is explicitly handed over through providers.

In a Terraform required_providers block, the source attribute is set to hashicorp/aws while the local name (the map key) is aws. Explain the distinct role each value plays in provider resolution and why Terraform requires both.#

Show answer

The source attribute (hashicorp/aws) is the fully-qualified provider address on the Terraform Registry. It combines a namespace (hashicorp) and a provider type (aws) and tells Terraform exactly which plugin to download and from where. The local name (the map key aws) is a module-scoped shorthand used to bind provider blocks, resource blocks, and data sources to that provider within the module's configuration. Both are needed because the local name is only meaningful inside the module and can be chosen freely or differ from the provider type, while the source is the global, unique identifier that resolves to a specific downloadable provider artifact.

Why:

The source attribute is the registry address (namespace plus type) that determines which plugin Terraform downloads, while the local name is a module-internal shorthand for referencing that provider in configuration blocks such as provider and resource blocks. Both are required because the local name is scoped to the module and can be freely chosen, whereas the source is the global, unique identifier needed to locate the correct provider artifact.

When a Terraform module needs multiple configurations of the same provider (for example, the AWS provider pointed at two different regions), each provider block must include an _____ argument to give that configuration a distinct name. A resource then selects which configuration to use by setting the _____ meta-argument to the value <provider_local_name>.<alias_value>.#

Show answer

When a Terraform module needs multiple configurations of the same provider (for example, the AWS provider pointed at two different regions), each provider block must include an alias argument to give that configuration a distinct name. A resource then selects which configuration to use by setting the provider meta-argument to the value <provider_local_name>.<alias_value>.

Why:

Terraform allows several configurations of one provider by giving each provider block an alias argument, which pairs with the default configuration (which has no alias). A resource chooses a non-default configuration by setting the provider meta-argument to <provider_local_name>.<alias_value>, for example aws.west. Both names are fixed by Terraform's configuration language, so alias and provider are the only correct fills.

Given the Terraform configuration below, which provider configuration does Terraform use for the aws_s3_bucket.example resource, which has no provider meta-argument?#

Options

Show answer

Terraform uses the default, un-aliased provider configuration for any resource that omits the provider meta-argument. In this setup, that is the aws provider block with no alias, which sets region us-east-1. Aliased blocks are used only when a resource explicitly references them, and block order in the file does not matter.

Why:

Terraform uses the default (non-aliased) provider configuration for any resource that omits the provider meta-argument. Here, the aws provider block with no alias (region us-east-1) is that default. The block with alias = "west" is an additional named configuration that applies only when a resource sets provider = aws.west. Declaring one un-aliased and one aliased block is valid, so no error occurs. Block order in the file has no effect on which configuration is selected.

A Terraform configuration defines providers in a required_providers block with version constraints (e.g., ~> 4.0). An existing .terraform.lock.hcl file is present in the working directory. Which of the following statements about provider resolution and the lock file are true?#

Options

Pick every one that applies.

Show answer

The true statements are: terraform init without -upgrade respects the locked provider version even when a newer satisfying version exists; terraform init -upgrade overwrites the lock file with the newest version satisfying each constraint; and deleting the lock file and re-running init regenerates it with the latest satisfying version. The lock file records checksums only for the current platform by default—not all platforms—and it does not lock module versions.

Why:

The .terraform.lock.hcl file pins the exact provider version and checksums so that every team member who runs terraform init gets identical provider artifacts. Without -upgrade, init respects the locked version even if a newer satisfying version exists (the statement that terraform init (without -upgrade) installs the provider version recorded in the lock file even if a newer version satisfying the constraint is available is true). With -upgrade, init ignores the existing lock, selects the newest available version satisfying each constraint, and rewrites the lock file (the statement that terraform init -upgrade updates .terraform.lock.hcl to record the newest available provider version that satisfies each required_providers version constraint is true). If the lock file is deleted, init starts fresh and picks the newest satisfying version, writing a new lock file (the statement that deleting .terraform.lock.hcl and running terraform init regenerates the file, selecting the newest available version satisfying each required_providers constraint is true). The claim that terraform init records provider checksums in .terraform.lock.hcl for all supported platforms is false: terraform init only records checksums for the current platform's archive; to include additional platforms you must run terraform providers lock -platform=.... The claim that .terraform.lock.hcl also locks module versions referenced via source references in the configuration is false: .terraform.lock.hcl covers provider plugins only—module versions are pinned in the configuration itself (e.g., a Git tag or registry version in the module block), not in the lock file.

In Terraform 1.x, consider this configuration:#

Show answer

Terraform only selects a provider configuration automatically when it is the default one, meaning a provider block without an alias argument. Both aws blocks here carry aliases (east and west), so neither is a default, and Terraform never picks an aliased configuration implicitly, since the choice would be arbitrary. To make the association explicit, either add a non-aliased provider "aws" block so it becomes the default, or set the meta-argument provider = aws.east (or aws.west) inside the aws_s3_bucket resource block.

Why:

A provider block without an alias argument defines the default configuration for its provider type, and a resource that omits the provider meta-argument uses that default. Aliased configurations are never selected implicitly, because Terraform has no basis for choosing one among several. In this configuration both aws blocks have aliases, so the resource has no unambiguous configuration. The fix is either to add a non-aliased aws provider block, which becomes the default, or to add an explicit provider meta-argument such as provider = aws.east to the resource.

A Terraform 1.x module declares the following required_providers block:#

Show answer

Terraform resolves the source hashicorp/aws to the fully-qualified address registry.terraform.io/hashicorp/aws by prepending the default registry hostname. That full address identifies which provider plugin is downloaded and checksum-verified during terraform init. The local name aws is only the map key in the module's required_providers block: it is a module-scoped label used in provider configuration blocks and in the provider meta-argument on resources. Changing the local name would not change which binary is fetched; the source controls that.

Why:

The source argument gives the provider's global address. Terraform prepends the default registry hostname registry.terraform.io to hashicorp/aws, producing registry.terraform.io/hashicorp/aws, and that address determines which plugin binary is downloaded and verified during terraform init. The local name aws is the key in required_providers; it is a module-scoped label used to reference the provider in provider configuration blocks and in provider meta-arguments on resources. Renaming the local name would not change which binary is fetched, only the identifier used within the module.

A Terraform configuration declares one new managed resource that uses a provider plugin which has been installed but has not yet been launched in this run. Place the following provider plugin gRPC calls in the order Terraform invokes them during a single terraform apply run, including the plan phase that apply performs internally.#

Put these in order

Show answer

In a single terraform apply for a new resource, Terraform calls GetProviderSchema first, then ConfigureProvider, then PlanResourceChange, and finally ApplyResourceChange. The schema is needed before the provider can be configured, configuration must be set before planning, and the planned change is what gets applied.

Why:

Terraform first calls GetProviderSchema to learn which resource types, data sources, and schemas the freshly launched provider exposes, since it cannot validate or plan anything without them. It then calls ConfigureProvider to pass the provider block's values (credentials, region, endpoints) so the plugin can make API calls. Next, the internal plan phase of apply calls PlanResourceChange for the new resource to compute the proposed new state and resolve unknown values. Only after the plan is produced and the change is confirmed does Terraform call ApplyResourceChange, which performs the actual create operation through the provider's API and returns the final state. Each call depends on the one before it, so the order is fixed.

Under the Terraform provider plugin protocol (tfplugin5, as used by Terraform 1.x), the UpgradeResourceState RPC is invoked by Terraform Core for a managed resource instance during plan/apply when which condition is true?#

Options

Show answer

Terraform Core calls the provider's UpgradeResourceState RPC only when the schema version number stored in a resource instance's state is lower than the version the provider reports for that resource type in its GetProviderSchema response. It is a version-driven state-migration mechanism, not triggered by field-level mismatch, provider address changes, or drift detection. When the versions already match, the call is skipped.

Why:

Terraform Core compares the integer schema version stored in each resource instance's state against the version the provider advertises for that resource type in its GetProviderSchema response. When the stored version is lower, Core calls UpgradeResourceState, passing the stored version, and the provider walks its registered state-upgrader functions from that version forward to the current one, returning the migrated state. This is a strictly version-number-driven migration mechanism — it has nothing to do with field-level conformance, the provider source address in state, or drift detected by ReadResource. If the stored version already equals the current version, the RPC is skipped entirely; if it is higher than what the provider supports, Terraform reports an error.

In a Terraform configuration, the root module defines two AWS provider configurations: a default provider "aws" and an aliased provider "aws" { alias = "west" }. A child module declares configuration_aliases = [aws.west] in its required_providers block. The root module's module block passes both configurations through its providers map (providers = { aws = aws, aws.west = aws.west }), and a resource inside the child module uses provider = aws.west. If the configuration_aliases entry is removed from the child module's required_providers block, and everything else stays the same, what is the result? Explain what Terraform does and why.#

Show answer

Terraform reports a configuration error and stops before planning or applying changes. The root module's providers map passes aws.west, but the child module no longer declares that alias in configuration_aliases, so the child has no declared provider configuration under that name to receive. The resource's provider = aws.west reference is also unresolvable inside the child. Terraform does not silently fall back to the default aws provider.

Why:

A child module can only receive an aliased provider configuration if it declares that alias in configuration_aliases within required_providers. The root's providers map entry for aws.west has no matching declaration in the child, so Terraform raises a configuration error (it does not fall back to the default aws provider) and halts before planning. The child's provider = aws.west reference would also fail, since no provider configuration with that alias is known in the child's scope.

Related interview questions

Job market

See terraform salaries and hiring demand from live job postings.

The other 11 questions

This page shows 25 and marks what you pick. That's as far as a page can go. A free account opens the other 11 and keeps every answer. What you miss comes back until it's right: after a day, then at longer gaps.

Start with this topic

Free · the whole bank · 100 marked answers per 30 days · written feedback on the paid plan

Interview booked? Practise the job ad instead

What moved, monthly

One email a month when the bulletin comes out: what moved in the markets we track, and the new question topics we published. Confirm your address to join. Unsubscribe any time.