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 an module.
- 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.
The following variables are generated by terragrunt and added to every module:
environment
project
module
region
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 parameters required can be generated by terragrunt.
Set following environment variables:
GITLAB_USERNAME
GITLAB_TOKEN
CI_API_V4_URL
CI_PROJECT_ID
Add the following code to the terraform
section in the root.hcl
.
terraform {
extra_arguments "GitLab state storage" {
commands = ["init"]
arguments = [
"-backend-config=address=${get_env("CI_API_V4_URL")}/projects/${get_env("CI_PROJECT_ID")}/terraform/state/${local.state_name}",
"-backend-config=lock_address=${get_env("CI_API_V4_URL")}/projects/${get_env("CI_PROJECT_ID")}/terraform/state/${local.state_name}/lock",
"-backend-config=unlock_address=${get_env("CI_API_V4_URL")}/projects/${get_env("CI_PROJECT_ID")}/terraform/state/${local.state_name}/lock",
"-backend-config=username=${get_env("GITLAB_USERNAME", "gitlab-ci-token")}",
"-backend-config=password=${get_env("GITLAB_TOKEN", get_env("CI_JOB_TOKEN", ""))}",
"-backend-config=lock_method=POST",
"-backend-config=unlock_method=DELETE",
"-backend-config=retry_wait_min=5"
]
}
}