A module is bunch of files or a file with input and output variables defined, which can be reused to create terraform resources. It is just like any other terraform configuration which runs independently.
Every Terraform configuration must have at least one module, which is called root module. So, a root module consist of your terraform configuration files in your working directory.
You can call several child modules in your working directory. A module which calls other module is know as calling module. An example could be - you have called a module via root module (can be known as calling module as well in this case).
Module Block
A module can be called using below syntax.
module "vpc" {
source = ""
...
}
1. The "source" argument is mandatory for all the modules. It could be a local path or remote location from where terraform will download it during initialisation.
2. "version" argument is supported only for modules installed from a module registry, such as the public Terraform Registry or Terraform Cloud's private module registry. Other module sources can provide their own versioning mechanisms within the source string itself, or might not support versions at all.
3. We can also pass aliased provider as argument. If not specified, the child module inherits all of the default (un-aliased) provider configurations from the calling module.
4. Other arguments are basically the input variables defined in the module.
Note
In addition to above points, Terraform module block supports count, for_each and depends_on as well.
After adding, removing, or modifying module blocks, you must re-run "terraform init" to allow Terraform the opportunity to adjust the installed modules. By default this command will not upgrade an already-installed module; use the "-upgrade" option to instead upgrade to the newest available version.
Module Sources
There are many sources available for terraform modules. Few of them are -
1. Local path
A local path must begin with either ./ or ../ to indicate that a local path is intended, to distinguish from a module registry address.
They don't need to installed as files are already on local disks. Local modules can just be used directly. Their source code is automatically updated if the parent module is upgraded.
module "vpc" {
source = "./modules/network"
...
}
2. Terraform Registry
A module registry is the native way of distributing Terraform modules using a Terraform-specific protocol that has full support for module versioning.
Terraform Registry is an index of modules shared publicly. You can also use a private registry, either via the built-in feature from Terraform Cloud, or by running a custom service that implements the module registry protocol.
Terraform registry module can be reference in the source address as -
Private registry modules: <HOSTNAME>/<NAMESPACE>/<NAME>/<PROVIDER>
module "consul" {
source = "hashicorp/consul/aws"
version = "0.1.0"
}
Note: Registry at "registry.terraform.io" hosts public modules and "app.terraform.io" hosts private terraform modules, if you're using terraform cloud.
3. GitHub
Terraform will recognise un-prefixed github.com URLs and interpret them automatically as Git repository sources.
module "resource_group" {
source = "github.com/myorg/tf-azure-rg.git"
}
While executing "terraform init", Terraform installs modules from Git repositories by running git clone, and so it will use any local Git configuration set on your system, including credentials. To access a non-public Git repository, must configure Git with suitable credentials for that repository.
Use sources as below -
To clone over SSH: "git@github.com:hashicorp/example.git"
Note: By default, Terraform will clone and use the default branch (referenced by HEAD) in the selected repository. You can override this using the ref argument (a different branch can be selected or a tag can be selected) as mentioned below -
"github.com/myorg/tf-azure-rg?ref=v1.2.0"
4. Generic Git Repository
Arbitrary Git repositories can be used by prefixing the address with the special "git::" prefix. After this prefix, any valid Git URL can be specified to select one of the protocols supported by Git.
Use syntaxes below for HTTPS and SSH -
# Example 01:module "vpc" { source = "git::https://example.com/vpc.git"
}
# Example 02:
module "storage" {
source = "git::ssh://username@example.com/storage.git"
}