Every Terraform project has external dependencies on code that does not exist within the project itself. These external dependencies rely on Terraform Providers and Modules that may exist outside the code base of the Terraform project. Terraform 0.14 and later uses the Dependency Lock File track its decision from one run to another on determining which dependencies are potentially compatible with the current configuration to select the appropriate dependency versions for use.
If you’ve been using Terraform, then you’ve undoubtedly noticed a file named .terraform.lock.hcl
get created when you run the terraform init
command. This file is the Terraform Lock File. Let’s dig into what this file is for!
Note: The dependency lock file (
.terraform.lock.hcl
) is a feature that relates to the use of Terraform 0.14 and later, as tracking dependency selections was added in version 0.14. Older versions did not track the dependency selections.
There are two dependency types that Terraform must determine version compatibility for:
- Terraform Providers – These are the plugins that extend Terraform with support for working with external systems, such as the
azurerm
provider for managing Microsoft Azure Resources. - Terraform Modules – These are reusable groups of Terraform code that can be consumed by multiple Terraform projects.
Determining External Dependency Version Compatibility
When Terraform runs it must determine which versions of dependencies are potentially compatible with the Terraform project code. Each of the dependency types (Providers and Modules) can be versioned and published separately from the Terraform project code that depends on them.
Within the Terraform project, version constraints can be configured for the Terraform project itself to determine which dependency versions are potentially compatible. The version constraints enable a range of acceptable versions of a dependency to be specified within the Terraform project code.
One Terraform determines and selects a specific compatible dependency version, then it stores this decision in the dependency lock file. Storing the decision in the dependency lock file enabled Terraform to use the same decision again in the future without being required to determine it again.
Currently, the Terraform only remembers the Terraform Provider dependency version chosen within the configuration lock file (.terraform.lock.hcl
). The version decision for remote Terraform Modules are not remembered via the dependency lock file at this time. As a result, when Terraform is determining the compatible version of modules, it will always select the newest available module version that matches the specified module version constraint.
Terraform Lock File
The Terraform Lock File is always named .terraform.lock.hcl
and is located at the current working directory where Terraform is run. This is because the lock file is created to track the compatible dependency versions for the entire Terraform Project, rather than having separate lock files for each individual module in the project. This working directory is also the “root” directory of the Terraform Project itself.
The Terraform Lock File is named .terraform.lock.hcl
with the .terraform
prefix in it that matches the name of the .terraform
directory. The .terraform
directory is a hidden directory which is used by Terraform to cache provider plugins and remove modules dependencies referenced by the Terraform project code.
When terraform init
command is run, it will automatically create the Terraform Lock File if it doesn’t exist. If the file already exists, then Terraform will update it with the latest dependency versions selected. It is recommended that the lock file be included in version control repositories with the rest of the Terraform (.tf
) files for the project.
One of the steps performed by the terraform init
command when it’s initializing the Terraform project is to install all of the Terraform Providers needed for the Terraform project code. It takes into account the defined version constraints and the version selection stored in the dependency lock file. If no version is stored in the lock file, then Terraform will select the newest available version that matches the version constraint defined, then update the lock file with this version selection.
When terraform init
does update the Dependency Lock File, it will output to the console that these changes were made. The following is what that output looks like:
Terraform has made some changes to the provider dependency selections recorded
in the .terraform.lock.hcl file. Review those changes and commit them to your
version control system if they represent changes you intended to make.
The syntax of the dependency lock file is not Terraform code, but it is the same low-level syntax of HashiCorp Configuration Language (HCL). Therefore the file has the .hcl
file extension for HCL rather than the file extension of .tf
for Terraform.
Terraform Dependency Version Upgrade
When the Dependency Lock File contains previously selected dependency versions for Provider plugins or modules, then Terraform will always use the versions recorded in the lock file. Re-running the terraform init
command will only go through the process of determining the compatible versions of dependencies for any new dependencies added to the project since the previous run.
If you check-in the Dependency Lock File (.terraform.lock.hcl
) into source control, this will cause the selected dependency versions to be used from the file.
If you need to force the selected dependency versions to be updated, the -upgrade
attribute flag can be added to the terraform init
command, as in the following command:
terraform init -upgrade
This -upgrade
option will tell Terraform to redetermine the dependency versions again, just like before. This will have the result in Terraform upgrading the project to the latest version of the dependencies. The version constraints will still be factored in when determining the latest compatible version of dependencies, just like when the Dependency Lock File was first created.
Happy Terraforming!