skip to Main Content

I am trying to use below code

data "azurerm_resource_group" "rg_tst_na" {
  name     = "test1"
}

data "azurerm_resource_group" "rg_dev_na" {
  name     = "test2"
}

resource "azurerm_role_assignment" "test_role_assign" {
  for_each = var.test_role_assignment
  principal_id         = azurerm_user_assigned_identity.test_setup["${each.key}_${each.value}"].principal_id # this is created as separate resource using a for_each loop this resource is validate by terraform apply
  role_definition_name = "Network Contributor"          
  scope                = data.azurerm_resource_group."${each.key}_${each.value}".id
}

variable "var.test_role_assignment" {
  type = map(string)
  default={
    "na" = "dev",
    "na" = "tst",    
  }
}

I am getting error that scope cannot be read during terraform plan, how can I variablize the input of resource attribute

  scope = data.azurerm_resource_group.rg_"${each.value}"_"${each.key}".id

Is this possible?

Can I use variable in the value of scope as resource attribute but variablized? Is this violation of terraform rules

2

Answers


  1. There are a couple of things to note:

    1. variable "var.test_role_assignment" should be only variable "test_role_assignment"
    2. The other part you are asking about, scope, that’s not how terraform works and cannot be done.

    However, you could use the same for_each for the data source, and reference that in the resource block. Something along the lines should work:

    data "azurerm_resource_group" "rg_na" {
     for_each = var.test_role_assignment
     name     = each.value
    }
    
    resource "azurerm_role_assignment" "test_role_assign" {
      for_each             = var.test_role_assignment
      principal_id         = azurerm_user_assigned_identity.test_setup["${each.key}_${each.value}"].principal_id # this is created as separate resource using a for_each loop this 
    resource is validate by terraform apply
      role_definition_name = "Network Contributor"          
      scope                = data.azurerm_resource_group.rg_na[each.key].id
    }
    
    variable "test_role_assignment" {
      type    = map(string)
      default = {
        "na" = "dev",
        "na" = "tst",    
      }
    }
    
    Login or Signup to reply.
  2. Terraform uses static analysis of references to understand the dependencies between resources, and so a reference from one resource to another must be written as a static reference; dynamic expression evaluation is not allowed.

    However, you can achieve a similar effect by defining a local value that acts as a lookup table for your resource objects:

    locals {
      resource_groups = {
        tst_na = azurerm_resource_group.rg_tst_na
        dev_na = azurerm_resource_group.rg_dev_na
      }
    }
    

    In an expression like local.resource_groups.tst_na, only the local.resource_groups part is important for Terraform’s dependency analysis: Terraform will conclude that local.resource_groups depends on both azurerm_resource_group.rg_tst_na and azurerm_resource_group.rg_dev_na, and so therefore anything that refers to local.resource_groups indirectly depends on both of those resources, regardless of what other attribute accesses might appear after that reference.

    You can therefore construct the attribute lookup for that object using arbitrary expressions:

    local.resource_groups["${each.value}_${each_key}"]
    

    …and the result would be the same object as if you’d referred to the corresponding resource directly.

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