Last Updated on February 17, 2024 by Arnav Sharma
Terragrunt is a thin wrapper that provides extra tools for keeping your configurations DRY, working with multiple Terraform modules, and managing remote state.
Terragrunt works on DRY concept, ie. Don’t repeat yourself !!
The DRY principle is stated as “Every piece of knowledge must have a single, unambiguous, authoritative representation within a system”.
Benefits and key features:
- Better backend management and using variables in the backend config file.
- If using multiple modules, we just need one backend config file – so no copy/paste.
- It uses a repo/module structure so it’s easy to manage code and environments.
- You don’t have to update or add variables in multi-module design, everything can be supplied via terragrunt file.
- Can execute on each child module as well as all modules at the same time.
- Config generation: Remote and Provider files can be generated during runtime.
For sometime it was bit hard for me to understand on why would we need Terragrunt when we can use modules, however the best way to get started and understand Terragrunt is start using it. The main benefit was that Terragrunt forces you to stick to a directory structure and organise variables in better way.
- Initial setup can be tricky.
- The syntax can be difficult to understand- it’s HCL.
- Most of the examples on Terragrunt doco are based on AWS. ?
- The documentation isn’t very clear. (When compared to Terraform)
Installing: Follow the link and its quick Install (gruntwork.io)
Configuration file syntax: Configuration (gruntwork.io)
The modules I have used are on GitHub:
The green ones are configuration files and the red ones are the modules (link above)
I want to deploy 4 resources in 3 different environments:
- Using Terraform I can create modules for each, declare the variables for each module and then have backend + provider copy-pasted for each.
- The state file is located in one of the files and all resources are dumped into a folder.
- And lastly, I need to pass on my variables based on the environments – so this would need a couple of file edits.
I’m deploying Resource Group with App Service, VM and vNET in 3 different environments.
Each resource folder is having a terragrunt.hcl file (Green Arrow) and a main terragrunt.hcl file at the root level (Red Arrow)
If you look at the one of the main.tf file (example Virtual Network) – the file calls the source folder,
- but no location is specified here 1️⃣
- nor there is any providers block 2️⃣
- and no backend block/config is specified here. 3️⃣
So, overall nothing changes here in case we want to deploy it to the Development or Testing environment.
And that’s how the terragrunt.hcl file looks like – this file has two blocks, one pointing to root folder and another setting dependency on the resource group deployment.
The terragrunt.hcl at the root level:
Pretty much everything sits here:
- The first block (red) points to the main modules or the source code for resources. The link has been posted above.
- The second block (green) is for locals and inputs – basically allowing us to pass locals and variables (inputs) – so this is the only file or block which needs to be changed while changing environments or the resource values/names.
- The third block (blue) generates the providers file, so the file is never present but generated while executing the code.
- The last block (yellow) specifies the remote state – we can use variables here and can change the values for folders (container structure) on the go, which is not supported by Terraform by default.
Overall – the only file that needs to be edited or updated is the root terragrunt file.
For the execution part, (refer CLI options (gruntwork.io)) run the terragrunt init followed by terragrunt run-all apply command from the root directory and the code will be executed with any dependencies specified.
If there are any dependencies, like deploying VM after vNET, it will be processed in a groups:
Authentication remains the same – pretty much similar to Terraform. ?
For detailed and additional details, refer to the documentation: Documentation (gruntwork.io)
Modules repo: sharmaarnav/terragruntmodules (github.com)
Live used: sharmaarnav/terragruntliverepo (github.com)