Skip to content

Skeleton for infrastructure as code Projects with Terragrunt wrapping Terraform/OpenTofu

License

Notifications You must be signed in to change notification settings

makandra/iac-project-template

Repository files navigation

Terraform/OpenTofu Template

This is a template containing a basic skeleton for infrastructure as code projects with Terraform/OpenTofu wrapped in Terragrunt.

General structure

Environments

Root modules that are holding state are stored in one of the environments. The environments global, staging and production are a good starting point.

Create your own Modules

See environment/global/state-storage for an example of a module.

Hierarchical loading of data

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.

Version constraints

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.

Root Variables

The following variables are generated by Terragrunt and added to every module:

  • environment
  • project
  • module
  • region

Generated Code

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().

Terraform plugin cache dir

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.

Use OpenTofu

When using OpenTofu add the following to the terraform section.

terraform {
   extra_arguments "OpenTofu binary" {
     commands = ["*"]
     env_vars = {
       TERRAGRUNT_TFPATH = "tofu"
     }
   }
}

Secrets

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")))

GitLab as state storage

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 name
  • TF_HTTP_PASSWORD: A Project Access Token with scope api and role Maintainer
  • CI_API_V4_URL: The GitLab API v4 root URL
  • CI_PROJECT_ID: The ID of the GitLab project

Enable the remote_state block in the root.hcl file.

About

Skeleton for infrastructure as code Projects with Terragrunt wrapping Terraform/OpenTofu

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages