skip to Main Content

I’m loading json from Azure KeyVault and convert with jsondecode().
While raw string is working, when I load the same string from KeyVault I cannot use it in dynamic Block.

Error: Invalid dynamic for_each value
Cannot use a tuple value in for_each. An iterable collection is required.

Working

resource "azurerm_monitor_action_group" "SIDevelopment" {
  name                = "Test"
  resource_group_name = "kv-test"
  short_name          = "Test"

  dynamic "email_receiver" {
    for_each = jsondecode("["[email protected]","[email protected]"]")
    content {
      name                    = email_receiver.value
      email_address           = email_receiver.value
      use_common_alert_schema = false
    }
  }
}

Not Working

data "azurerm_key_vault" "this" {
  name                = var.key_vault_name
  resource_group_name = var.resource_group_name
}

data "azurerm_key_vault_secret" "secret" {
  name         = var.secret_name
  key_vault_id = data.azurerm_key_vault.this.id
}

resource "azurerm_monitor_action_group" "SIDevelopment" {
  name                = "Test"
  resource_group_name = "kv-test"
  short_name          = "Test"

  dynamic "email_receiver" {
    for_each = jsondecode(data.azurerm_key_vault_secret.secret.value)
    content {
      name                    = email_receiver.value
      email_address           = email_receiver.value
      use_common_alert_schema = false
    }
  }
}

When I try to compare results they are looks equal

output "kv"{
  value = jsondecode(data.azurerm_key_vault_secret.secret.value)
  sensitive = true
}

output "string"{
  value = jsondecode("["[email protected]","[email protected]"]")
  sensitive = true
}

after read output as json

{
  "kv": {
    "sensitive": true,
    "type": [
      "tuple",
      [
        "string",
        "string"
      ]
    ],
    "value": [
      "[email protected]",
      "[email protected]"
    ]
  },
  "string": {
    "sensitive": true,
    "type": [
      "tuple",
      [
        "string",
        "string"
      ]
    ],
    "value": [
      "[email protected]",
      "[email protected]"
    ]
  }
}

I’ve try toset, tolist, etc.
And still can’t figure out why string from KeyVault behave differently.

2

Answers


  1. Chosen as BEST ANSWER

    It's was just a missing nonsensitive function

    for_each = jsondecode(nonsensitive(data.azurerm_key_vault_secret.secret.value))

    So to make it work it I've replace code to be like this

    resource "azurerm_monitor_action_group" "SIDevelopment" {
      name                = "Test"
      resource_group_name = "kv-test"
      short_name          = "Test"
    
      dynamic "email_receiver" {
        for_each = jsondecode(nonsensitive(data.azurerm_key_vault_secret.secret.value))
        content {
          name                    = email_receiver.value
          email_address           = email_receiver.value
          use_common_alert_schema = false
        }
      }
    

  2. I tried to create an email receiver in the Azure Monitor Action Group for each email address in the list stored in the secret present in the vault using count instead of dynamic foreach and I was able to provision the requirement successfully.

    It seems that your scenario does not support using for_each with an object (map) that is derived from a list. This is uncommon, as usually this conversion from a list to a map with indices as keys should be successful. However, there may be some particularities in your situation that trigger this problem.

    For this case I suggestcount is a better choice than dynamic foreach for your task of looping through a simple list of email addresses. count is easy to use for lists that have a fixed order and don’t require individual labels for each item.

    Before you configure anything, verify that the JSON data in the Azure Key Vault consists of a list of email addresses in this format: ["[email protected]", "[email protected]", ...].

    My demo terraform configuration:

    provider "azurerm" {
      features {}
    }
    
    variable "key_vault_name" {
      description = "The name of the key vault"
      type        = string
    }
    
    variable "resource_group_name" {
      description = "The name of the resource group"
      type        = string
    }
    
    variable "secret_name" {
      description = "The name of the secret in the key vault"
      type        = string
    }
    
    data "azurerm_key_vault" "this" {
      name                = var.key_vault_name
      resource_group_name = var.resource_group_name
    }
    
    data "azurerm_key_vault_secret" "secret" {
      name         = var.secret_name
      key_vault_id = data.azurerm_key_vault.this.id
    }
    
    resource "azurerm_monitor_action_group" "SIDevelopment" {
      name                = "Test"
      resource_group_name = "demorg-vk"
      short_name          = "Test"
    
    
      count = length(jsondecode(data.azurerm_key_vault_secret.secret.value))
    
      email_receiver {
        name                    = "emailReceiver-${count.index}"
        email_address           = jsondecode(data.azurerm_key_vault_secret.secret.value)[count.index]
        use_common_alert_schema = false
      }
    }
    
    
    
    output "kv" {
      value     = tolist(jsondecode(data.azurerm_key_vault_secret.secret.value))
      sensitive = true
    }
    
    output "string" {
      value     = jsondecode("["[email protected]","[email protected]"]")
      sensitive = true
    }
    

    Output:

    enter image description here

    enter image description here

    enter image description here

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search