Use terraform module sub directory

Hello.
I create terraform modules and use current resources.
As resources increased, terraform files increased like this.

├modules/
├terraform/
  ├a.tf
  ├b.tf
  ├c.tf
  ├...

Now, I want to seperate terraform files like this.

├modules/
├terraform/
  ├main.tf
  ├network
    ├a.tf
    ├b.tf
  ├vm
    ├a.tf
    ├b.tf
  ├monitoring
  ├...

when I run terraform apply, only modules in main.tf are work and not work sub directory modules…
How can I seperate my terraform files and run?

my terraform files have enterprise resources(+1000), so I think tfstate seperation is hard now…

Thank u.

Hi @Danpatpang,

From Terraform’s perspective, each directory is a separate Terraform module. Therefore if you place files in separate directories then you now have multiple separate modules, and so you’ll need to make sure that your root module (I think that’s your terraform directory) contains module blocks to call the others:

module "network" {
  source = "./network"

  # (and any input variables the module needs)
}

module "vm" {
  source = "./vm"

  # (and any input variables the module needs)
}

module "monitoring" {
  source = "./monitoring"

  # (and any input variables the module needs)
}

If you already have remote objects associated with the resources in your configuration then by default Terraform will understand this change as you wanting to destroy the existing objects and create new objects at the new addresses.

The forthcoming Terraform v1.1.0 release, which is currently in release candidate and so should be final soon unless anyone raises a significant blocker based on the release candidate, includes a new feature where you can use moved blocks to tell Terraform how to map from the old resource addresses to the new resource addresses:

moved {
  from = aws_vpc.example
  to   = module.network.aws_vpc.example
}

moved {
  from = aws_instance.example
  to   = module.vm.aws_instance.example
}

With declarations like this for each of your existing resources you will be able to run terraform apply and see Terraform propose to move the existing objects into the child modules, rather than to destroy the old objects and create new ones.

If you can’t wait for Terraform v1.1.0 then you can achieve a similar effect today using the terraform state mv command, but that will modify your current state directly and so there is no mechanism to preview the address changes as part of a plan, and you’ll need to coordinate with your coworkers to make sure nobody else tries to plan and apply changes to this configuration while you are doing your refactoring work.

Terraform v1.1.0 isn’t final yet at the time while I’m writing this, so the docs aren’t yet published, but once Terraform v1.1.0 final is published you will be able to see the documentation for moved blocks on the Refactoring page. (which will return a “Not Found” error until the v1.1.0 final release.)

1 Like