This repository represents our recommended template for a Terraform Root Module.
A Terraform Root Module is the most bottom level Terraform configuration, from which you would call other pieces of Terraform configurations and modules to create your infrastructure.
A Terraform Root Module is -not- typically used by other Terraform configurations; those would instead be called child modules.
This terminology is set by HashiCorp in their glossary and can be a little confusing; a Root Module might be better referred to as the base of your Terraform config, but it is better if we try to maintain parity with the upstream standard.
When you are creating a new repository to hold some top level Terraform configurations, you should follow the steps below:
- Copy the contents of the repository.
- Delete
.github/CODEOWNERS
, and the.github
folder if it is not required. - Edit .tflint.hcl to uncomment the relevant cloud provider(s) as necessary.
- If using Azure, you will also have to install the relevant tflint ruleset when enabling the plugin.
- Edit terraform/terraform.tf to set the Required Providers and also configure any required State Backends.
- Edit terraform/providers.tf to set any configuration options up for the required providers.
- Delete everything between the
REPLACE THIS SECTION
tags in the README.md and terraform/README.md files and replace them with relevant documentation.
pre-commit is needed to run a number of basic linters and tests locally; as such, you need to install the pre-commit hooks for each time you clone a repository using this template, if you don't do so automatically already. This can be done with the following command in the root directory of your repository;
pre-commit install
This example was created and checked using the following versions of the tooling. If newer versions of the tooling are available, feel free to check and raise a PR to update the version table below.
The tool versions in the table below are meant as a guideline, and client requirements could override these. In this case please test the code with the version that the client specifies.
Tool | Version | Description |
---|---|---|
pre-commit | 2.10.1 | Used to control and run Git hooks. |
terraform | 1.2.4 | Used for testing and applying the Terraform configurations. |
coreutils | N/A | Required for the realpath binary on macOS. Install via brew install coreutils . |
terraform-docs | 0.11.2 | Used to create the terraform/README.md file from the Terraform configurations themselves. |
tflint | 0.35.0 | Used to perform more advanced linting of the Terraform configurations. |
tfsec | 0.39.6 | Used to scan Terraform configurations for known potential security issues. DOG would also recommend checkov as an alternative. |
This folder is only present for functions within this existing repository, and should -not- be present in a deployed version of this template, excluding any files added into the separate repository.
The .tflint.hcl
file is used to configure the tflint application to perform linting checks against the Terraform in this repository.
The Terraform code itself has been put into a subfolder, terraform/
, to allow for other types of code that live in the same repository to be kept separate.
This also keeps the root folder cleaner, so only mandatory dot files and any CI/CD files that are required have to live in the root of the repository.
The terraform
folder itself should contain the following files:
The terraform/.terraform.lock.hcl
file, also known as the Dependency Lock file, is used by Terraform to validate and lock the version of the required provider binaries used for a set of Terraform configurations. The file contains hashes of the provider binary and zip files, plus the versions and constraints specified for the provider at the time of creating the file.
For a root module, we would highly recommend committing the Dependency Lock file, terraform/.terraform.lock.hcl
.
This ensures that for all executions of the your root module's Terraform configurations, the exact same provider releases and versions are used, increasing consistency within Terraform workflows (Ignoring possible remote API variance).
The terraform/.terraform.lock.hcl
file should not be committed into either child modules within the same repository, or modules and configurations that are to be shared with others.
For child modules, only the root module level terraform/.terraform.lock.hcl
file is considered, and so storing them at any other location is unnecessary and adds additional maintenance overheads for no benefit.
For shared code examples, the provider version calculated based upon variable provider constraints means that terraform/.terraform.lock.hcl
is highly likely to be recreated. You also do not typically need the benefits that the Dependency Lock file provides in this scenario, as all shared code examples should be validated as working in the new environment that they've been applied into.