7

I'm trying to call multiple modules from terragrunt. I understand that currently, terragrunt doesn't support multiple sources and we can only call one module at a time. So, I created a main.tf file to frontend multiple modules.

# main.tf 

module "foo" {
   source = "../modules/vpc"
}


module "bar" {
   source = "../modules/s3"
}

Inside terragrunt calling main.tf as a source, thinking that will call module foo and module bar.

# terragrunt.hcl

terraform {
  source = "./main.tf

  }


inputs {
}

Is this possible using terragrunt? I need to group multiple terraform modules at once.

Meet101
  • 711
  • 4
  • 18
  • 35

2 Answers2

12

In short, yes, the two files snippets you've posted would work.

terragrunt doesn't support multiple sources and we can only call one module at a time.

Longer answer: It's useful to think of the terraform { ... } block in your terragrunt.hcl as a pointer to a "root terraform module". This root module is just any other terraform module, but is special because it is at the root, or the top, of all your terraform config.

So terragrunt only supports one root module, but that root module can use as many additional modules as you need.

The power terragrunt gives us is the ability to re-use these root modules. In vanilla terraform you cannot re-use this root modules.

In your example the terragrunt file is pointing to a root module in the same file (./main.tf). This works just fine, but because we use terragrunt to keep things DRY we would normally put this root module in a different directory, perhaps even in a git repo and reference it appropriately in the terragrunt.hcl file

Here is a quick diagram:

         +-------------------------------+
         |       /my/root-module         |
         |                               |
         |           main.tf             |
         |                               |
         +--------------+----------------+
+------------------+    |    +----------------+
|  /my/modules/vpc |    |    | /my/modules/s3 |
|                  |    |    |                |
|   module "foo"   <----+---->  module "bar"  |
|                  |         |                |
|                  |         |                |
+------------------+         +----------------+

Not shown is the terragrunt.hcl file that would point to /my/root-module, this can be somewhere else on disk or in git.

Casey
  • 6,166
  • 3
  • 35
  • 42
  • I don't think we can put /my/root-module anywhere. it needs to be somewhere on the path where you have child modules (/my/modules/vpc, /my/modules/s3). I tried this and didn't work. when you reference /my/root-module as source in terragrunt.hcl, It downloads all modules config based on whatever root you have specified with (//) in the path. in this case, it will be source = //my/root-modules. so terragrunt will download everything on level of /my directory which will cover both modules. let me know if this is not true and is it possible to put root-modules anywhere. it didn't work for me! – Meet101 Feb 25 '21 at 21:33
  • That's not the case @Meet101. It /can/ go anywhere, but the `source = "..."` line must be updated to reference accordingly. It can be a relative file path, an absolute file path, a remote github repository, or a reference to one of the hosted modules on the terraform registry. The location of modules are independent of eachother, it only matters if you're using relative paths. – Casey Feb 26 '21 at 07:50
  • 1
    Hi @Casey quick question for you: If I have this setup (with a root Terraform module calling child modules) as in the picture above, how do I approach a situation where my Terragrunt modules only need to use a specific child module. The root Terraform module has the variables {} needed for all the child modules, but Terragrunt isn't passing them all if it only needs a selective child module. For instance there might be /my/modules/vpc and /my/modules/s3 but a Terragrunt module might only pass inputs for /my/modules/vpc to the root module. – Alexander Witte Apr 27 '22 at 20:53
  • I'm not understanding how this makes code dry. Your main.tf isn't reusable by any means, since most likely each root module calls different resources. My root module for s3, calls an s3 module vs. my root module for a serverless service, calls a serverless service module. Having your `terragrunt.hcl` call a local main.tf file is just fine. – alex067 Aug 22 '23 at 14:21
2

I have the following structure.

project    
│
└───live
│   │
│   └───dev
│       │   terragrunt.hcl
│       │   
│       └───aws-ec2
|       |      terragrunt.hcl   
|       └───aws-rds
|              terragrunt.hcl
│   
└───modules
    │   
    └───ec2
    │      files.tf
    └───rds
           files.tf

In dev I am running terragrunt plan-all (which is deprecated, but works if you do not mind the errors caused by dependencies). The latest cli option is terragrunt run-all (command), but I think you need a terraform file in addition to your terragrunt file.

More info can be found here:

  • this is correct. in my case, I have a complicated directory structure, and not possible to use apply-all/ run-all command from the root directory. instead of this, I am grouping multiple modules into one and then call that root module directly. – Meet101 Feb 25 '21 at 21:27