Part 06 — Structuring Terraform Modules

Vighnesh Prakash
4 min readApr 9, 2023

--

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

tests/main.tf

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

.gitlab-ci.yml

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.
tests/provider.tf
  • 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.
Cleanup_* 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

transcendent-wisdom / stories / Managing Terraform Modules / 06-structuring-terraform-modules · GitLab

Articles in this Series

Introduction — Terraform Modules: From Development to Deployment on Gitlab

Part 01 — Publishing Terraform Modules to GitLab Infra Registry

Part 02 — Just Enough Gitlab

Part 03 — Publishing Terraform Modules using GitLab Pipelines

Part 04 — Documenting Terraform Modules

Part 05 — Release Strategy

Part 06 — Structuring Terraform Modules

[Coming Soon] Part 07 — Bringing it All Together

--

--