Making Terraform module documenatation easier with the terraform-docs tool

Making Terraform module documenatation easier with the terraform-docs tool

When to write a module for Terraform

Well, if we read from the source at Hashicorp they state:

"In principle any combination of resources and other constructs can be factored out into a module, but over-using modules can make your overall Terraform configuration harder to understand and maintain, so we recommend moderation."

I can agree with this. However writing the code is not the hard part, the annoying part can be the documentation work. Luckily we can make good use of the terraform-docs tool which can help us with this and dramatically reduce the amount of time required to complete modules.

How to use the tool

We will demonstrate it by creating a module for Terraform with the AzureRM provider. If you have never done this you will learn today!

First we will create a folder that needs to follow a certain naming convention for it to be accepted.

First I will create my root folder mkdir -p terraform-modules/terraform-azurerm-network & cd into it.

I will create all the files and populate them with the required content. Our goal is to provision a basic virtual network, route table and network security group. It will be created and the route table and NSG should be associated to the subnet we are privisioning automatically.

$ tree terraform-azurerm-network/
.
├── README.md
├── .gitignore
├── LICENSE (MIT)
├── main.tf
├── variables.tf
├── outputs.tf
├── network.tf
├── rg.tf
├── nsg.tf
├── rt.tf

You can find the contents of each file in my repo here

In this module we will use a DATA block for the resource group which means we will use an existing RG. I will create one once we are ready to provision.

Now for the magic. I have not populated anything inside the README.md file I have focused only on writing terraform configuration. Let us automagically create the documentation, you can find install instructions for terraform-docs here

At my terminal I will enter the following command:

As you can see by running cat I can see that my README file is updated with all the required information needed.

Now I am ready to provision. I will create a repository in Github with the same name as the root folder, note that it must be public so that the Terraform registry can find it.

Select Public, not Private like I did here... I had to change it later!

And from the terminal I will push my local code

We also need to push a tag which I will for simplicitys sake we will do with the following commands in the terminal

git tag v1.0.0
git push origin tag v1.0.0

Publish the module

As long as you have an account you can head to this link HERE

And if you are authenticated properly you can now find your new module in the list, go ahead and publish it like I did here:

And there you go:

Let us test the module. Ideally you would have done this earlier locally if you were building something more complex but I was fairly confident that this would work (Sometimes famous last words).

In a new folder I will create a new main.tf with the following content:

You need only create the main.tf file, the other files here are automatically created when executing the deployment

To run I will authenticate to Azure and create my required resource group:

az login
az account set -s <subID>
az group create -n rg-prod-sc-network -l swedencentral

And to run my terraform code:

terraform init
terraform plan
terraform apply -auto-approve

Finally if all went well we can see our new resources in the Portal:

Association works

Improvements to be made

Now as you can see we have some issues still with this module

  • We forgot to set the name of the NSG to accept a variable, it was left hardcoded and therefor the NSG name became incorrect
  • We force the use of an existing RG, perhaps we want to make it possible for the enduser to chose?
  • We have made all variables mandatory, this is not very user friendly - what if we do not want to set a custom DNS server for example?
  • We could reduce the amount of variables required with smarter variable types

Probably more things to improve upon, this is the nice thing with small improvements here and there everyday. This is afterall just v1.0.0 so we can iterate on this.

The goal of this article was to showcase the usefulness of the terrform-docs tool - in the upcoming sections we will focus on how we can improve the module we have built already. I hope you will join me for that as well!

References

GitHub - terraform-docs/terraform-docs: Generate documentation from Terraform modules in various output formats
Generate documentation from Terraform modules in various output formats - terraform-docs/terraform-docs
Creating Modules | Terraform | HashiCorp Developer
Modules are containers for multiple resources that are used together in a configuration. Learn when to create modules and about module structure.

About me

About me
If you have landed on my page you will have already understood my passion for tech, but obviously there is more to life than that. Here I will try and outline a few of my other hobbies. Strength training I am a person who loves to move around and challenge