Virtual Geek

Tales from real IT system administrators world and non-production environment

Writing and Using Terraform modules

This is a small example of Terraform module how to write and use it. A Terraform module is a folder/container for multiple resources that are used together. Every Terraform configuration has at least one module, known as its root module, which consists of the resources defined in the terraform .tf files in the main working directory.

Download Terraform module example zip here or you can download tf zip bundle from

Here are my files and folder hierarchy structure of the Hashicorp Terraform modules. In this example I will be creating a demo Resource Group on Microsoft Azure cloud using this Terraform module template. There are total 3 tf files.

Terraform Modules reusable code hcl hashicorp powershell cmd folder tree map files azure provider azurerm arm portal.png

If you look inside the modules folder, I have create Resource_Group directory and under I have file, where I have mentioned Terraform azure resource azurerm_resource_group to create a new Resource Group if not exist. in the file all the variables for files are mentioned (Resource group name, location, tags). This is regular simple terraform tf template, you can copy and deploy easily.

Files name in the modules folder must be matching, and, Additionally you can add file.

Terraform Using one module variable in another module

#Location:  .\Modules\Resource_Group

#Resource group module file
resource "azurerm_resource_group" "example_rg" {
    name     = var.resource_group_name
    location = var.location
    tags     = var.tags

#Resource group module file
variable "resource_group_name" {
    description = "The name of the module demo resource group in which the resources will be created"
    type = string
    default     = "example_module_rg"

variable "location" {
    description = "The location where module demo resource group will be created"
    type = string
    default     = "East Us"

variable "tags" {
    description = "A map of the tags to use for the module demo resources that are deployed"
    type        = map(string)
    default = {
        environment = "Example"
        Owner = ""

Screenshot location of the module Resource Group and file.

terraform example modules resource group create azurerm_resource_group location tags map string default description id automation devops plugins.png

Below main file is kept on the root folder as per the tree shown earlier. In this file I am mentioning provider and module with source path to modules and mentioned the resource group information.

#Root file

# Configure the Microsoft Azure Provider
provider "azurerm" {
  features {}

module "Demo_Azure_Module_RG" {
    source = "./Modules/Resource_Group"
    resource_group_name = "demo_RG"
    location = "West US"
    tags = {
        environment = "DemoRG"
        Owner = ""

Root file content screenshot.

terraform microsoft azure provider azurerm features source modules resource group location tags tfvar devops automation iac infrastructure as a code.png

To start deployment I will login and authenticate to Microsoft Azure with AzureCLI command: az login.

Create an Azure virtual machine scale set and load balancer using Terraform

Microsoft Powershell azurecli az login oauth2 authorize tenant subscription terraform resusable module variable tf file tfvars provider azurerm azure.png

az login

The default web browser has been opened at Please continue the login in the web browser. If no web browser is available or if the web browser fails to open, use device code flow with `az login --use-device-code`.
You have logged in. Now let us find all the subscriptions to which you have access...
The following tenants require Multi-Factor Authentication (MFA). Use 'az login --tenant TENANT_ID' to explicitly login to a 
a59fb284-02ec-4a72-a79a-4a6b6105ab9d ''
    "cloudName": "AzureCloud",
    "homeTenantId": "3b80xxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
    "id": "9e22xxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
    "isDefault": true,
    "managedByTenants": [],
    "name": "Sponsership-by-Microsoft",
    "state": "Enabled",
    "tenantId": "3b80xxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
    "user": {
      "name": "[email protected]",
      "type": "user"

Once Azure log is successful, Change to the folder where Terraform modules with root files are kept. Initialize module with command terraform init. It will download and install all the prerequite azure providers. Locks will be created.

Azure Terraform fixed Availibility Zones on Virtual Machine Scale Set

Terraform hashicorp modules example azure module azurerm provider plugin tf init terraform init initializition successful variable tfvar output.png

PS D:\Projects> cd D:\Projects\Terraform\Demo\Terraform_Module_Example

PS D:\Projects\Terraform\Demo\Terraform_Module_Example> terraform init

Initializing modules...
- Demo_Azure_Module in Modules\Resource_Group   

Initializing the backend...

Initializing provider plugins...
- Finding latest version of hashicorp/azurerm...
- Installing hashicorp/azurerm v2.68.0...
- Installed hashicorp/azurerm v2.68.0 (signed by HashiCorp)

Terraform has created a lock file .terraform.lock.hcl to record the provider
selections it made above. Include this file in your version control repository
so that Terraform can guarantee to make the same selections by default when
you run "terraform init" in the future.

Terraform has been successfully initialized!

You may now begin working with Terraform. Try running "terraform plan" to see
any changes that are required for your infrastructure. All Terraform commands
should now work.

If you ever set or change modules or backend configuration for Terraform,
rerun this command to reinitialize your working directory. If you forget, other
commands will detect it and remind you to do so if necessary.

By running command terraform plan, it will show and indicate what actions will be performed. In may case it will create resource group on azure with the information mentioned on the root file.

PS D:\Projects\Terraform\Demo\Terraform_Module_Example> terraform plan

Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the     
following symbols:
  + create

Terraform will perform the following actions:

  # module.Demo_Azure_Module.azurerm_resource_group.example_rg will be created
  + resource "azurerm_resource_group" "example_rg" {
      + id       = (known after apply)
      + location = "westus"
      + name     = "demo_RG"
      + tags     = {
          + "Owner"       = ""
          + "environment" = "Demo"

Plan: 1 to add, 0 to change, 0 to destroy.


Note: You didn't use the -out option to save this plan, so Terraform can't guarantee to take exactly these actions if you   
run "terraform apply" now.

Terrform by Hashicorp automation devops terraform plan create module example variable tf tfvar azure provider azurerm microsoft azure portal destroy devops add 1 change apply changes execution plan.png

There are no errors in the plan, I will apply the configuration with terraform apply -auto-approve. Creation completed successfully with module.

Terraform hashicorp create terraform apply -auto-approve azurerm azure provider variable data module resources azurerm_resource_group change destroy devops automation tags location id.png

terraform apply -auto-approve

Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the
following symbols:
  + create

Terraform will perform the following actions:

  # module.Demo_Azure_Module_RG.azurerm_resource_group.example_rg will be created
  + resource "azurerm_resource_group" "example_rg" {
      + id       = (known after apply)
      + location = "westus"
      + name     = "demo_RG"
      + tags     = {
          + "Owner"       = ""
          + "environment" = "DemoRG"

Plan: 1 to add, 0 to change, 0 to destroy.
module.Demo_Azure_Module_RG.azurerm_resource_group.example_rg: Creating...
module.Demo_Azure_Module_RG.azurerm_resource_group.example_rg: Creation complete after 4s [id=/subscriptions/9e22xxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/demo_RG]

Apply complete! Resources: 1 added, 0 changed, 0 destroyed.

Useful Articles
Create an Azure App registrations in Azure Active Directory using PowerShell & AzureCLI
Get started and configure with certificate-based authentication in Azure
Create a Virtual machine on Microsoft Azure
PowerShell List All Azure Resverations
Powershell get the list of Azure Reservations Virtual Machines instances
Get the list Azure Reservation Catalog with PowerShell and AzureCLI
Azure automation account DSC for On-Premise Virtual Machine on boarding
Azure Powershell : Operation returned an invalid status code 'BadRequest'
Get Azure virtual machine backup reports using Powershell

Go Back


Blog Search

Page Views


Follow me on Blogarama