External terraform modules can speed up IAC deployments, promote code reuse, and let us do things more consistently. In this post, I will demonstrate 2 ways to use an external module.
Terraform can retrieve remote modules automatically. For example, to use the apigateway-v2 module, declare a module in your code and provide the source path and version. This will tell terraform to git clone the module.
module "apigateway-v2" {
source = "terraform-aws-modules/apigateway-v2/aws"
version = "3.1.0"
}
The source path can be a self-developed repo too. Terraform supports installation from multiple repo type. For example, use this to specify a git repo:
module "storage" {
source = "git::ssh://[email protected]/storage.git"
}
Another way is to use git submodule. It more or less does the same thing. Instead of letting terraform do the cloning and placing the source code inside .terraform in each root module, we can place the submodule at a location of choice.
In this example, I have a SharedModules directory which contains all of the shared modules. I can run these to add the apigateway-v2 module to the collection:
cd SharedModules/ApplicationIntegration
git submodule add https://github.com/terraform-aws-modules/terraform-aws-apigateway-v2.git
git switch --detach v3.1.0
git add ../.gitmodules terraform-aws-apigateway-v2
git commit -m 'NEW: added submodule ApplicationIntegration/terraform-aws-apigateway-v2'
git push
The first 3 commands adds the submodule and switch to version v3.1.0. The last 3 commands commits the submodule to my git repo.
Now let’s say the actual deployment happens in another machine. Use the following command to clone the SharedModules including all submodules.
git clone --recurse-submodules https://my.terraform.repo/git/xpk/SharedModules.git
If you already have a local git repo, and someone added a submodule on the remote repo, do this on your local repo to download the submodules
git submodule update --init --recursive # first time only
git pull --recurse-submodules
In your root module, reference the local filesystem path as the source
module "storage" {
source = "../SharedModules/terraform-aws-apigateway-v2"
}