This is a template containing a basic skeleton for infrastructure as code projects with Terraform/OpenTofu wrapped in Terragrunt.
Root modules that are holding state are stored in one of the environments. The environments global, staging and production are a good starting point.
See environment/global/state-storage for an example of a module.
The basic logic for data loading is defined in the root.hcl in the environments folder. This file gets included in every subsequent terragrunt.hcl. When running terragrunt run-all plan in the environments folder every terragrunt.hcl gets identified by Terragrunt as root module and a plan is created for every root module. This also explains why the top-level Terragrunt file must be named root.hcl instead of terragrunt.hcl. With this naming scheme Terragrunt doesn't identify root.hcl as a root module and won't create a plan for it, which would lead to an error.
The terragrunt.hcl itself includes the root.hcl and all other relevant files. These two files combined lead to the following hierarchical loading logic:
- module loads
inputs.yaml - environment loads
environment_inputs.yaml - root loads
global_inputs.yaml
All the loaded data is merged and passed to the called modules. The YAML files are merged with priority to specific data. That means if a value is set on root level and on module level, the module level wins.
Note that deep merging of nested values does not work. If any sub-values are set in a higher priority file, the complete value is overwritten and all sub-values that are not defined in the higher priority file will not be present after merging.
It is a good idea to have version constraints defined for your code. By default a globally managed versions_override.tf will be created.
If you don't want to use it, for example you use an external module which already has versions defined, simple remove the include "versions" block.
The following variables are generated by Terragrunt and added to every module:
environmentprojectmoduleregion
Generated files are named "*_generated.tf", which is already excluded from git.
The templates for generated code live in code_snippets and can be included with file() or templatefile().
The environment variable TF_PLUGIN_CACHE_DIR is set to ~/.cache/terraform/plugin-cache by default and can be overwritten by setting the variable otherwise. The cache directory is created if not existent. This suppresses a warning raised by terraform.
When using OpenTofu add the following to the terraform section.
terraform {
extra_arguments "OpenTofu binary" {
commands = ["*"]
env_vars = {
TERRAGRUNT_TFPATH = "tofu"
}
}
}Secrets can be stored in secrets.yaml. Its content is added to the inputs hash.
Add the following code to the locals block of root.hcl to use this feature.
secrets = yamldecode(file(find_in_parent_folders("secrets.yaml")))When using GitLab as state storage, the backend configuration required can be generated by Terragrunt.
Set following environment variables:
TF_HTTP_USERNAME: Your GitLab user nameTF_HTTP_PASSWORD: A Project Access Token with scopeapiand roleMaintainerCI_API_V4_URL: The GitLab API v4 root URLCI_PROJECT_ID: The ID of the GitLab project
Enable the remote_state block in the root.hcl file.