Auto-switch and pinning
Let teriac pick the version each project needs from version files, the state file or required_version, switch on every cd with the shell hook, and pin versions for your team.
Auto-switch
auto-switch switches to the version your project needs, and installs it first if it isn't in the
store.
teriac auto-switch
teriac as # alias
teriac as --provider tofu
teriac as -p tgWhere the version comes from
For Terraform and OpenTofu, teriac looks at these, in order, and uses the first it finds:
- A version file in the current folder
- Terraform:
.terraform-version,.tfswitchrc,.tfswitch.toml, or aterraformline in.tool-versions(asdf / mise) - OpenTofu:
.opentofu-version,.tofu-version, anopentofuortofuline in.tool-versions, then.terraform-version
- Terraform:
terraform.tfstate: theterraform_versionfieldrequired_versionin any.tffile. All constraint operators work:=,>=,>,<=,<,!=,~>, and compound ones like">= 1.3, < 2.0"
When a constraint allows several versions, teriac picks the newest stable release that fits.
For Terragrunt, see OpenTofu and Terragrunt.
Version files at a glance
| File | Read for | Example |
|---|---|---|
.terraform-version |
Terraform (and OpenTofu as a fallback) | 1.9.0 |
.opentofu-version |
OpenTofu | 1.8.0 |
.tofu-version |
OpenTofu | 1.8.0 |
.terragrunt-version |
Terragrunt | 1.2.1 |
.tgswitchrc |
Terragrunt | 1.2.1 |
.tfswitchrc |
Terraform | 1.9.0 |
.tfswitch.toml |
Terraform | version = "1.9.0" |
.tool-versions |
All three (asdf / mise) | terraform 1.9.0 |
terragrunt.hcl, root.hcl |
Terraform and Terragrunt | terraform_version_constraint = "~> 1.9" |
*.tf |
Terraform and OpenTofu | required_version = ">= 1.6" |
A .tool-versions file can hold every tool at once:
terraform 1.9.0
opentofu 1.8.0
terragrunt 1.2.1Switch on cd
The shell hook runs whenever you change directory (it uses your shell's own hooks, such as zsh's
chpwd), so entering a Terraform project switches the version for you. Other folders cost one
filesystem check and no subprocess.
A folder counts as a Terraform project if it has:
- a version file (
.terraform-version,.opentofu-version,.tofu-version,.tfswitchrc,.tfswitch.toml), or - a
.tool-versionsfile with aterraform,opentofuortofuline, or - a Terragrunt file (
.terragrunt-version,.tgswitchrc,terragrunt.hcl,root.hcl), or - any
*.tffiles
It switches Terraform as above, and also switches OpenTofu when the project pins it with its own file
(.opentofu-version, .tofu-version or .tool-versions), and Terragrunt when the project pins it.
cd ~/Downloads # no .tf files → nothing happens
cd ~/projects/react-app # no .tf files → nothing happens
cd ~/projects/infra # has main.tf → auto-switch runs silently
cd ~/projects/platform # has .terraform-version → auto-switch runs silentlySet it up once
# Bash
printf '\neval "$(teriac shell-init bash)"\n' >> ~/.bashrc
# Zsh
printf '\neval "$(teriac shell-init zsh)"\n' >> ~/.zshrc
# Fish
printf '\nteriac shell-init fish | source\n' >> ~/.config/fish/config.fish
# PowerShell
Add-Content $PROFILE "`nInvoke-Expression (teriac shell-init powershell | Out-String)"pwsh works as a name for PowerShell too. Open a new terminal afterwards.
To see what the hook does before you add it, print it: teriac shell-init zsh.
Tab completion
shell-init also adds tab completion:
teriac <tab>completes commands;teriac use <tab>completes installed versions;teriac --provider <tab>completes provider names.
Pin a version
pin writes a version file in the current folder, so teammates (and auto-switch, the shell hook,
CI and teriac server) all use the same version. Each tool has its own file, so pinning one never
switches another.
teriac pin # pin the active version → .terraform-version
teriac pin 1.9.0 # pin a specific version
teriac pin --provider tofu # → .opentofu-version
teriac pin --provider terragrunt # → .terragrunt-versionCommit the file. teriac server plans each project with the exact version it pins, from these same files; see what gets planned.
A team workflow
# Once, by whoever upgrades the project
cd infra/
teriac install 1.9.^
teriac use 1.9
teriac pin
git add .terraform-version && git commit -m "Use Terraform 1.9"
# Everyone else, with the shell hook set up
git pull
cd infra/ # teriac installs and switches to the pinned version
terraform version