Update version constraints in your Terraform / OpenTofu configurations
Update version constraints in your Terraform / OpenTofu configurations
If you integrate tfupdate with your favorite CI or job scheduler, you can check the latest release daily and create a Pull Request automatically.
It is a best practice to break your Terraform configuration and state into small pieces to minimize the impact of an accident. It is also recommended to lock versions of Terraform core, providers and modules to avoid unexpected breaking changes. If you decide to lock version constraints, you probably want to keep them up-to-date frequently to reduce the risk of version upgrade failures. It's easy to update a single directory, but what if they are scattered across multiple directories?
That is why I wrote a tool which parses Terraform configurations and updates all version constraints at once.
If you are a macOS user, you can install tfupdate via either Homebrew or MacPorts:
$ brew install minamijoyo/tfupdate/tfupdate
$ sudo port install tfupdate
Download the latest compiled binaries and put it anywhere in your executable path.
https://github.com/minamijoyo/tfupdate/releases
If you have Go 1.26+ development environment:
$ go install github.com/minamijoyo/tfupdate@latest
$ tfupdate --version
You can also run it with Docker:
$ docker run -it --rm minamijoyo/tfupdate --version
$ tfupdate --help
Usage: tfupdate [--version] [--help] []
Available commands are:
lock Update dependency lock files
module Update version constraints for module
opentofu Update version constraints for opentofu
provider Update version constraints for provider
release Get release version information
terraform Update version constraints for terraform
$ tfupdate terraform --help
Usage: tfupdate terraform [options]
Arguments
PATH A path of file or directory to update
Options:
-v --version A new version constraint (default: latest)
If the version is omitted, the latest version is automatically checked and set.
-r --recursive Check a directory recursively (default: false)
-i --ignore-path A regular expression for path to ignore
If you want to ignore multiple directories, set the flag multiple times.
If you have main.tf like the following:
$ cat main.tf
terraform {
required_version = "0.12.15"
}
Execute the following command:
$ tfupdate terraform -v 0.12.16 main.tf
$ cat main.tf
terraform {
required_version = "0.12.16"
}
The version flag accepts any string literal. You can also pass a version constraint:
$ tfupdate terraform -v "~> 1.0" main.tf
$ cat main.tf
terraform {
required_version = "~> 1.0"
}
If you want to update all your Terraform configurations under the current directory recursively,
use -r (--recursive) option:
$ tfupdate terraform -v 0.12.16 -r ./
You can also ignore some path patterns with -i (--ignore-path) option:
$ tfupdate terraform -v 0.12.16 -i modules/ -r ./
If the version is omitted, the latest version is automatically checked and set.
$ tfupdate terraform -r ./
$ tfupdate opentofu --help
Usage: tfupdate opentofu [options]
Arguments
PATH A path of file or directory to update
Options:
-v --version A new version constraint (default: latest)
If the version is omitted, the latest version is automatically checked and set.
-r --recursive Check a directory recursively (default: false)
-i --ignore-path A regular expression for path to ignore
If you want to ignore multiple directories, set the flag multiple times.
If you have main.tf like the following:
$ cat main.tf
terraform {
required_version = "1.8.0"
}
Execute the following command:
$ tfupdate opentofu -v 1.9.0 main.tf
$ cat main.tf
terraform {
required_version = "1.9.0"
}
…
$ cat main.tf
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "3.70.0"
}
}
}
$ tfupdate provider aws -v 3.74.0 main.tf
$ cat main.tf
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "3.74.0"
}
}
}
The version flag accepts any string literal. You can also pass a version constraint:
$ tfupdate provider aws -v "~> 3.0" main.tf
$ cat main.tf
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 3.0"
}
}
}
For updating the dependency lock file (.terraform.lock.hcl), use the tfupdate lock command.
…
$ cat main.tf
module "s3_bucket" {
source = "terraform-aws-modules/s3-bucket/aws"
version = "2.14.0"
bucket = "my-s3-bucket"
acl = "private"
versioning = {
enabled = true
}
}
$ tfupdate module -v 2.14.1 terraform-aws-modules/s3-bucket/aws main.tf
$ cat main.tf
module "s3_bucket" {
source = "terraform-aws-modules/s3-bucket/aws"
version = "2.14.1"
bucket = "my-s3-bucket"
acl = "private"
versioning = {
enabled = true
}
}
The version flag accepts any string literal. You can also pass a version constraint:
$ tfupdate module -v "~> 2.14.1" terraform-aws-modules/s3-bucket/aws main.tf
$ cat main.tf
module "s3_bucket" {
source = "terraform-aws-modules/s3-bucket/aws"
version = "~> 2.14.1"
bucket = "my-s3-bucket"
acl = "private"
versioning = {
enabled = true
}
}
$ tfupdate release --help
Usage: tfupdate release [options] [args]
This command has subcommands for release version information.
Subcommands:
latest Get the latest release version
list Get a list of release versions
…
$ tfupdate release latest terraform-providers/terraform-provider-aws
2.40.0
If you want to access private repositories on GitHub, export your access token to the GITHUB_TOKEN environment variable.
If you want to access public or private repositories on GitLab, export your access token with api permissions to the GITLAB_TOKEN environment variable. If you are using an instance that is not https://gitlab.com, set the correct base URL to the GITLAB_BASE_URL environment variable (defaults to https://gitlab.com/api/v4/).
If you want to use the public OpenTofu registry, set the TFREGISTRY_BASE_URL environment variable to https://registry.opentofu.org/.
…
$ tfupdate release list -n 5 hashicorp/terraform
0.12.17
0.12.18
0.12.19
0.12.20
0.12.21
The tfupdate lock command updates the dependency lock file (.terraform.lock.hcl). For more information on the dependency lock file, see the official Terraform documentation: https://developer.hashicorp.com/terraform/language/files/dependency-lock
…
If you want to use the public OpenTofu registry, set the TFREGISTRY_BASE_URL environment variable to https://registry.opentofu.org/.
$ export TFREGISTRY_BASE_URL=https://registry.opentofu.org/
Given the following configuration:
$ cat test-fixtures/lock/simple/main.tf
terraform {
required_providers {
null = {
source = "hashicorp/null"
version = "3.1.1"
}
}
}
As you know, you can generate the dependency lock file by the terraform providers lock command:
$ terraform -chdir=test-fixtures/lock/simple providers lock -platform=linux_amd64 -platform=darwin_amd64 -platform=darwin_arm64
…
When updating provider version, the lock file must also be updated:
$ tfupdate provider null -v 3.2.1 ./test-fixtures/lock/simple/
$ cat test-fixtures/lock/simple/main.tf
terraform {
required_providers {
null = {
source = "hashicorp/null"
version = "3.2.1"
}
}
}
You can update the lock file by the tfupdate lock command without Terraform CLI:
$ tfupdate lock --platform=linux_amd64 --platform=darwin_amd64 --platform=darwin_arm64 ./test-fixtures/lock/simple/
Note that unlike the terraform providers lock command, the --platform flag requires two hyphens.
…
The tfupdate lock command parses the required_providers block in your configuration, downloads provider packages and calculates hash values under the hood. The most important point is that it caches calculated hash values in memory, which gives us a huge performance advantage when updating multiple directories at once using the -r (--recursive) option.
To skip terraform init, we assume that all dependencies are pinned to a specific version in the required_providers block of the root module. Note that version constraint expressions or indirect dependencies via modules are not supported and ignored.
If the registry supports h1 hash values, as in the public OpenTofu Registry, omitting the platform will record hash values for all platforms without downloading binaries.
If you integrate tfupdate with your favorite CI or job scheduler, you can check the latest release daily and create a Pull Request automatically.
An example for tfupdate with CircleCI is available:
https://github.com/minamijoyo/tfupdate-circleci-example
You can also use a CircleCI orb:
https://github.com/masutaka/circleci-tfupdate-orb
If you find any security issues in this project, please refer to SECURITY.md.
MIT
No open issues yet, or sync has not completed.