Terraform Modules on Github
I’m learning Terraform and wanted to start developing modules. I need to do source control versioning and be able to use and test the module from anywhere. Fortunately Terraform has a nifty feature which allows you to configure your terraform code to pull these modules directly from a git repository. I’ll be sharing how I configured this under this guide.
What is a Terraform Module
Terraform Modules allows you to package up terraform code into logical reusable unit of work that you can share. Modules makes it easier to navigate, understand, and update your configuration by keeping related parts of your configuration together. It allows us to provide consistency and ensure best practices are applied across all of your configuration.
Module structure.
Typically this is how our module is structured.
README.md will contain documentation describing how to use your module in markdown format.
LICENSE will contain the license under which your module will be distributed. It will let people using it know the terms under which it has been made available. This is optional as Terraform doesn’t really use this.
main.tf will contain the main set of configuration for your module.
variables.tf will contain the variable definitions for your module. When your module is used by others, the variables will be configured as arguments in the module
block.
outputs.tf will contain the output definitions for your module. Module outputs are made available to the configuration using the module.
I created a sample module that provisions a simple S3 bucket. You can extract this locally and put it inside a modules
folder.
I also created our root terraform configuration code. Our main.tf uses the module as follows.
This example passes the bucket_name
and tags
arguments to the module, which provides values for the matching variables found in modules/terraform-aws-s3/variables.tf
.
In the sample module, we defined an output for the arn of the bucket. That value is available to out root module configuration. The contents of the outputs.tf
file in your root module directory is as follows:
See how we are referencing the module outputs under line 3.
Terraform must install the module before it can be used. This can be done by issuing terraform get
orterraform init
commands.
Now that our new module is installed and configured, let’s run terraform apply
to provision our bucket.
…
As you can see from the above, we have created a new s3 bucket using our custom Terraform module.
Sourcing your terraform modules in Github
Modules can either be loaded from the local filesystem, or a remote source. When working with Terraform modules you shouldn’t really be manually packaging and deploying them. Terraform supports a variety of remote sources, including the Terraform Registry, version control systems, HTTP URLs, and Terraform Cloud or Terraform Enterprise private module registries.
I wanted to use Github as my Terraform module repository.
Let’s push our module code into a new Github repo.
If we want to access an unsecured repo, then using HTTPS is most likely be the easiest solution to connect to our repo. For repositories that are secured, using an SSH key is the best solution rather than trying to work with credentials over HTTP.
For information on how to connect to github via SSH you can check out this guide: https://docs.github.com/en/authentication/connecting-to-github-with-ssh/
Source update
You need to amend your terraform configurations to source out modules from a git repo instead of a local folder. To do this, we need to change the source
field to reference a git url rather than a local folder path.
As you can see from the above, I also deleted the previous modules folder which holds the terraform-aws-s3 module. All we need to do now is to run terraform init
and that should download the module from our repo
and running terraform apply
should give us a new bucket.
Module Versions
Let’s say you are developing a new version of the module on a branch and you want to test it. If you want to use a specific version or tag then all you need to do is to amend the url used in your Terraform configurations to use the ref
attribute, here you can specify the branch or tag name.
Terraform btw expects you to have 1 git repo per module, if you don’t conform to this you’ll get an error Error: Failed to download module
with a further explanation fatal: Could not read from remote repository
.