tfupdate rewrites Terraform and OpenTofu version constraints in place
Update version constraints in your Terraform / OpenTofu configurations
At a glance
- What is it?
- minamijoyo/tfupdate is a Go command line tool that parses Terraform and OpenTofu configurations and rewrites the required_version and provider version constraints, including in .terraform.lock.hcl files, without invoking the Terraform CLI. It targets the routine chore of bumping pinned versions across many directories.
- Who is it for?
- Adopt tfupdate when you pin Terraform core, provider and module versions across many directories and want a repeatable command, or a CI job that opens a pull request with the bump. Do not adopt it for the latest-version lookup alone, since that needs network access to GitHub, GitLab or the Terraform and OpenTofu registries, and the module subcommand explicitly does not support automatic latest version resolution.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 100 days ago.
- What is it written in?
- Mainly Go, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.
Editorial analysis
The tool exists because pinned versions drift across scattered directories
The README explains the motivation in a short argument. It is a best practice to break Terraform configuration and state into small pieces to limit the damage of an accident, and it is also recommended to lock versions of Terraform core, providers and modules to avoid unexpected breaking changes. Locking is only safe if you keep the locks current, and the README is blunt about the difficulty: it is easy to update a single directory, but what if they are scattered across multiple directories. That is the problem tfupdate was written to solve, by parsing Terraform configurations and updating all version constraints at once. The framing matters for adoption. This is not a Terraform alternative and it does not plan or apply anything. It is a text editing tool for one specific field in one specific file format, aimed squarely at the chore of keeping a pin fresh across a large repository.
Six subcommands cover core, providers, modules and lock files
The command surface is the fastest way to understand the scope.
$ tfupdate --help
Usage: tfupdate [--version] [--help] <command> [<args>]
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 terraformSo there is a separate subcommand for Terraform core and one for OpenTofu core, one for providers, one for modules, one for dependency lock files, and a release subcommand that reports version information rather than editing anything. Each editing subcommand takes a path, and the module and provider subcommands also take a name. The supported versions are listed in the README: Terraform v0.12 and later, OpenTofu v1.6 and later. The lock subcommand is the interesting one, because the feature list says dependency lock files (.terraform.lock.hcl) are updated without the Terraform or OpenTofu CLI, which means the tool can refresh a lock file in a context where the Terraform binary is not installed or not permitted.
A single file update rewrites required_version in place
The terraform subcommand takes a path and a version. The help text shows the options.
$ tfupdate terraform --help
Usage: tfupdate terraform [options] <PATH>
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.The example in the README starts from a file with a pinned core version and rewrites it.
$ tfupdate terraform -v 0.12.16 main.tfThe version flag is not restricted to a bare version number. The README states it accepts any string literal and that you can pass a version constraint, so a pessimistic constraint is written into the file as a constraint.
$ tfupdate terraform -v "~> 1.0" main.tfThe result is that required_version inside the terraform block now reads "~> 1.0".
Recursive mode with ignore patterns covers a whole repository
For a repository where configurations are scattered, the recursive flag is the one you actually want. The README shows updating everything under the current directory, and then the same run with a path pattern to skip.
$ tfupdate terraform -v 0.12.16 -r ./$ tfupdate terraform -v 0.12.16 -i modules/ -r ./The ignore option takes a regular expression for paths to ignore, and setting the flag multiple times ignores multiple directories. That is the mechanism for excluding vendored modules or generated configuration, where a rewritten version constraint would create noise. If the version flag is omitted, the latest version is checked automatically and set, so a bare recursive run is the same thing as asking for whatever the registry currently offers.
$ tfupdate terraform -r ./One operational note follows from the mechanism. Finding the latest version means a network lookup against GitHub, GitLab, the Terraform Registry or the OpenTofu Registry, as the feature list states, while rewriting to an explicit version such as 0.12.16 is a local edit. That distinction is what makes the tool usable in an air-gapped or offline CI job, and it is also the distinction to keep in mind when a run fails.
Provider updates need both the provider name and the file
The provider subcommand takes two arguments, and the README gives an example that shows the before and after of a required_providers block.
$ tfupdate provider aws -v 3.74.0 main.tfThe provider name argument accepts either a short name such as aws or a namespaced one such as integrations/github. As with the core subcommand, the version can be a full version or a constraint, so the same provider block can be rewritten to a pessimistic range.
$ tfupdate provider aws -v "~> 3.0" main.tfThe OpenTofu subcommand mirrors the Terraform one exactly in shape, and the README example shows a required_version of 1.8.0 rewritten to 1.9.0. Both core subcommands therefore take the same flags, which is convenient when a repository contains both Terraform and OpenTofu configurations. What differs is the version each one looks up when the flag is omitted, since each resolves against its own registry.
Modules are the exception: latest resolution is not supported
The module subcommand is the one place where the tool does less than you might expect. Its help text states that the version option is required, and that automatic latest version resolution is not currently supported for modules. The module name argument accepts a module name or a regular expression in RE2 syntax, with examples such as terraform-aws-modules/vpc/aws, git::https://example.com/vpc.git and git::https://example\.com/.+. So for registry modules you still have to look up the version yourself and pass it in, while git sourced modules can be matched by pattern and given a version constraint. The reason is structural rather than a missing feature: a module can live in a registry, in a git repository, or in a local path, and only the registry case has a well defined latest version. The README also notes that the dependency lock file is handled by the separate lock command, not by the module subcommand.
Four install paths, from Homebrew to a Go toolchain
The README documents four ways to get the binary. On macOS you can use Homebrew or MacPorts.
$ brew install minamijoyo/tfupdate/tfupdate$ sudo port install tfupdateYou can also download the latest compiled binaries and put them anywhere in your executable path, with the releases page linked. From source you need a Go development environment, and the README specifies Go 1.26 or later.
$ go install github.com/minamijoyo/tfupdate@latest
$ tfupdate --versionThe Docker route runs the image directly.
$ docker run -it --rm minamijoyo/tfupdate --versionThe dependency list in go.mod explains the design choices. The tool parses HCL with hashicorp/hcl/v2, resolves provider addresses with terraform-registry-address, compares versions with hashicorp/go-version, and talks to GitHub and GitLab through go-github and go-gitlab. It uses spf13/pflag and mitchellh/cli for the command surface, afero for a filesystem abstraction that makes the editing testable, and minamijoyo/terraform-config-inspect, the author's own library, for reading Terraform configuration. The go.mod file declares go 1.25.0 while the README asks for Go 1.26 or later, so follow the README if you are installing from source.
Editorial conclusion
Adopt tfupdate when you pin Terraform core, provider and module versions across many directories and want a repeatable command, or a CI job that opens a pull request with the bump. Do not adopt it for the latest-version lookup alone, since that needs network access to GitHub, GitLab or the Terraform and OpenTofu registries, and the module subcommand explicitly does not support automatic latest version resolution. Verify first by running tfupdate terraform -v 0.12.16 on a scratch copy of a configuration, confirm the diff matches what you expect, and check that version v0.10.2, released on 2026-07-14, still behaves the way your pipeline assumes.
Frequently asked questions
How do I update a Terraform required_version with tfupdate?
Run tfupdate terraform -v 0.12.16 main.tf against the file, and the required_version inside the terraform block is rewritten in place. The version flag accepts any string literal, so a constraint such as "~> 1.0" can be written instead of an exact version.
Can tfupdate update all configurations in a directory recursively?
Yes, use the -r or --recursive flag with a path such as ./, and add -i with a regular expression to ignore directories you do not want touched. The flag can be repeated to ignore several path patterns.
Does tfupdate need the Terraform CLI installed?
Not for lock files. The README states that dependency lock files (.terraform.lock.hcl) can be updated without the Terraform or OpenTofu CLI, which is what the tfupdate lock command does.
Why does the tfupdate module command require a version?
The module help text states that the version option is required because automatic latest version resolution is not currently supported for modules. The module name argument can be a name or a regular expression in RE2 syntax, covering registry and git sourced modules.
Where does tfupdate get the latest version from?
The feature list says the latest release version comes from GitHub, GitLab, the Terraform Registry or the OpenTofu Registry, depending on what is being updated. That means resolving the latest version needs network access, while writing an explicit version is a local edit.
What licence is tfupdate released under?
The project is licensed under MIT, with the LICENSE file in the repository root. The code is written in Go, and the module path is github.com/minamijoyo/tfupdate.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/minamijoyo-tfupdate)Was this useful?