How to set up versions.tf at root level of directory

Terraform
├── prod
│ ├── prod-terraform-version
│ ├── mysql
│ ├──── main.tf
│ └── vpc etc
│ ├──── main.tf
└── staging
├── staging-terraform-version
├── mysql
└── vpc etc

is how I would like to set up my env but not sure how to proceed in setting up the versions.tf file not in the working directory. does terraform init --backend-config work for this or is that only for backend config block?

Hi @lokeshmanchi,

The file name versions.tf is just a convention for where to place information about version constraints, but they can really appear in any .tf file.

The key thing to note here is that the version constraints are a per-module idea and so should ideally be included in every directory that contains .tf files, describing which Terraform and provider versions each specific module is compatible with. There is no expectation that all of your modules would declare the same requirements, because each one will be using different features of Terraform and different provider features.

I would therefore suggest specifying in each module only the minimum version of each provider that particular module depends on, using a >= version constraint. That will ensure that each module gets at least the version it requires.

terraform init will then select the latest version of each provider that all of your modules are compatible with and record that information in the dependency lock file, which you should add to your version control to “remember” which exact versions you are using until you explicitly upgrade.

1 Like

@apparentlymart
is the following structure what you would suggest

So from what you’re suggesting, each directory needs a providers/versions.tf and there’s no way to have a central file that controls that? In my thought it would be easier to control versions if there was a central file. Im also using terraform cloud if that makes a difference

Is there an example repo I can take a look at that follows the structure you suggest?

Yes, each module should ideally specify only the versions that individual module needs, so each module has its own constraints.

For example, if your gke module use a feature of the GCP provider that was added only recently in v4.40, that module should specify >= 4.40.0. But that version constraint need not be specified in any other module, unless that particular module also uses very new provider features.

This means that you only need to update the version constraints for a module when you start using new provider features in that particular module. No other module needs to be updated, because Terraform will itself merge all of the version constraints together and select a version that all of the modules are compatible with.

Notice that the version constraints are for specifying a set of versions that the module should be compatible with, and not for selecting an exact version to use. The exact version selection belongs in the dependency lock file instead, and Terraform will generate or update that automatically as part of terraform init.