Terraform-Fehler mit dynamischem Block in for_each

Sep 09 2020

Ich versuche, eine azurblaue Speicherzuordnungszuordnung mithilfe der Azuremrm-Ressource storage_share zu instanziieren . Ich muss in der Lage sein, mehr als eine Speicherfreigabe mit demselben Block zu instanziieren. Jede dieser Aktien kann einen Abschnitt "acl" haben oder nicht.

Ich dachte daran, dieses Problem mit einem for_each in Verbindung mit einem dynamischen Block zu lösen, wie in der zugehörigen SE-Frage:

Main.tf

resource "azurerm_storage_share" "storage_share" {
  for_each             = var.storage_share_map
  name                 = each.key
  storage_account_name = azurerm_storage_account.sa.name
  quota                = each.value.quota

  dynamic "acl" {
    for_each = each.value.acl
    content {
      id = acl.value.id

      access_policy {
        permissions = acl.value.access_policy.permissions
        start       = acl.value.access_policy.start
        expiry      = acl.value.access_policy.expiry
      }
    }
  }

Die Variable würde definiert werden als:

variable "storage_share_map" {
  type = map(object({
    quota = number,
    acl = object({
      id = string,
      access_policy = object({
        expiry      = string,
        permissions = string,
        start       = string
      })
    }),
  }))
  default     = {}
}

und später in meinen Tests parametrisiert als:

storage_share_map = { 
  my-share-2 = {
    quota = 123,
    acl = {
      id = "a-id",
      access_policy = {
        expiry      = "ISO8061 UTC TIME"
        permissions = "rwdl"
        start       = "ISO8601 UTC TIME"
      },
    },
  }

Beim Testen gibt terraform jedoch die folgende Ausgabe zurück:

Error: Unsupported attribute

  on .terraform\modules\sa\main.tf line 83, in resource "azurerm_storage_share" "storage_share":
  83:       id = acl.value.id
    |----------------
    | acl.value is object with 3 attributes

This object does not have an attribute named "id".


Error: Unsupported attribute

  on .terraform\modules\sa\main.tf line 83, in resource "azurerm_storage_share" "storage_share":
  83:       id = acl.value.id
    |----------------
    | acl.value is "a-id"

This value does not have any attributes.


Error: Unsupported attribute

  on .terraform\modules\sa\main.tf line 86, in resource "azurerm_storage_share" "storage_share":
  86:         permissions = acl.value.access_policy.permissions
    |----------------
    | acl.value is object with 3 attributes

This object does not have an attribute named "access_policy".


Error: Unsupported attribute

  on .terraform\modules\sa\main.tf line 86, in resource "azurerm_storage_share" "storage_share":
  86:         permissions = acl.value.access_policy.permissions
    |----------------
    | acl.value is "a-id"

This value does not have any attributes.

Nach meinem Verständnis besteht das Problem hier darin, dass for_each im dynamischen Block entweder fehlerhaft ist oder sich schlecht verhält: acl.value scheint sowohl als Zeichenfolge "a-id" als auch mit drei Attributen (?) Bewertet zu sein.

Terraform Version 0.12.26 Azurerm Version 2.26.0

Jeder Einblick wäre dankbar.

Verwandte Frage: Dynamischer Block mit for_each in einer Ressource, die mit for_each erstellt wurde

Antworten

3 MattSchuchard Sep 09 2020 at 23:33

Durch Iterieren im dynamischen Block mit for_each = each.value.acliterieren Sie über die Werte im objectTyp. Es scheint, dass Sie wirklich über sich aclselbst iterieren möchten . Sie müssten Ihren Typ anpassen, um:

variable "storage_share_map" {
  type = map(object({
    quota = number,
    acl = list(object({
      ...
    }))
  })),
}

An den Fehlermeldungen können Sie erkennen, dass es derzeit immer wieder wiederholt wird idund access_policydie beiden angeforderten Attribute für jedes nicht gefunden werden, weshalb Sie 2 * 2 = 4 Fehler haben.

Sie können Ihre Eingabe entsprechend anpassen an:

storage_share_map = { 
  my-share-2 = {
    quota = 123,
    acl = [{
      id = "a-id",
      access_policy = {
        expiry      = "ISO8061 UTC TIME"
        permissions = "rwdl"
        start       = "ISO8601 UTC TIME"
      },
    }],
  }

und dies wird das gewünschte Verhalten erreichen.

Beachten Sie, dass Terraform 0.12 manchmal Probleme mit den Spezifikationen für verschachtelte Objekttypen hat. Wenn Sie also das aclwith weglassen, []kann dies unter bestimmten Umständen zum Absturz führen.

3 adp Sep 09 2020 at 21:39

Bitte verwenden Sie eckige Klammern für each.value.acl.

Der Azure-Speicherfreigabeblock sollte folgendermaßen aussehen:

resource "azurerm_storage_share" "storage_share" {
  for_each             = var.storage_share_map
  name                 = each.key
  storage_account_name = azurerm_storage_account.sa.name
  quota                = each.value.quota

  dynamic "acl" {
    for_each = [each.value.acl]
    content {
      id = acl.value.id

      access_policy {
        permissions = acl.value.access_policy.permissions
        start       = acl.value.access_policy.start
        expiry      = acl.value.access_policy.expiry
      }
    }
  }
}