Menu

Virtual Geek

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

Terraform foreach module output to show only required results

In my previous articles I was testing my variable information to see output, one thing I observed in the output was showing all the variable content information in the output. 

Terraform testing local variables and output csv file without resource Part 1
Terraform testing variable map object values without resource configuration part 2

I wanted only the selected rg_name information to be shown in output as below.

Terraform Microsoft Azure resource group storage account changes module output only specified item foreach for example.png

To show the selected information, here is my complete terraform configuration module, check the output I am using name attributes in the output with foreach loop to pass on information.

./Modules/Resource_Group/main.tf
resource "azurerm_resource_group" "example_rg" {
  for_each = {
    for key, rg in var.resource_info : rg.rg_name => rg
  }
  name     = each.value.rg_name
  tags     = each.value.tags
  location = var.location_info.location
}

locals {
  allSA = flatten([
    for rgkey, rg in var.resource_info : [
      for storagekey, storage in coalesce(rg.storage_accounts, {}) : {
        name                     = storage.name
        resource_group_name      = rg.rg_name
        account_tier             = storage.account_tier
        account_replication_type = storage.account_replication_type
      }
    ]
  ])
}

# locals {
#   allSA = coalesce(flatten([ 
#     for rgkey, rg in var.resource_info : try([
#       for storage in rg.storage_accounts : {
#         name                     = storage.name
#         resource_group_name      = rg.rg_name
#         account_tier             = storage.account_tier
#         account_replication_type = storage.account_replication_type
#       } #for storage
#     ], []) #for rg try block
#   ]), null) #allSA = coalesce
# } #locals

resource "azurerm_storage_account" "example_sa_name" {
  count = length(local.allSA)
  name                     = local.allSA[count.index].name
  resource_group_name      = local.allSA[count.index].resource_group_name
  location                 = "West US"
  account_tier             = local.allSA[count.index].account_tier
  account_replication_type = local.allSA[count.index].account_replication_type
  tags = {
    environment = "Dev"
    project     = "Terraform"
  }
  depends_on = [azurerm_resource_group.example_rg]
}

./Modules/Resource_Group/variable.tf
variable "location_info" {
  description = "The name of the module demo resource group in which the resources will be created"
  type = object({
    location = string
    #otheroption = string
  })
}

variable "resource_info" {
  type = map(object({
    rg_name = string
    tags = object({
      environment = string
      Owner       = string
    })
    storage_accounts = optional(map(object({
      name                     = string
      account_tier             = string
      account_replication_type = string
    })), null)
  }))
}

./Modules/Resource_Group/output.tf
# output "rg_name" {
#   value = [for s in var.rg_info : s.name]
# }

# output "location_name" {
#   value = var.location_info.location
# }

# output "rg_name" {
#   value = azurerm_resource_group.example_rg[*]
# }

output "rg_name" {
  description = "Show names of all storage account"
  value = { for rg_key, rg_value in azurerm_resource_group.example_rg : rg_key => rg_value.name }
}

In the module output, I am using rg_name to show the information on the console, once I plan or apply the configuration.

./sa.tf
# Configure the Microsoft Azure Provider
provider "azurerm" {
  features {}
}
module "Demo_Azure_Module_RG" {
  source = "./Modules/Resource_Group"
  location_info = {
    location = "West US"
  }
  resource_info = {
    rg1 = {
      rg_name = "demo_RG1"
      tags = {
        environment = "DemoRG1"
        Owner       = "http://vcloud-lab.com"
      } #tags
      storage_accounts = {
        sa1 = {
          name                     = "vcloudlab0001"
          account_tier             = "Standard"
          account_replication_type = "ZRS"
        } #sa1
        sa2 = {
          name                     = "vcloudlab0002"
          account_tier             = "Standard"
          account_replication_type = "ZRS"
        } #sa2
      }   #storage_accounts
    }     #rg1
    rg2 = {
      rg_name = "demo_RG2"
      tags = {
        environment = "DemoRG2"
        Owner       = "http://vcloud-lab.com"
      } #tags
    }   #rg2
  }     #resource_info
}       #module Demo_Azure_Module_RG

