Exam objective 1.3 for the TF-003 exam focuses on installing and managing the Terraform CLI and its versions. This matters because if you install the wrong version of Terraform for your project, your code might fail or, worse, destroy infrastructure in an unpredictable way. Learning to control which version you use is like learning to pick the right key for a lock — a basic skill that prevents disasters.
Jump to a section
A simple way to picture Installing and Managing Terraform Versions
The Head Chef at a busy restaurant needs to manage recipe cards for every dish on the menu. Each dish, from a simple omelette to a complex soufflé, has its own specific recipe card. The head chef cannot just scribble a new recipe on a napkin every time a customer orders. They use a master binder of recipe cards, each versioned and dated. When a new menu is launched, the chef updates the binder with the correct recipe cards and archives the old ones. If a customer orders a dish from last year's special, the chef can pull the exact old card from the archive.
Now imagine a junior chef tries to use last year's recipe for a chocolate cake but the oven has been replaced with a different model. The temperature and timing instructions on the old card are wrong. The cake burns. This is exactly the problem that Terraform version management solves. Terraform providers and configurations change over time. A configuration written for one version might break with another. Professionals use version managers like tfenv or the built-in Terraform version constraints to ensure every team member uses the exact same Terraform version for a given project, just like the head chef ensures everyone uses the correct, current recipe card from the master binder.
Terraform is a tool that lets you define and provision infrastructure using code. Infrastructure is the physical or virtual hardware that runs your applications: servers, databases, networking, and so on. The Terraform CLI (Command Line Interface) is the program you run on your computer to apply that code. Just like any software, Terraform gets new features and bug fixes over time, which means new versions are released.
Why does version management matter so much? Terraform configurations are written in a language called HCL (HashiCorp Configuration Language). As Terraform evolves, the way HCL works can change. A feature you used in version 0.12 might be deprecated (removed or no longer recommended) in version 1.5. If you run a configuration written for 0.12 with the 1.5 binary, you might get errors or unexpected behaviour. Version management ensures you always use the correct Terraform version for each project.
There are two main ways to manage Terraform versions. The first is to download a specific binary manually from the HashiCorp website and place it somewhere on your system. This works but can become messy if you work on multiple projects requiring different versions. The second, more professional approach, is to use a version manager tool. The most popular one is tfenv, which works on macOS and Linux. tfenv allows you to install, switch, and manage multiple versions of Terraform on the same machine. You can set a default version for your whole system and a project-specific version using a .terraform-version file. When you run 'terraform' commands, tfenv automatically picks the correct version based on that file.
Another key concept is the required_version setting inside your Terraform configuration file (usually named 'versions.tf'). This is a block of code that tells Terraform which versions of the CLI are allowed to run this configuration. For example:
terraform { required_version = ">= 1.0.0, < 2.0.0" }
This constraint means the configuration can only be used with Terraform version 1.0.0 up to, but not including, 2.0.0. If a teammate tries to run it with version 0.15, Terraform will refuse and print an error message. This protects your infrastructure from being accidentally modified by an incompatible version.
Version management also applies to providers. A provider is a plugin that Terraform uses to interact with a cloud platform like AWS, Azure, or GCP. Each provider has its own versioning. You can set provider version constraints inside the same 'terraform' block, for example:
required_providers { aws = { source = "hashicorp/aws" version = "~> 4.0" } }
The tilde (~) with the greater-than sign means "allow any version in the 4.x range, but not 5.0 or higher". This ensures that you get minor updates and bug fixes without unexpectedly jumping to a breaking release.
The upgrade process also matters. When you want to move to a newer version of Terraform for a project, you typically run a command like 'terraform init -upgrade' to update the lock file that records which exact provider versions are being used. Then you run 'terraform plan' to check that no breaking changes have occurred. HashiCorp publishes upgrade guides for every major version bump, which detail specific changes you need to make to your code. Ignoring these guides is a common cause of production incidents.
Finally, Terraform stores a state file (terraform.tfstate) that maps your configuration to real-world infrastructure. The state file format can change between Terraform versions. If you upgrade Terraform without planning, you might end up with a state file that the new version cannot read, effectively locking you out of managing your own infrastructure. That is why version management is a critical skill for anyone using Terraform in a team or production environment.
Check current Terraform version
Run 'terraform --version' in your terminal to see what version is currently active. This tells you the starting point before any changes. It also shows installed provider versions.
Set version constraint in configuration
Add a 'required_version' line inside the 'terraform' block in your 'versions.tf' file. For example, 'terraform { required_version = ">= 1.0.0" }'. This documents the allowed versions and enforces them at runtime.
Install the target version using a version manager
Use tfenv (or similar) to install the specific Terraform version you need. Run 'tfenv install 1.5.0'. This downloads the binary and makes it available in your system. This step avoids downloading the wrong version from the web manually.
Create a .terraform-version file
In the root directory of your Terraform project, create a file named '.terraform-version' containing just the version number (e.g., "1.5.0"). This file is read by tfenv to automatically select the correct version when you navigate to that folder.
Update provider versions with init -upgrade
Run 'terraform init -upgrade' to update the .terraform.lock.hcl file with the latest provider versions that are compatible with your new Terraform version. This ensures your configuration uses up-to-date and compatible provider plugins.
Run terraform plan to validate
Run 'terraform plan' to see what changes Terraform would make. If the version upgrade introduced breaking changes, the plan will show modifications or errors. This is a safe way to test before applying.
Apply changes in a controlled window
If the plan shows expected changes (like updating deprecated resources), apply them during a maintenance window using 'terraform apply'. Always have a backup of your state file before applying, in case of unexpected issues.
Sarah is a cloud engineer at a mid-sized software company that builds and deploys a web application on Amazon Web Services (AWS). The team has three microservices, each managed in a separate Git repository with its own Terraform configuration. Sarah started the project using Terraform version 0.12 two years ago. Last month, the team decided to upgrade one of the services to Terraform 1.5 to use a new data source that only exists in the newer version. The other two services will stay on 0.12 for now because their configurations are stable and the team does not want to risk breaking them in a busy release period.
Here is what Sarah does step-by-step:
She installs tfenv on her laptop using Homebrew (a package manager for macOS). She runs 'tfenv install 0.12.31' and 'tfenv install 1.5.0' so both binaries are available.
She navigates to the directory of the service that needs upgrading. She creates a file named '.terraform-version' containing exactly "1.5.0". Now whenever Sarah or any teammate runs a Terraform command in that directory, tfenv automatically uses Terraform 1.5.0.
She also updates the 'required_version' in the 'versions.tf' file to ">= 1.5.0, < 2.0.0" to ensure that no one accidentally runs it with an older version if they do not have tfenv configured.
She runs 'terraform init -upgrade' to download the latest provider plugins compatible with Terraform 1.5.
She runs 'terraform plan' and sees that the plan shows 'no changes'. This is a good sign that the upgrade was safe, at least for the current state.
She checks the HashiCorp upgrade guide from 0.12 to 1.5 and manually modifies a few deprecated attributes in the configuration, such as changing 'aws_instance' to use the newer 'aws_instance_v2' resource syntax. She runs 'terraform plan' again, and this time it shows the planned changes to update those resources.
After code review, she applies the changes during a maintenance window. The infrastructure is updated successfully.
Sarah also sets a system-wide default version so new projects default to the latest stable Terraform. She runs 'tfenv use 1.5.0' to set the default globally. For the two services staying on 0.12, she simply creates a .terraform-version file with "0.12.31" in those directories. This setup allows her team to work on all three services without ever running the wrong command.
When a new developer joins, they only need to install tfenv and run 'tfenv install' (which reads the .terraform-version file) to get the correct binary. This saves hours of debugging and avoids accidental infrastructure destruction caused by version mismatches.
The TF-003 exam tests objective 1.3 in several specific ways. You need to know the difference between the required_version setting and provider version constraints. The exam will likely present a scenario where a configuration has a required_version constraint, and you must identify what happens when a user runs it with an incompatible binary. The answer is always: Terraform will print an error and refuse to proceed. It will not attempt to run or partially apply the configuration.
Key concepts they love to test:
The syntax for required_version: 'terraform { required_version = ">= 1.0.0" }'. You must know it goes inside the 'terraform' block, not the 'provider' block.
Provider version constraints: They use the same 'required_providers' nested block inside 'terraform'. You must recognise the tilde operator '~>' which means "pessimistic version constraint". For example, '~> 2.0' means '>= 2.0, < 3.0'.
Version managers: You should know that tfenv is a common tool, but the exam might ask about the general concept of version management. The correct answer is that it allows you to install and switch between multiple versions on the same system.
The .terraform-version file: You need to know that it is a simple text file containing just the version number, and it is used by tools like tfenv to automatically select the correct version.
The upgrade workflow: Questions may ask about the order of operations when upgrading. The correct sequence is: 1) Update required_version, 2) Run 'terraform init -upgrade', 3) Run 'terraform plan' to check for deprecations, 4) Apply changes if needed.
Common trap patterns:
The exam might show a required_version that uses '>= 1.0, < 1.5' and ask if a user running 1.6 would succeed. The answer is no, because the constraint excludes 1.6.
They might present a scenario where the user forgot to update the required_version after upgrading, and ask what will happen if they run 'terraform apply'. The answer is that Terraform will run successfully (since the binary is compatible), but team members with older versions might break later. The exam expects you to flag the missing constraint as a risk.
They sometimes show provider version constraints that conflict. For example, one module requires 'aws >= 3.0' and another requires 'aws < 3.5'. You need to identify that the version range is the intersection: 3.0 to 3.4 inclusive.
Memorise these definitions exactly:
Terraform CLI version: The version of the terraform binary.
Provider version: The version of the plugin that interfaces with a specific cloud provider.
Version constraint: A string like '>= 1.0.0' that specifies acceptable versions.
Terraform Registry: Where providers and modules are published with version metadata.
Exam questions on this topic are usually straightforward if you have practised the commands and know the constraint syntax. Do not overthink them — the answer is often the simplest option that matches the rules described above.
The required_version setting inside the terraform block tells Terraform which CLI versions are allowed to run your configuration, and Terraform will refuse to operate if the version does not match.
Provider version constraints use the 'required_providers' block and the tilde operator (~>) to specify a range of acceptable versions, preventing unexpected upgrades.
The .terraform-version file is read by tools like tfenv to automatically select the correct Terraform version for a project, but it is not a native Terraform feature.
When upgrading Terraform, always run 'terraform init -upgrade' to update provider lock files, then run 'terraform plan' to detect any breaking changes before applying.
Version management prevents state file corruption, which can occur if the state file format changes between Terraform versions.
Always check HashiCorp's official upgrade guides when moving between major Terraform versions, as they detail specific code changes required.
Multiple Terraform versions can coexist on the same machine using a version manager like tfenv, allowing work on projects with different requirements.
A version constraint like '>= 1.0.0, < 2.0.0' means any version from 1.0.0 up to but not including 2.0.0 is acceptable.
These come up on the exam all the time. Here's how to tell them apart.
required_version (CLI)
Controls which Terraform binary can run the configuration
Set inside the terraform block using 'required_version'
Uses simple comparison operators like >=, <, ~>, etc.
provider version constraint
Controls which version of a provider plugin is used
Set inside the required_providers block within terraform
Also uses comparison operators but applied to specific providers
tfenv (version manager)
Allows switching between versions per project
Automatically selects version based on .terraform-version file
Simplifies team collaboration by ensuring everyone uses the same version
Manual binary download
Downloading from releases page puts one binary in your PATH
Requires manual effort to swap versions or maintain symlinks
Can lead to version conflicts across projects on the same machine
terraform init
Downloads provider plugins based on existing lock file
Safe to run when no version changes have occurred
Will not update to newer provider versions unless lock is missing
terraform init -upgrade
Updates the lock file to the latest acceptable provider versions
Useful after upgrading Terraform CLI or changing constraints
Should be followed by reviewing the plan for breaking changes
Version constraint >= 1.0.0
Allows any version from 1.0.0 upward (1.0, 1.1, 2.0, etc.)
Broadest possible range, including major upgrades
Risky for production because 2.0 may break configuration
Version constraint ~> 1.0
Allows any version from 1.0 to less than 2.0 (only patch and minor)
More restrictive, prevents major version jumps
Safer for production as it avoids breaking changes
Mistake
You only need to worry about Terraform version management when you are upgrading to a completely new major version like from 0.12 to 1.0.
Correct
Minor and patch version changes can also introduce breaking changes or behavioural differences, especially for providers. Always specify version constraints for both Terraform CLI and providers.
Beginners often assume that only major version bumps (like 1.0 to 2.0) matter, but in practice, provider versions frequently change even in minor releases.
Mistake
If you have multiple Terraform versions installed, you can just rename the terraform binary to switch between them.
Correct
Renaming the binary is error-prone and unsupported. The correct approach is to use a version manager like tfenv or to create symlinks, but the most reliable method is to always use the exact binary path or a version file.
Beginners who come from a background of simply downloading software often try manual file management, not realising that Terraform expects a specific binary name and path to work correctly.
Mistake
Setting required_version in your configuration prevents anyone from running a wrong version on their local machine.
Correct
Required_version is a safety check that prints an error, but it does not automatically switch versions. It only validates at runtime. The user must still have the correct version installed.
This distinction is subtle: people think the software will magically download the correct version, but it only checks what is already there.
Mistake
The .terraform-version file is a Terraform feature built into the CLI.
Correct
The .terraform-version file is a convention used by third-party version managers like tfenv. Terraform itself does not read this file. It is not part of the official Terraform tooling.
The name and behaviour look similar to other tools like Node's .nvmrc, so beginners mistakenly believe Terraform natively supports it.
Mistake
Provider version constraints and Terraform CLI version constraints are interchangeable and can be used in the same block.
Correct
They use different syntax and are placed inside the same 'terraform' block but under different keys. required_version controls the CLI binary, while required_providers controls provider plugins.
Both concepts involve version constraints, which leads to confusion about where each belongs and what each actually affects.
Reveal each answer, then mark whether you got it right. Score 60%+ to unlock the next chapter.
Use a version manager like tfenv (on macOS/Linux) or tfswitch (also cross-platform). Run 'tfenv install 1.0.1' to download and make that version available. Alternatively, download the exact binary from the HashiCorp releases page on GitHub.
If the configuration includes a required_version constraint, Terraform will refuse to run and show an error message stating the version mismatch. If there is no constraint, it will attempt to run, which may cause failures or unexpected behaviour due to deprecated features.
No. The .terraform-version file is a convention used by tools like tfenv to select the right binary. The version constraint in the code (required_version) is a Terraform feature that validates which binary can run the configuration. They work together but are separate.
Yes. Version managers like tfenv allow you to install multiple versions side by side. You can switch between them globally or per-project using the .terraform-version file. This is common when you work on different projects that require different Terraform versions.
Yes. After upgrading the binary you use, update the required_version in your configuration to match the new range. This ensures that everyone on the team uses the same version and that CI/CD pipelines enforce consistency.
Upgrading Terraform may change how it interprets your configuration. Deprecated attributes or resources can be replaced with new ones. Also, the new version may reorder or rename resources in the state file. Always review the plan carefully before applying.
You've finished Installing and Managing Terraform Versions. Continue through the TF-003 study guide to build a complete picture of the exam.
Done with this chapter?