terraform dynamic block for_each construction

1.3k views Asked by At

Newbie question.

This is my variable file

 instances = ["instance1", "instance2"]

cors_rules = {
  instance1 = {
    origin       = ["https://instance.com", "http://localhost:4200"],
  },
  instance2 = {
    origin        = [https://instance2.com"", "http://localhost:4200"],
  }

}

This is my resource file

resource "azurerm_storage_account" "storage-account" {
  count                    = length(var.instances)
  name                     = "${var.storageAccount.name}${var.instances[count.index]}"
  location                 = var.location
  resource_group_name      = var.resource_name
  account_tier             = "Standard"
  account_replication_type = "LRS"


 blob_properties {
    dynamic "cors_rule" {
        for_each = need to construct 
  }
      content {
        allowed_origins    = 
        allowed_methods    = ["DELETE", "GET", "POST", "OPTIONS", "PUT", "PATCH"]
        allowed_headers    = ["*"]
        exposed_headers    = ["*"]
        max_age_in_seconds = 200
      }
    }
  }
}

Current i am having two instances. I want to add allowed_origins ["https://instance.com", "http://localhost:4200"] in one instance and [https://instance2.com"", "http://localhost:4200"] in second instance. can you help me with constructing a for_each inside dynamic block?

1

There are 1 answers

0
peytoncas On BEST ANSWER

You don't need a dynamic cors_rule block in this case, because the azurerm_storage_account is configured to accept a list. I would use the cors_rule object as a map so that you can look up the rules by their name. This would allow you to dynamically fetch the cors block based on a for_each of the azurerm_storage_account. I'll include an example below.

 instances = ["instance1", "instance2"]

cors_rules = {
  instance1 = {
    origin       = ["https://instance.com", "http://localhost:4200"],
  },
  instance2 = {
    origin        = [https://instance2.com"", "http://localhost:4200"],
  }

}

resource "azurerm_storage_account" "storage-account" {
  for_each                 = var.instances
  name                     = "${var.storageAccount.name}${each.value}"
  location                 = var.location
  resource_group_name      = var.resource_name
  account_tier             = "Standard"
  account_replication_type = "LRS"


 blob_properties {
      cors_rule {
        content {
            allowed_origins    = var.cors_rules[each.value]
            allowed_methods    = ["DELETE", "GET", "POST", "OPTIONS", "PUT", "PATCH"]
            allowed_headers    = ["*"]
            exposed_headers    = ["*"]
            max_age_in_seconds = 200
        }
      }
    }
  }
}

You could also merge the two variables, and simply for_each off the objects. This is a better approach anyways because Terraform will index off the map key name instead of list index which can change when you add/remove values from the list.

instances = {
   instance1 = {
    origin  = ["https://instance.com", "http://localhost:4200"]
   },
  instance2 = {
    origin  = [https://instance2.com"", "http://localhost:4200"],
  }
}

resource "azurerm_storage_account" "storage-account" {
  for_each                 = var.instances
  name                     = "${var.storageAccount.name}${each.key}"
  location                 = var.location
  resource_group_name      = var.resource_name
  account_tier             = "Standard"
  account_replication_type = "LRS"


 blob_properties {
      cors_rule {
        content {
            allowed_origins    = each.value["origin"]
            allowed_methods    = ["DELETE", "GET", "POST", "OPTIONS", "PUT", "PATCH"]
            allowed_headers    = ["*"]
            exposed_headers    = ["*"]
            max_age_in_seconds = 200
        }
      }
    }
  }
}