./output.tf
# output "rg_name" {
#   value = [for s in var.rg_info : s.name]
# }

# output "location_name" {
#   value = var.location_info.location
# }

output "rg_name" {
  value = module.Demo_Azure_Module_RG.rg_name #.rg_name[0].demo_RG1.id
}

You can download this script Terraform module output results here or it is also available on github.com. Below is the output on the screen.

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_RG.azurerm_resource_group.example_rg["demo_RG1"] will be created
  + resource "azurerm_resource_group" "example_rg" {
      + id       = (known after apply)
      + location = "westus"
      + name     = "demo_RG1"
      + tags     = {
          + "Owner"       = "http://vcloud-lab.com"
          + "environment" = "DemoRG1"
        }
    }

  # module.Demo_Azure_Module_RG.azurerm_resource_group.example_rg["demo_RG2"] will be created
  + resource "azurerm_resource_group" "example_rg" {
      + id       = (known after apply)
      + location = "westus"
      + name     = "demo_RG2"
      + tags     = {
          + "Owner"       = "http://vcloud-lab.com"
          + "environment" = "DemoRG2"
        }
    }

  # module.Demo_Azure_Module_RG.azurerm_storage_account.example_sa_name[0] will be created
  + resource "azurerm_storage_account" "example_sa_name" {
      + access_tier                       = (known after apply)
      + account_kind                      = "StorageV2"
      + account_replication_type          = "ZRS"
      + account_tier                      = "Standard"
      + allow_nested_items_to_be_public   = true
      + cross_tenant_replication_enabled  = true
      + default_to_oauth_authentication   = false
      + enable_https_traffic_only         = true
      + id                                = (known after apply)
      + infrastructure_encryption_enabled = false
      + is_hns_enabled                    = false
      + large_file_share_enabled          = (known after apply)
      + location                          = "westus"
      + min_tls_version                   = "TLS1_2"
      + name                              = "vcloudlab0001"
      + nfsv3_enabled                     = false
      + primary_access_key                = (sensitive value)
      + primary_blob_connection_string    = (sensitive value)
      + primary_blob_endpoint             = (known after apply)
      + primary_blob_host                 = (known after apply)
      + primary_connection_string         = (sensitive value)
      + primary_dfs_endpoint              = (known after apply)
      + primary_dfs_host                  = (known after apply)
      + primary_file_endpoint             = (known after apply)
      + primary_file_host                 = (known after apply)
      + primary_location                  = (known after apply)
      + primary_queue_endpoint            = (known after apply)
      + primary_queue_host                = (known after apply)
      + primary_table_endpoint            = (known after apply)
      + primary_table_host                = (known after apply)
      + primary_web_endpoint              = (known after apply)
      + primary_web_host                  = (known after apply)
      + public_network_access_enabled     = true
      + queue_encryption_key_type         = "Service"
      + resource_group_name               = "demo_RG1"
      + secondary_access_key              = (sensitive value)
      + secondary_blob_connection_string  = (sensitive value)
      + secondary_blob_endpoint           = (known after apply)
      + secondary_blob_host               = (known after apply)
      + secondary_connection_string       = (sensitive value)
      + secondary_dfs_endpoint            = (known after apply)
      + secondary_dfs_host                = (known after apply)
      + secondary_file_endpoint           = (known after apply)
      + secondary_file_host               = (known after apply)
      + secondary_location                = (known after apply)
      + secondary_queue_endpoint          = (known after apply)
      + secondary_queue_host              = (known after apply)
      + secondary_table_endpoint          = (known after apply)
      + secondary_table_host              = (known after apply)
      + secondary_web_endpoint            = (known after apply)
      + secondary_web_host                = (known after apply)
      + sftp_enabled                      = false
      + shared_access_key_enabled         = true
      + table_encryption_key_type         = "Service"
      + tags                              = {
          + "environment" = "Dev"
          + "project"     = "Terraform"
        }
    }

  # module.Demo_Azure_Module_RG.azurerm_storage_account.example_sa_name[1] will be created
  + resource "azurerm_storage_account" "example_sa_name" {
      + access_tier                       = (known after apply)
      + account_kind                      = "StorageV2"
      + account_replication_type          = "ZRS"
      + account_tier                      = "Standard"
      + allow_nested_items_to_be_public   = true
      + cross_tenant_replication_enabled  = true
      + default_to_oauth_authentication   = false
      + enable_https_traffic_only         = true
      + id                                = (known after apply)
      + infrastructure_encryption_enabled = false
      + is_hns_enabled                    = false
      + large_file_share_enabled          = (known after apply)
      + location                          = "westus"
      + min_tls_version                   = "TLS1_2"
      + name                              = "vcloudlab0002"
      + nfsv3_enabled                     = false
      + primary_access_key                = (sensitive value)
      + primary_blob_connection_string    = (sensitive value)
      + primary_blob_endpoint             = (known after apply)
      + primary_blob_host                 = (known after apply)
      + primary_connection_string         = (sensitive value)
      + primary_dfs_endpoint              = (known after apply)
      + primary_dfs_host                  = (known after apply)
      + primary_file_endpoint             = (known after apply)
      + primary_file_host                 = (known after apply)
      + primary_location                  = (known after apply)
      + primary_queue_endpoint            = (known after apply)
      + primary_queue_host                = (known after apply)
      + primary_table_endpoint            = (known after apply)
      + primary_table_host                = (known after apply)
      + primary_web_endpoint              = (known after apply)
      + primary_web_host                  = (known after apply)
      + public_network_access_enabled     = true
      + queue_encryption_key_type         = "Service"
      + resource_group_name               = "demo_RG1"
      + secondary_access_key              = (sensitive value)
      + secondary_blob_connection_string  = (sensitive value)
      + secondary_blob_endpoint           = (known after apply)
      + secondary_blob_host               = (known after apply)
      + secondary_connection_string       = (sensitive value)
      + secondary_dfs_endpoint            = (known after apply)
      + secondary_dfs_host                = (known after apply)
      + secondary_file_endpoint           = (known after apply)
      + secondary_file_host               = (known after apply)
      + secondary_location                = (known after apply)
      + secondary_queue_endpoint          = (known after apply)
      + secondary_queue_host              = (known after apply)
      + secondary_table_endpoint          = (known after apply)
      + secondary_table_host              = (known after apply)
      + secondary_web_endpoint            = (known after apply)
      + secondary_web_host                = (known after apply)
      + sftp_enabled                      = false
      + shared_access_key_enabled         = true
      + table_encryption_key_type         = "Service"
      + tags                              = {
          + "environment" = "Dev"
          + "project"     = "Terraform"
        }
    }

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

Changes to Outputs:
  + rg_name = {
      + demo_RG1 = "demo_RG1"
      + demo_RG2 = "demo_RG2"
    }

────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── 

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.

Useful Articles
Hashicorp Terraform map and object inside module and variable example
Terraform one module deploy null or multiple resources based on input
Terraform A reference to a resource type must be followed by at least one attribute access, specifying the resource name
Create an Azure virtual machine scale set and load balancer using Terraform
Azure Terraform fixed Availibility Zones on Virtual Machine Scale Set
Writing and Using Terraform modules
Terraform Using one module variable in another module
Hashicorp Terraform dynamic block with example
Terraform for_each loop on map example
Terraform for_each loop on resource example
Terraform manage similar resources with for_each loop inside modules
Importing existing resources into Terraform - Step by Step
Importing already created module Infrastructure into Terraform and update state file
Conditionally create resources in Terraform

Go Back

Comment

Blog Search

Page Views

12278877

Follow me on Blogarama