Terraform — как получить ссылку на ресурсы, созданные в for_each блоке

#terraform #terraform-provider-azure

#terraform #terraform-provider-azure

Вопрос:

У меня есть приведенный ниже код, в котором я создаю виртуальные сети в for_each блоке:

 provider "azurerm" {
  features {}
}

variable "vnets" {
  type = map(object({
    name          = string
    address_space = list(string)
  }))
  default = {
    "vnet1" = {
      "name"          = "vnet1",
      "address_space" = ["10.0.0.0/16"]
    },
    "vnet2" = {
      "name"          = "vnet2",
      "address_space" = ["10.1.0.0/16"]
    }
  }
}

resource "azurerm_resource_group" "vnets" {
  name     = "vnets"
  location = "WestEurope"
}

resource "azurerm_virtual_network" "virtual_network" {
  for_each = var.vnets
    name                =       each.value.name
    location            =       "West Europe"
    resource_group_name =       azurerm_resource_group.vnets.name
    address_space       =       each.value.address_space
}

 

С планом все работает, виртуальные сети будут созданы,
но проблема в том, как добраться до созданных ресурсов из блока for_each?

Когда я набираю команду для возврата списка ресурсов:

 terraform state list
 

Затем у меня есть следующий вывод из консоли:

 azurerm_resource_group.vnets
azurerm_virtual_network.virtual_network["vnet1"]
azurerm_virtual_network.virtual_network["vnet2"]
 

И когда я хочу использовать vnet1 в любом месте кода, используя ссылку azurerm_virtual_network.virtual_network[«vnet1»], я получаю сообщение об ошибке.

Например, я хочу просмотреть ресурс vnet1:

 terraform state show azurerm_virtual_network.virtual_network["vnet1"]
 

Я получаю такую ошибку:

 Error parsing instance address: azurerm_virtual_network.virtual_network[vnet1]

This command requires that the address references one specific instance.
To view the available instances, use "terraform state list". Please modify
the address to reference a specific instance.
 

Я попробовал следующие команды для доступа к ресурсу, но они не работают:

 terraform state show azurerm_virtual_network.virtual_network["vnet1"]
terraform state show 'azurerm_virtual_network.virtual_network["vnet1"]'
terraform state show azurerm_virtual_network.virtual_network[vnet1]
terraform state show azurerm_virtual_network.virtual_network[0]
terraform state show azurerm_virtual_network.virtual_network.vnet1
 

Вы знаете, как это решить?

Комментарии:

1. Вам нужно экранировать кавычки из вашей оболочки. terraform state show azurerm_virtual_network.virtual_network["vnet1"] должно сработать.

2. @ydaetskcoR, это не работает:/ Ошибка синтаксического анализа адреса экземпляра: azurerm_virtual_network.virtual_network[vnet1] Для этой команды требуется, чтобы адрес ссылался на один конкретный экземпляр. Чтобы просмотреть доступные экземпляры, используйте «список состояний terraform». Пожалуйста, измените адрес, чтобы ссылаться на конкретный экземпляр.

3. Можете ли вы перепроверить terraform state show 'azurerm_virtual_network.virtual_network["vnet1"]' . Это правильный способ, и он должен работать.

Ответ №1:

Кроме того, если вы хотите показать конкретный экземпляр в файле состояния, вы можете использовать terraform state show ‘azurerm_virtual_network.virtual_network[«vnet1 «]’

Я столкнулся с такой же проблемой при использовании модулей. Приведенный выше правильный ответ, и ниже показано, как выполнить его с помощью модуля:

 terraform state show 'module.module_name["module_instance"].resource.resource_name["resource_instance"]
 

Пример:

 state show 'module.rsm_keyvault_solution_module_resource["development"].azurerm_key_vault.keyvault_module_resource["rsm-playground-dev"]'
 

Ответ №2:

В этом случае вы можете использовать функцию values для получения карты и возврата списка, содержащего значения элементов на этой карте.

Например, чтобы получить значения виртуальных сетей на карте:

 output "azurerm_vnets_names" {

    value = values(azurerm_virtual_network.virtual_network)[*].name
             
}
 

введите описание изображения здесь

Или получить конкретное имя виртуальной сети следующим образом:

 output "azurerm_vnet1_name" {

    value = values(azurerm_virtual_network.virtual_network)[0].name
             
}
 

Кроме того, если вы хотите показать конкретный экземпляр в файле состояния, вы можете использовать

 terraform state show 'azurerm_virtual_network.virtual_network["vnet1"]'
 

введите описание изображения здесь