Part 04 - Documenting Terraform Modules

Vighnesh Prakash
7 min readJan 29, 2023

--

The quality of documentation determines the effectiveness of a terraform module. Documenting your terraform module is important as it helps others understand how to use and configure the modules you have created. It also allows users to assess your module's capabilities and limitations.

In this article, we will explore one of the ways to document terraform modules. We see then how this process can be automated by adding it to a GitLab pipeline.

terraform-docs

terraform-docs is an amazing tool that generates documentation for Terraform modules. It reads the terraform files in a module and generates a markdown documentation file that includes information about the module’s inputs, outputs, and usage. This tool is open-source and can be run locally on a developer’s machine or as a part of a continuous integration pipeline.

In this article, we will not cover the specifics of using terraform-docs as the tool’s official documentation does an excellent job of that. Instead, we will explore how to integrate terraform-docs into a GitLab pipeline.

Set-Up

Let us see our updated repo structure below.

Updated repo structure with .docs

As you see, a “.docs” folder is added to the root of the repo. This contains the necessary components to generate our documentation. Let's take a look at each file.

  • header.md” is a template that contains information about the terraform module. This must be filled in by the user
header.md
  • footer.md” is a template that contains information on how to use the module. This necessary information must be populated by the user.
footer.md
  • The “.terraform.docs.yml” file provides the configuration needed for terraform-docs to generate the documentation in a specific format. terraform-docs uses the contents of the “header.md” file, the generated body, and the contents of the “footer.md” file to create the final documentation for the module.
.terraform.docs.yml

Manual Document Generation

Now that the configurations are ready, let us generate the documentation. First, let us run it locally using the terraform-docs container. It involves a few “manual” steps

  1. Copy the .docs folder from the root to inside the src folder (Which contains the actual module code)
  2. From the root folder, run the below-given code
docker run --rm --volume "$(pwd):/terraform-docs" \ # map current working directory to a folder inside the container
quay.io/terraform-docs/terraform-docs:0.16.0 \ #specify the docker image to be used
/terraform-docs/src > ./readme.md \ #specify the "src" folder where the module code exists and the readme.md file where the generated document should be saved
--config /terraform-docs/src/.docs/.terraform.docs.yml # specify the config file

3. Manually replace the placeholders inside the readme.md with necessary values.

Manually Generated document

See the manually generated md file here.

4. Delete the contents of the .docs inside the src and commit just the readme.md file

The manual steps stated here are error-prone. Let us see how we can solve this using Gitlab CICD.

Automatic Document Generation

There is no change in the configuration steps. The .docs folder with the configuration yaml, header, and footer are all required. We make a change to the .gitlab-ci.yml file by adding a documentation job.

Current .gitlab-ci.yml
Document stage added before publish

Our .gitlab-ci.yml file contains a single job that pertains to releasing the module. To it, we add a stage called “document” and add two jobs

1. The auto-document job

First Job is called “auto-document” which runs terraform-docs on the src folder based on the settings provided in the “.docs/.terraform.docs.yml”

auto-document job

The steps inside the auto-document jobs are as follows:

  • Line 39: Pull An image that contains the curl tool installed.
  • Lines 40–44: Specify rules to determine when the job should be run. In our case, the auto-document job will only be run on feature, bugfix, and hotfix branches. On all the other branches, it is never run.
  • Lines 46–50: Next, we download the terraform-docs executable, and add the executable to the PATH env variable.
  • Lines 51–57: We set the terraform module name, platform, and Package Source from the various Gitlab Variables available to us at run time
  • Lines 60–61: We replace the placeholders inside the header and footer files in the .docs folder.
  • Lines 62–63: We copy the “.docs” folder to the “src ”folder and run the terraform-docs command. The generated document is then saved as an “artifact” making it available in the next job
auto-document job log

When the job runs successfully, the README.md file that is created will be used in the next job

2. The auto-commit job

The README.md file generated by the auto-documentation job is not yet accessible in the relevant branch. The “auto-commit” job commits the updated README.md file to make it accessible within the repository.

auto-commit job

The steps inside the auto-commit job are as follows.

  • Line 72–74: We select the git image to run the next set of commands. By specifying the entrypoint: [“”] we are telling the container NOT to run any command when the container starts. We will explicitly provide the commands required.
  • Line 75: We are telling the pipeline that the “auto-commit” job should only be run after the “auto-document” job has been successfully completed.
  • Lines 76–80: The rules for running the auto-commit job In this example, the job will only be executed for feature, bugfix, and hotfix branches. For all other branches, the job will not run.
    It is important to note that when using the “needs” attribute, the rules from the parent job (auto-document) must also be applied in the child job (auto-commit) to ensure the Gitlab CICD pipeline runs smoothly.
  • Lines 82–83: The two lines are used to configure the email and name of the user that will be associated with the commits made by the pipeline.
  • Lines 85–90: Here we commit just the README.md file to the “current” branch (specified in the $CI_COMMIT_REF_NAME) with the message “[doc-job] Updating README.md”. We then push the changes to the repo, thus making the updated README.md available in the branch.
auto-commit job log

Note: It is important to note that before running the pipeline, a variable named “MY_ACCESS_TOKEN ”must be defined in the “variables” section. This variable contains a personal access token, which must be generated before the pipeline is executed. See below.

Set variables in GitLab CICD
Adding a new variable
MY_ACCESS_TOKEN

Result

You can see the generated document here.

Someone asked me, how the “Inputs” and “Outputs” sections were generated.

The Input and Output section is populated based on the variables and outputs defined in the root module. It’s important to note that the variables and outputs of child modules are ignored.

Therefore, it is crucial to ensure that your variable descriptions are meaningful and informative. Additionally, you can use markdown format to format the description and make it more readable.

Variable with a detailed description

Conclusion

Documenting Terraform modules is an important aspect of maintaining the integrity and ease of use of your infrastructure. By creating a clear and detailed README.md file, you can provide valuable information to other users and contributors of the module, including an overview of the module’s purpose, usage instructions, and input variables. Additionally, by using automation tools such as GitLab CI/CD, you can easily ensure that the documentation stays up-to-date and accurate as changes are made to the module.

The goal of this article is to give a broad introduction to the topic of generating and automating documentation for Terraform modules. It is intended to serve as a foundation for further exploration and understanding, rather than a comprehensive guide.

--

--