개체 목록이있는 Terraform for-each

Nov 20 2020

variables.tf 파일에 다음 변수가 있습니다.

variable tenants {
  description = "Map of project names to configuration."
  type = list(object({
    name  = string
    dname = string
    desc  = string
    site  = list(string)
  }))
  default = [{
      name  = "Tenant-1",
      dname = "Tenant-1",
      desc  = "Test Tenant 1",
      site  = ["site1", "site2"]
    },
    {
      name  = "Tenant-2",
      dname = "Tenant-2",
      desc  = "Test Tenant 2",
      site  = ["site1"]
    }]
}

내 main.tf 파일에서이 목록을 반복하고 싶습니다. main.tf 파일에 다음 코드가 있습니다.

resource "mso_tenant" "restenant" {
  for_each = {for i, v in var.tenants:  i => v}
    name         = each.value.name
    display_name = each.value.dname
    description  = each.value.desc
    site_associations {
      site_id =  each.value.site
  }
}

따라서 최종 결과는 변수 파일에 지정된 속성으로 2 개의 테넌트가 생성되어야합니다. 따라서 tenant1에는 2 개의 site_associations가 있고 tenant2에는 1 개의 연결이 생성됩니다.

결과는 다음과 같아야합니다.

name         = "Tenant-1"
display_name = "Tenant-1"
description  = "Test Tenant 1"
site_associations {
  site_id = site1
  site_id = site2
}

name         = "Tenant-2"
display_name = "Tenant-2"
description  = "Test Tenant 2"
site_associations {
   site_id = site1
}

다음을 시도했습니다.

resource "mso_tenant" "restenant" {
  for_each = {for i, v in var.tenants:  i => v}
    name         = each.value.name
    display_name = each.value.dname
    description  = each.value.desc
    site_associations {
      site_id =  each.value.site
  }
}

이것을위한 작품 name, dname그리고 desc있지만, 그것은 (목록입니다) 사이트 변수를 반복하지 않습니다. 이로 인해 오류 메시지가 나타납니다.

each.value.site는 1 개의 요소가있는 문자열 목록입니다. 속성 "site_id"에 대한 부적절한 값 : 문자열이 필요합니다.

다음과 같이 해결하려고 시도했습니다.

resource "mso_tenant" "restenant" {
  for_each = {for i, v in var.tenants:  i => v}
    
    name         = each.value.name
    display_name = each.value.dname
    description  = each.value.desc
    site_associations {
      site_id = [for site in each.value.site: site]
  }
}

그러나 이것은 또한 다음을 제공합니다.

each.value.site는 2 개의 요소가있는 문자열 목록입니다. 속성 "site_id"에 대한 부적절한 값 : 문자열이 필요합니다.

답변

2 ElijahRoberts Nov 20 2020 at 20:48

당신이 찾고있는 것은 동적 블록입니다. https://www.terraform.io/docs/configuration/expressions.html#dynamic-blocks

실물:

site_associations {
    site_id =  each.value.site
}

동적:

dynamic "site_associations"{
    for_each = each.value.site
    content {
        site_id = site_associations.value
    }
}

dynamic블록은 다른 만들 수 있습니다 for_each오버 루프를 each.value.site.

참고 : 동적 블록 내부의 값은 블록 이름을 사용하여 참조됩니다. site_associations.value

전체 main.tf :

variable tenants {
  description = "Map of project names to configuration."
  type = list(object({
    name  = string
    dname = string
    desc  = string
    site  = list(string)
  }))
  default = [{
      name  = "Tenant-1",
      dname = "Tenant-1",
      desc  = "Test Tenant 1",
      site  = ["site1", "site2"]
    },
    {
      name  = "Tenant-2",
      dname = "Tenant-2",
      desc  = "Test Tenant 2",
      site  = ["site1"]
    }]
}

resource "mso_tenant" "restenant" {
  for_each = {for i, v in var.tenants:  i => v}
    name         = each.value.name
    display_name = each.value.dname
    description  = each.value.desc
    dynamic "site_associations"{
    for_each = each.value.site
    content {
      site_id = site_associations.value
    }
    }

}

계획 결과 :


  # mso_tenant.restenant["0"] will be created
  + resource "mso_tenant" "restenant" {
      + description  = "Test Tenant 1"
      + display_name = "Tenant-1"
      + id           = (known after apply)
      + name         = "Tenant-1"

      + site_associations {
          + aws_access_key_id         = (known after apply)
          + aws_account_id            = (known after apply)
          + aws_secret_key            = (known after apply)
          + azure_access_type         = (known after apply)
          + azure_active_directory_id = (known after apply)
          + azure_application_id      = (known after apply)
          + azure_client_secret       = (known after apply)
          + azure_subscription_id     = (known after apply)
          + is_aws_account_trusted    = (known after apply)
          + site_id                   = "site1"
          + vendor                    = (known after apply)
        }
      + site_associations {
          + aws_access_key_id         = (known after apply)
          + aws_account_id            = (known after apply)
          + aws_secret_key            = (known after apply)
          + azure_access_type         = (known after apply)
          + azure_active_directory_id = (known after apply)
          + azure_application_id      = (known after apply)
          + azure_client_secret       = (known after apply)
          + azure_subscription_id     = (known after apply)
          + is_aws_account_trusted    = (known after apply)
          + site_id                   = "site2"
          + vendor                    = (known after apply)
        }

      + user_associations {
          + user_id = (known after apply)
        }
    }

  # mso_tenant.restenant["1"] will be created
  + resource "mso_tenant" "restenant" {
      + description  = "Test Tenant 2"
      + display_name = "Tenant-2"
      + id           = (known after apply)
      + name         = "Tenant-2"

      + site_associations {
          + aws_access_key_id         = (known after apply)
          + aws_account_id            = (known after apply)
          + aws_secret_key            = (known after apply)
          + azure_access_type         = (known after apply)
          + azure_active_directory_id = (known after apply)
          + azure_application_id      = (known after apply)
          + azure_client_secret       = (known after apply)
          + azure_subscription_id     = (known after apply)
          + is_aws_account_trusted    = (known after apply)
          + site_id                   = "site1"
          + vendor                    = (known after apply)
        }

      + user_associations {
          + user_id = (known after apply)
        }
    }

Plan: 2 to add, 0 to change, 0 to destroy.