Terraform: How to variablize a block/set for dynamic use case?

Viewed 1947

I have created a base folder for diagnostic setting.

Directory structure:

main_repo/<base_folder>/monitor/main.tf

data {} #data block for resource_id

resource "azurerm_monitor_diagnostic_setting" "example" {
  name               = var.name
  target_resource_id = data.resource_id

  log {
    category = "AuditEvent"
    enabled  = var.enabled

    retention_policy {
      days = 0
      enabled = false
    }
  }

  log {
    category = "InsightLogs"
    enabled = var.enabled

    retention_policy {
      days = 0
      enabled = false
    }
  }
}

main_repo/<base_folder>/monitor/variables.tf

variable "enabled" {
    type = bool
    default  = false
}

variable "name" {
    type = string  
}

Now I am trying to use the content of this base folder in some environment like this:

main_repo/environment/main.tf:

module "resource1"{
   source = "../base_folder/monitor"
   name = var.name
   target_resource_id = var.someid
   log {
       // I want to enable/disable the module's block from environment with default values as specified in module
       category = "Audit Event"
       enabled = true
   }
}

main_repo/environment/variables.tf:

variable "someid" {
    type = string
}

variable "name" {
    type = string
    default = "default"
}

So, I am trying to change the value for say "Audit Event" with true instead of default false and it should pick the rest value for this block as well as in "InsightLogs" should be populated with false. I am able to make variable as dynamic, but this block/set of logs I am not able to make it dynamic. Also, the block retention_policy I wasn't able to make it dynamic (like change values inside that only for a particular case). Can someone please help with this ?

More description: This environments folder eventually runs when applying terraform plan. So when I am trying to reference a block of log from base folder to my environments folder, it says logs is not expected. I would like to have a customized log block from the base folder for some components and rest can be same as we are referencing using source "base_folder"

1 Answers

You are using var.enabled for both blocks. Variable can - obviously - have only one value at a time. What you perhaps want is a dynamic block:

resource "azurerm_monitor_diagnostic_setting" "example" {
  name               = var.name
  target_resource_id = data.resource_id

  dynamic "log" {
    for_each = var.log_settings
    content {
      category = log.value["category"]
      enabled = log.value["enabled"]
      retention_policy {
        days = log.value["retention_days"]
        enabled = log.value["retention_enabled"]
      }
    }
  }
}
variable "log" {
  type = list(any)
}

Now you can pass following values to your module:

module "resource1"{
   source = "../base_folder/monitor"
   name = var.name
   target_resource_id = var.someid
   log = [
     {
       name = "AuditEvent"
       enabled = true
       retention_enabled = false
       retention_days = 0
     },
     {
       name = "InsightLogs"
       enabled = true
       retention_enabled = false
       retention_days = 0
     },

   ]
}

I haven`t tested above code, so maybe it contains syntax errors/bugs/typos. Please refer to documentation for your specific terraform version, eg. https://www.terraform.io/docs/language/expressions/dynamic-blocks.html

Related