×
Community Blog A Guide to Writing Terraform Modules

A Guide to Writing Terraform Modules

This post is a quick and easy guide to writing Terrafrom Modules.

By He Guimin, nicknamed Xiaozhu at Alibaba.

This tutorial is intended to be a guide on how you can write Terraform modules on Alibaba Cloud. In it, I will explain how to write a universal and standard module based on my own understanding of modules as a technical expert at Alibaba Cloud.

To get started, let's first discuss what exactly Modules are. In short, Modules are small, reusable Terraform configurations that let you manage a group of related resources as if they were a single resource. Modules make Terraform's template structure simpler and clearer while reducing the complexity of template writing and maintenance. For more information about why modules are used, check out post Modules That Make Terraform Easier to Use.

Creating a GitHub Repository for a Module

Currently, the modules that are officially registered on the Terraform Registry only support GitHub repositories. Therefore, before writing a template, you must first create a standard GitHub repository:

  1. The repository must be public.
  2. The repository must use the name format: terraform-<PROVIDER>-<NAME>. For example, the repository can be named terraform-alicloud-ecs-instance or terraform-alicloud-vpc.
  3. After creating the repository, you must add a description to it.

To better manage all Alibaba Cloud Terraform modules, we build all repositories under Terraform Alibaba Cloud Modules. If you need to create a new repository, contact the owner.

Writing a Module

After a repository is created for a module, fork this repository and clone it to the corresponding local machine. Next, start writing the module. Hashicorp has provided principles and norms for standard modules to follow. For more information, see standard-module-structure. This tutorial will build on this information.

1. Basic Principles

  • Each module should not contain too many resources. You need to include only the resources related to the same product as far as possible. This prevents the module from becoming complex, keeping it easy to maintain and read.
  • Different resources of one single product should be placed in different child modules, and then all child resources are organized in main.tf at the outermost layer. For example, two resources are defined in module slb, including the Server Load Balancer (SLB) instance and SLB attachment. These two child resources are defined in modules/slb and modules/slb_attachment, respectively. Then, the two child modules are combined in main.tf at the outermost layer into a new module.
  • Each module should be unitized as much as possible so that it can be freely added or deleted during actual use without affecting other resources. That is, a module should describe one or two things as much as possible, such as creating an SLB instance and attaching a group of Elastic Compute Service (ECS) instances to this SLB instance that is used to load balance these ECS instances. The listener configuration of this SLB instance should be placed in a separate module. On the one hand, listeners are complex and involve four protocols. On the other hand, most configurations of listeners that use the same protocol, apart from listening ports, are the same. These same configurations can be reused in other resource templates through a separate module.
  • In the template writing process, a lot of TF syntax is required. For more information, see Configuration Syntax and Interpolation Syntax.

2. main.tf

  • Each module must contain a main.tf file to store resources and data sources. The parameters of resources and data sources cannot be hard-coded but must be referenced by variables.
  • For standardization, each resource and data source is named with a keyword or keyword prefix, such as this or default. Keywords or keyword prefixes such as foo and test should be avoided.
  • To better understand how many times a module is referenced by others, Alibaba Cloud Provider supports tagging each module by declaring the configuration_source field in provider in main.tf. The following format is used:
provider "alicloud" {
...
configuration_source = "terraform-alicloud-modules/demo"  // This should be replaced by the specified owner and module name
}

3. variables.tf

  • A corresponding description of this parameter must be added for each variable. This parameter will eventually appear on the official Terraform Registry website.
  • You can set a default value for non-relational parameters, such as name and description.
  • The types of complex variables, such as list and map, must be explicitly declared.
  • Variables of child resources must be displayed in a list in README.

4. outputs.tf

  • The output function of a module is referenced by other templates and modules. Therefore, each module outputs some important information, such as the resource ID and resource name.
  • Variables of repeated resources must be output in a list. For example, if multiple instance resources are created in the ecs-instance module, the IDs of these resources should be output to the instance_ids list variable.
  • Similar to those variables, the output variables of child resources must be displayed in a list in README.

5. README

  • Describes what the current module is used for and what resources and data sources are involved.
  • Adds Usage to specify how to use this module. The source format of the module is source = "<Repo Organization>/<NAME>/alicloud", such as source = "terraform-alicloud-modules/slb-listener/alicloud".
  • Adds the input and output parameters exposed by the module to help developers better use the module.
  • For more information, reference other modules.

To help you better write modules, Alibaba Cloud provides a Module Demo for your reference.

Test and Publish a Module

After you write a template, use Terratest to test the current module. When the test is successful, submit the corresponding code to GitHub.

To submit your module to Terraform Alibaba Cloud Modules, you can leave a message below or send an email to heguimin36@163.com. After the application is approved, I will create a new repository for you. Every developer who contributes a module will have the opportunity to become a member of Terraform Alibaba Cloud Modules.

A Terraform module implements version control by using repository releases. After its code is confirmed to be correct, including its README, a new release is published. Then, you can register and publish this module on the Terraform Registry. For more information, see Publishing Modules.

The views expressed herein are for reference only and don't necessarily represent the official views of Alibaba Cloud.

0 0 0
Share on

Alibaba Clouder

2,190 posts | 506 followers

You may also like

Comments

Alibaba Clouder

2,190 posts | 506 followers

Related Products