Part 06 — Structuring Terraform Modules
This article provides a brief overview of the folder structure that I use for my Terraform modules. If you have been following the previous articles in this series, you should already be familiar with this structure.
Folder Structure
Here is the folder structure I typically use for my Terraform modules:
module/
├── .docs/
│ ├── .terraform.docs.yml
│ └── footer.md
│ └── header.md
├── src/
│ ├── main.tf
│ ├── variables.tf
│ └── outputs.tf
│ └── context.tf
│ └── provider.tf
├── tests/
│ ├── test.tf
│ ├── variables.tf
│ └── outputs.tf
│ └── provider.tf
│ └── .auto.tfvars.tf
├── .gitlab-ci.yml
└── Readme.md
Let me explain what each of these folders contains and why they are important.
.docs
The .docs
folder contains any content necessary for generating documentation for your module. I have explained in detail about the contents in the `.docs` folder in Part 04 — Documenting Terraform Modules | by Vighnesh Prakash | Medium.
src
The src
folder is where the actual module code resides. This includes the main.tf
file, which contains the resources that make up the module, as well as any variables.tf
and outputs.tf
files that define inputs and outputs for the module. There is also a special context.tf
which is used to streamline all the “common” inputs to a module.
Separating the module code from the test code makes it easier to reuse the module across different projects.
tests
The tests
folder contains code to consume the contents in the src
folder and possibly deploy it in some environment. It's important to have good tests to ensure that the module works as expected and to prevent any regressions when updating the code. I will use this article to articulate more on the pipeline I use for testing my terraform modules.
Let's see how I invoke my terraform
As you see, the source refers to the local src folder and NOT the published module. This is done intentionally as the “tests” must run before the module is published.
Let's understand the GitlabCI for the tests
The “test” pipeline has two stages, test and clean up.
- Whatever has been deployed to the environment must be “removed” after the tests have run. One of the two jobs (cleanup_when_test_success or cleanup_when_test_fails) will ensure that whatever has been deployed has been removed.
- The state file for
test_the_module
job is kept locally inside a folder called.build
. This.build
folder along with its contents is then passed as an artifact to the next job (cleanup_*) to destroy whatever has been deployed to your AWS environment.
- Whether the test succeeds or fails, one of the cleanup_* job is always run. This ensures that whatever has been created during the test will ALWAYS be destroyed by one of these jobs.
Line numbers 29–40 is a way of referencing common code applicable to both cleanup_when_test_success or cleanup_when_test_fails jobs.
An anchor is a way of creating a reference to a YAML node so that it can be reused later in the YAML file without having to duplicate the entire node. In this case, &cleanup_job
is defining an anchor named "cleanup_job" that points to the .cleanup_job
job definition.
Later in the YAML file, the anchor can be used by referencing its name using the *
syntax, like <<: *cleanup_job
. This is a shorthand way of copying the entire node defined by the anchor into the current location in the YAML file. This makes it easy to reuse job definitions or other YAML nodes without duplicating code or configuration.
Links
Articles in this Series
Introduction — Terraform Modules: From Development to Deployment on Gitlab
Part 01 — Publishing Terraform Modules to GitLab Infra Registry
Part 03 — Publishing Terraform Modules using GitLab Pipelines
Part 04 — Documenting Terraform Modules
Part 06 — Structuring Terraform Modules
[Coming Soon] Part 07 — Bringing it All Together