31

Currently I am working on a infrastructure in azure that comprises of the following:

  • resource group
  • application gateway
  • app service
  • etc

everything I have is in one single main.tf file which I know was a mistake however I wanted to start from there. I am currently trying to move each section into its own sub folder in my repo. Which would look something like this:

terraform-repo/
├── applicationGateway/
│   ├── main.tf
│   ├── vars.tf
├── appService/
│   ├── main.tf
│   └── vars.tf
├── main.tf
└── vars.tfvars

However when I create this while trying to move over from the single file structure I get issues with my remote state where it wants to delete anything that isn't a part of the currently worked on sub folder. For example if I wanted to run terraform apply applicationGateway I will get the following:

  # azurerm_virtual_network.prd_vn will be destroyed

Plan: 0 to add, 2 to change, 9 to destroy.

What is the correct way to setup multiple logically organized sub folders in a terraform repo? Or do I have to destroy my current environment to get it to be setup like this ?

Pablo Marti Cordero
  • 944
  • 2
  • 9
  • 23

3 Answers3

32

You are seeing this issue because terraform ignores subfolders, so those resources are not being included at all anymore. You would need to configure the subfolders to be Terraform Modules, and then include those modules in your root main.tf

Mark B
  • 183,023
  • 24
  • 297
  • 295
  • 29
    Can someone explain motivation behind this? I find it pretty annoying that I need to have all tf files in one directory and not having it organised with subdirectories. – trubi Jul 29 '21 at 13:49
  • @trubi only Hashicorp can answer your question! Anyway, hi MarkB please update the link: https://www.terraform.io/docs/language/modules/index.html – ADTC Nov 22 '21 at 08:39
  • (looks to me like both links work) – Ben Millwood Sep 16 '22 at 10:09
  • @dur you should take that feedback to HashiCorp. Posting it here isn't going to accomplish anything. – Mark B Dec 05 '22 at 17:52
  • @dur just because there are some open issues after years doesn't mean there aren't tons of other issues have been fixed and closed out. You seem to be looking more for a place to vent and complain, and this is not the correct venue. – Mark B Dec 05 '22 at 18:15
  • 1
    @MarkB Sorry, I don't want to offend you. I'm not looking or a place to complain. It's just I'm really disappointed about some important issues still not resolved. However, it is open source and I should know it. – dur Dec 05 '22 at 19:26
9

update 06/2022 , Complete example :

Let's say you have the following directories

./your-folder
|__ main.tf
|__ variables.tf
|__ output.tf
|__ /modules
    |__ /module-a
        |__ main.tf
        |__ variables.tf
        |__ output.tf

Module definition in ./your-folder/modules/module-a/main.tf:

resource "[resource_type]" "my-module-name" {
   ...
}

Load module in your root main.tf file, so in ./your-folder/main.tf:

module "my-module-instance-name" {
    source = "./modules/module-a"
    other-input-variable = "..."
}

Then tell Terraform to load this new module running the following command in your root directory (so ./your-folder):

terraform get

Then test your setup with terraform plan.

To use root-level resources in child modules, inject it into child module as input variable.

To use child-level resources in root module, export it from child module with the output instruction.

Hope this helps. :)

Will Vousden
  • 32,488
  • 9
  • 84
  • 95
thiout_p
  • 717
  • 11
  • 15
  • 2
    important to point out that you can have multiple files in the module directory, regardless of file naming as long as the extension is ".tf" (I took a time to realizes that) – robsonrosa Nov 24 '22 at 11:29
3

One option for maintaining a DRY environment this way is using Terragrunt

Terragrunt is a wrapper for Terraform that allows organization and reusable components in a slightly different way than Terraform handles environments.

0bel1sk
  • 505
  • 5
  • 4