Search code examples
terraformterraform-provider-awsterraform-provider-azureterraform-template-file

Reuse the configuration to create similar resources in Terraform


I have the below TF file, which will create a function - FirstFunction. This works perfectly.

resource "azurerm_function_app" "**firstfunction**" {
  name                = **var.firstfunctionname**
  location            = azurerm_resource_group.resourcegroupX.location
  resource_group_name = azurerm_resource_group.resourcegroupX.name
  app_service_plan_id = azurerm_app_service_plan.appserviceplan.id
  https_only          = "true"
  client_affinity_enabled = "true"
  
  app_settings = {   
    NS                     = azurerm_eventhub_namespace.eventhubns.name
    Hub                    = azurerm_eventhub.**firsteventhub**.name    
    propertyX       = "**firstproperty**"
    LogRef                       = "${azurerm_storage_account.store.primary_blob_endpoint}${azurerm_storage_container.**firstlogs**.name}"
 }
 }
 
 resource "azurerm_app_service_virtual_network_swift_connection" "**firstvnet**" {
  app_service_id = azurerm_function_app.**firstfunction**.id
  subnet_id      = azurerm_subnet.snet.id

}

In the file, see the section enclosed with ****, which need to be changed to create SecondFunction, ThirdFunction and so on ...

The way i have right now is to create multiple TF files , with the same code copied and change the sections enclosed in **.

I read through the module system but understood the limitation with the module system is that I cannot refer to the other components created in the same TF root module as shown below For e.g In the TF file, I refer to location as location = azurerm_resource_group.resourcegroupX.location If I do it as a module, the location should be refered to as location = var.location_name where location_name should be defined as a variable. I cannot refer to components created with the same root module.

Can you please suggest a solution where I can create multiple components based on the similar code ? Please note that, in the above example, Im creating 2 resources in a single TF file and both of them are related.


Solution

  • The simplest way is that use the count property in your resources. It can help you create multiple same resources in the same code.

    resource "azurerm_function_app" "myfunction" {
      count               = number_your_need     # how many resources you want to create 
      name                = "${var.firstfunctionname}-${count.index}" 
      location            = azurerm_resource_group.resourcegroupX.location
      resource_group_name = azurerm_resource_group.resourcegroupX.name
      app_service_plan_id = azurerm_app_service_plan.appserviceplan.id
      https_only          = "true"
      client_affinity_enabled = "true"
      
      app_settings = {   
        NS                     = azurerm_eventhub_namespace.eventhubns.name
        Hub                    = azurerm_eventhub.**firsteventhub**.name   
        propertyX       = "**firstproperty**"
        LogRef                       = "${azurerm_storage_account.store.primary_blob_endpoint}${azurerm_storage_container.**firstlogs**.name}"
       }
     }
     
     resource "azurerm_app_service_virtual_network_swift_connection" "**firstvnet**" {
      count          = number      # how many you need to create
      app_service_id = element(azurerm_function_app.myfunction[*].id, count.index)
      subnet_id      = azurerm_subnet.snet.id
    
    }
    

    The same solution for the azurerm_eventhub that you need to create. For example:

    resource "azurerm_eventhub" "myeventhub" {
      count  = number    # how many you need to create 
      name   = "${var.eventhub_name}-${count.index}"
      ...
    }
    

    Then you can refer it in the function app like this:

    app_settings = {   
        NS                     = azurerm_eventhub_namespace.eventhubns.name
        Hub                    = element(azurerm_eventhub.myeventhub[*].name, count.index)  
        propertyX       = "**firstproperty**"
        LogRef                       = "${azurerm_storage_account.store.primary_blob_endpoint}${azurerm_storage_container.**firstlogs**.name}"
     }
    

    So does all the section enclosed with ****.