Терраформные петли - PullRequest
       4

Терраформные петли

0 голосов
/ 09 февраля 2020

В настоящее время я пишу код Terraform, который развертывает Azure Частные зоны DNS в Azure.

Я успешно развернул зоны DNS, используя следующий код:

dns_zones = [
"domain1.com",
"domain2.com",
"domain3.com",
]

resource "azurerm_private_dns_zone" "dns_zones" {
  for_each = toset(var.dns_zones)

  name                = each.value
  resource_group_name = var.resource_group
}

Моя проблема заключается в настройке связей между зонами и виртуальными сетями. Мне нужно перебрать список dns_zones и получить вложенный l oop, который затем перебирает список vnet_links и настраивает ссылки vnet в зоне.

Следующее решение работает, однако оно не очень надежно поскольку удаление конфигурации из любого списка будет перетасовывать порядковые номера списка, в результате чего Terraform удалит и заново создаст конфигурацию, что невозможно:

vnet_links = [
    {
    "linkName": "name-of-vnet-link1"
    "vnetId": "vnet--resource-id-placeholder1"
    },{
    "linkName": "name-of-vnet-link2"
    "vnetId": "vnet--resource-id-placeholder2"
    }
]

resource "azurerm_private_dns_zone_virtual_network_link" "vnet_link" {
  count              = length(setproduct(var.dns_zones, var.vnet_links))

  name                  = element(setproduct(var.dns_zones, var.vnet_links)[count.index], 1).linkName
  resource_group_name   = var.resource_group
  private_dns_zone_name = element(setproduct(var.dns_zones, var.vnet_links)[count.index], 0)
  virtual_network_id    = element(setproduct(var.dns_zones, var.vnet_links)[count.index], 1).vnetId
}

Я обнаружил, что с помощью setproduct () Функция ниже может создать новый список, содержащий данные, с которыми я хочу работать, и я намеревался использовать это с for_each, а не с count, но это не возможно использовать с функцией toset (), так как она принимает только список строк.

setproduct(var.dns_zones, var.vnet_links)

Прямо сейчас я немного застрял, где go с этим. Я мог бы включить информацию о зоне в список vnet_links, но это потребовало бы большого количества дублирования, которого я хотел бы избежать. В идеале я хотел бы найти решение, которое не требует никаких изменений в списке dns_zones и сохраняет отдельный список со ссылками vnet.

Спасибо!

РЕДАКТИРОВАТЬ :

Спасибо Чарльзу за предоставленный способ форматирования данных. В дополнение к ответу Чарльза мне также нужно было создать динамическую c карту внутри for_each l oop, чтобы использовать данные. Окончательное решение выглядит следующим образом:

dns_zones = [
"domain1.com",
"domain2.com",
"domain3.com",
]

vnet_links = [
    {
    "linkName": "name-of-vnet-link1"
    "vnetId": "vnet--resource-id-placeholder1"
    },{
    "linkName": "name-of-vnet-link2"
    "vnetId": "vnet--resource-id-placeholder2"
    }
]

locals {
  association = flatten([
    for dns_zone in var.dns_zones: [
      for link in var.vnet_links: {
        zone = dns_zone
        vnet_link = link
      }
    ]
  ])
}

resource "azurerm_private_dns_zone_virtual_network_link" "vnet_link" {
  for_each              = { for row in local.association:
    "${row.zone}_${row.vnet_link.linkName}" => {
      zone = row.zone
      linkName = row.vnet_link.linkName
      vnetId = row.vnet_link.vnetId
    }
  }

  name                  = each.value.linkName
  resource_group_name   = var.resource_group
  private_dns_zone_name = each.value.zone
  virtual_network_id    = each.value.vnetId
}

1 Ответ

0 голосов
/ 10 февраля 2020

Для ваших требований, я думаю, что для l oop подходит для вас, я предполагаю, что вы хотите связать информацию о зоне и ссылку Vnet в этот формат:

  {
    "vnet_link" = {
    "linkName": "name-of-vnet-link1"
    "vnetId": "vnet--resource-id-placeholder1"
    }
    "zone" = "domain1.com"
  }

Тогда вы можете используйте для l oop, чтобы поместить все возможные ассоциации в список, как показано ниже:

variable "dns_zones" {
  default = [
    "domain1.com",
    "domain2.com",
    "domain3.com",
  ]
}

variable "vnet_links" {
  default = [
    {
    "linkName": "name-of-vnet-link1"
    "vnetId": "vnet--resource-id-placeholder1"
    },
    {
    "linkName": "name-of-vnet-link2"
    "vnetId": "vnet--resource-id-placeholder2"
    }
  ]
}

locals {
  association = flatten([
    for dns_zone in var.dns_zones: [
      for link in var.vnet_links: {
        zone = dns_zone
        vnet_link = link
      }
    ]
  ])
}

output "association" {
  value = local.association
}

Наконец, вывод будет выглядеть так:

enter image description here

Если есть еще вопросы, пожалуйста, дайте мне знать. Надеюсь, что это решение, которое вы хотите.

...