Terraform Associate 004 #3 Terraform Fundamentals: Version Constraints, the Lock File, and Provider Configuration

4 min read

This part of the exam covers “preparing” Terraform and its providers. In real work it is the kind of thing you configure once and forget, which is exactly why it gets shaky right before the exam — and how version constraint operators are interpreted and what the lock file does appear so often you could call them question factories. We revisit the installation from Basics #1 and the block syntax from Basics #2, this time from the exam’s angle.

Installation and version check #

Terraform is a single binary, so installation is simple. Boiled down to what the exam cares about: you install through an official distribution channel (a package manager or a binary download) and confirm with terraform version, and version management tools (the tfenv family) exist for when different projects require different Terraform versions. The weight of the questions falls not on installation itself but on the version pinning in the next section.

Version constraint operators: you must be able to read ~> #

This is the constraint syntax used in the terraform block and required_providers.

main.tf
terraform {
  required_version = ">= 1.12.0"

  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 6.0"
    }
  }
}
OperatorMeaningExample
= 6.2.0 (or 6.2.0)Exactly this versionOnly 6.2.0 allowed
>= 6.2At leastEverything from 6.2 onward
>= 6.2, < 7.0Combined rangeComma means AND
~> 6.2Only the rightmost component may increase6.2, 6.3, … 6.x allowed, 7.0 not
~> 6.2.0Only the rightmost component may increase6.2.0–6.2.x allowed, 6.3 not

The exam’s favorite is the pessimistic operator ~>. The core rule is that only the rightmost specified component is allowed to increase, and you need to distinguish that ~> 6.2 and ~> 6.2.0 permit different ranges. The practical intent — “block the breaking changes of a major upgrade but accept minor and patch releases” — is why this operator exists, and it is also why ~> 6.0 was used throughout Basics and Practice.

The lock file: constraint versus pin #

Separating the roles of the two version-related files is the second staple of this domain.

  • The version in required_providers: a declaration of the allowed range. Written by a human.
  • .terraform.lock.hcl: the record of the exact version and checksums init actually selected within that range. Generated by Terraform.

Even if the range is ~> 6.0, if the lock file records 6.4.1, everyone on the team and CI uses 6.4.1. That is why the lock file is a file that must be committed to version control (the distinction from Basics #5 — state is never committed, the lock file is — is exactly what gets tested). The command to move to the latest version within the constraint range is terraform init -upgrade, and that completes the set.

Provider configuration and alias #

The provider block holds connection settings such as credentials and region. Two exam points.

  1. The same provider with multiple configurations: register additional ones with alias, and select them on a resource with provider = aws.us_east_1. The setup in Practice #10, where us-east-1 was added because of the CloudFront certificate, is a real-world instance of exactly this question.
main.tf
provider "aws" {
  region = "ap-northeast-2"
}

provider "aws" {
  alias  = "us_east_1"
  region = "us-east-1"
}
  1. Never put credentials in code: any answer choice that hardcodes access keys in the provider block is always wrong. External injection — environment variables, the shared credentials file, IAM roles — is the correct direction.

The .terraform directory: what init creates #

For questions that ask “what appears after init,” keep this distinction ready.

ArtifactContentsCommitted?
.terraform/Downloaded provider plugins, module cache, backend settingsNot committed (.gitignore)
.terraform.lock.hclPinned provider versions and checksumsCommitted

The contrast is the basis for the answer: .terraform/ is a local cache that init can regenerate at any time, while the lock file is a shared record that protects the team’s reproducibility.

Recap #

What we covered in this post.

  • The heart of version constraints is ~>. It allows only the rightmost specified component to increase, and you must distinguish the ranges of ~> 6.2 and ~> 6.2.0
  • required_providers declares the allowed range; .terraform.lock.hcl pins the version actually selected. Commit the lock file, and update it with init -upgrade
  • Multiple configurations of the same provider use alias, selected on the resource with the provider argument
  • Answer choices that hardcode credentials are always wrong. External injection is the correct direction
  • The .terraform directory is a regenerable local cache and is not committed

In the next post (#4 Core Workflow), we move to the central domain of the exam: the init, plan, apply, destroy cycle, the options of each command, and enabling debug logging.

X