How do i connect my main.tf to a .tfvars file in a different directory

my_terraform_project/
├── my_terraform_module/
│   ├── main.tf
│   ├── variables.tf
│   └── outputs.tf
├── environments/
│   ├── dev/
│   └── prod/

In my main i have written a blueprint for what I want my infrastructure to be like.

provider aws {
  region = var.aws.region
}

resource "aws_instance" "web" {
  ami           =  var.aws.ami
  instance_type =  var.aws.instance_type

  tags = {
    Name = var.instance_name
  }
}

module "my_instance" {

  source        = "../../my_terraform_module"
  instance_name = var.instance_name

}

However because i want to use two enviroments namely dev and prod. I have added variable files like so. dev:

aws_region       = "us-west-2"
aws_ami          = "ami-008bcc0a51a849165"
aws_instance_type = "t2.micro"
instance_name    = "dev-instance"

and prod:

aws_region       = "us-west-2"
aws_ami          = "ami-008bcc0a51a849165"
aws_instance_type = "t2.micro"
instance_name    = "dev-instance"

But how can I make sure that my main is connected to these variable files in such a way that when i go into the dev directory i can do a terraform apply command and the infrastructure gets created in the dev enviroment same thing with production. I would really appreciate some more insight into this problem

Before this I tried to work with terraform workspaces however it uses the same backand for all enviroments which reduced the flexibility i needed`

You need three backticks ``` on a line by themselves to enter/exit code block formatting.

It is difficult to answer with precision, as even though you have shown a directory tree, you appear to have left various files out … it is unclear in which directory the Terraform code you have shown us is located, and what filenames your variable files have.

It seems like you probably just need to take a look at https://developer.hashicorp.com/terraform/language/values/variables#variable-definitions-tfvars-files particularly the part reading

Terraform also automatically loads a number of variable definitions files if they are present:

  • Files named exactly terraform.tfvars or terraform.tfvars.json.
  • Any files with names ending in .auto.tfvars or .auto.tfvars.json.

With the layout you’ve shown here I would actually ignore .tfvars files altogether and just make the configuration under each environments directory describe the differences.

For example, your environments/dev directory could contain the following:

locals {
  aws_region    = "us-west-2"
  instance_name = "dev-instance"
  instance_type = "t2.micro"
  ami_id        = "ami-008bcc0a51a849165"
}

provider "aws" {
  region = local.aws_region
}

resource "aws_instance" "web" {
  ami           = local.ami_id
  instance_type = local.instance_type

  tags = {
    Name = local.instance_name
  }
}

module "my_instance" {
  source = "../../my_terraform_module"

  instance_name = local.instance_name
}

If you place all of the declarations that should be common across both environments in the my_terraform_module directory then your dev and prod directories will each contain only the parts which can vary between environments:

  • The four values you indicated you wanted to place in variables files.
  • The provider configuration.
  • Your backend configuration (not shown in your example, but if you had one it would go here)
  • Any resources that are unique to a particular environment, which I assume is true for aws_instance since in your example you showed it as being in the root module.

Input variables are primarily for values coming from outside of a Terraform configuration, or that which need to vary from one run to the next. If you already have a separate root module for each environment anyway then a separate variables file is unnecessary complexity, because each root module can directly encode the settings specific to that environment, and delegate to your shared module for the parts which are common across both.

If you still want to use variables files then one way to achieve that would be to place a terraform.tfvars file under each of the dev and prod directories. Terraform will automatically load a variables file of that name when you run terraform plan or terraform apply. That convention is primarily intended for use in automation scenarios (for example, Terraform Cloud automatically generates a terraform.tfvars file with the workspace stored variable settings before running terraform plan) but you can choose to place that file under your version control if you like.