Terraform и Azure: проблемы со связью между NetworkSecurityGroups и подсетями

При применении скрипта terraform я получаю следующую ошибку:

╷
│ Error: A resource with the ID "/subscriptions/***/resourceGroups/rg-subnet-test/providers/Microsoft.Network/virtualNetworks/subnet-test-vnet/subnets/subnet-test-subnet" already exists - to be managed via Terraform this resource needs to be imported into the State. Please see the resource documentation for "azurerm_subnet_network_security_group_association" for more information.
│
│   with azurerm_subnet_network_security_group_association.association1,
│   on main.tf line 47, in resource "azurerm_subnet_network_security_group_association" "association1":
│   47: resource "azurerm_subnet_network_security_group_association" "association1" {
│
╵

Это мой сценарий:

# Resource Group
resource "azurerm_resource_group" "rg_subnet_test" {
  location = "germanywestcentral"
  name     = "rg-subnet-test"
}

# VNET
resource "azurerm_virtual_network" "vnet_subnet_test" {
  address_space       = ["10.100.2.0/24"]
  location            = azurerm_resource_group.rg_subnet_test.location
  name                = "subnet-test-vnet"
  resource_group_name = azurerm_resource_group.rg_subnet_test.name
}

# Subnet
resource "azurerm_subnet" "subnet_germany" {
  name                 = "subnet-test-subnet"
  address_prefixes     = ["10.100.2.0/24"]
  resource_group_name  = azurerm_virtual_network.vnet_subnet_test.resource_group_name
  virtual_network_name = azurerm_virtual_network.vnet_subnet_test.name
}

# First Network Security Group
resource "azurerm_network_security_group" "app_server_nsg_1" {
  name                = "subnet-test-nsg-1"
  location            = azurerm_resource_group.rg_subnet_test.location
  resource_group_name = azurerm_resource_group.rg_subnet_test.name
}

# Second Network Security Group
resource "azurerm_network_security_group" "app_server_nsg_2" {
  name                = "subnet-test-nsg-2"
  location            = azurerm_resource_group.rg_subnet_test.location
  resource_group_name = azurerm_resource_group.rg_subnet_test.name
}

# Association between first NSG to subnet
resource "azurerm_subnet_network_security_group_association" "association1" {
  subnet_id                 = azurerm_subnet.subnet_germany.id
  network_security_group_id = azurerm_network_security_group.app_server_nsg_1.id
}

# Association between second NSG to subnet
resource "azurerm_subnet_network_security_group_association" "association2" {
  subnet_id                 = azurerm_subnet.subnet_germany.id
  network_security_group_id = azurerm_network_security_group.app_server_nsg_2.id
}

Я не понимаю ошибки, потому что я создаю подсеть только один раз. Почему вторая ассоциация пытается снова создать подсеть? Что я здесь делаю не так?

См. перемещение ресурсов .

Rui Jarimba 17.07.2024 16:46

Нет, это не то. Даже если у меня будет чистый лист в Azure, эта ошибка будет выдана.

s3b 17.07.2024 17:44

Если вы создали ресурс(ы) с помощью terraform, а затем переместили его, вам необходимо манипулировать файлом состояния и/или использовать блок move, как указано в подстатьях по ссылке, которую я разместил. Попробуйте удалить соответствующую запись из состояния, а затем используйте команду import, как указано в сообщении об ошибке.

Rui Jarimba 17.07.2024 17:56

Опять же, эта ошибка возникает, даже если я использую полностью чистую подписку Azure. Я ничего не двигаю.

s3b 17.07.2024 18:02

Я отредактировал свой вопрос. Надеюсь, теперь я смогу продемонстрировать проблему немного лучше.

s3b 18.07.2024 10:24
Как установить LAMP Stack - Security 5/5 на виртуальную машину Azure Linux VM
Как установить LAMP Stack - Security 5/5 на виртуальную машину Azure Linux VM
В предыдущей статье мы завершили установку базы данных, для тех, кто не знает.
Как установить LAMP Stack 1/2 на Azure Linux VM
Как установить LAMP Stack 1/2 на Azure Linux VM
В дополнение к нашему предыдущему сообщению о намерении Azure прекратить поддержку Azure Database для MySQL в качестве единого сервера после 16...
0
5
74
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Terraform и Azure: проблемы со связью между NetworkSecurityGroups и подсетями

Как упоминалось в ошибке, нам нужно импортировать ресурс подсети в соответствии с требованиями, поскольку это единственный подход, который работает. Когда я тестирую эту конфигурацию, я сталкиваюсь с аналогичной проблемой, о которой вы упомянули.

Команда terraform_move здесь не будет работать, так как нам нужно переместить изменения конфигурации в соответствии с ресурсом, который нам нужно переместить, в файле состояния, как Руи Джаримба упомянул, что лучше удалить информацию о ресурсе из состояния и повторно импортировать ее в соответствии с требование работает только так, как ожидалось.

Ошибка, с которой мы столкнулись, возникла только из-за несоответствия конфигурации состоянию, которое мы пробовали, а не способу предоставления ресурсов.

Конфигурация соответствует репозиторию, которым вы поделились в github я поделился только той частью конфигурации, где мы импортируем ресурс.

конфигурация:

модули/немецкий/main.tf

variable "region" {}
variable "resource_group_name" {}

module "network" {
  source = "../network"
  region = var.region
  resource_group_name = var.resource_group_name
}

module "appserver" {
  source = "../vm/app"
  region = var.region
  resource_group_name = var.resource_group_name
  subnet_id = module.network.subnet_id
}

module "dbserver" {
  source = "../vm/db"
  region = var.region
  resource_group_name = var.resource_group_name
  subnet_id = module.network.subnet_id
}

модули/сеть/main.tf:

variable "region" {}
variable "resource_group_name" {}

resource "azurerm_virtual_network" "vnet" {
  name                = "subnet-test-de-vnet"
  address_space       = ["10.0.0.0/16"]
  location            = var.region
  resource_group_name = var.resource_group_name
}

resource "azurerm_subnet" "subnet" {
  name                 = "subnet-test-de-subnet"
  resource_group_name  = var.resource_group_name
  virtual_network_name = azurerm_virtual_network.vnet.name
  address_prefixes     = ["10.0.1.0/24"]
}

output "subnet_id" {
  value = azurerm_subnet.subnet.id
}

продолжите остальную часть конфигурации

Развертывание:

запусти команду terraform state list

удалить ресурс

этот ресурс был импортирован в другой модуль согласно требованию

terraform import 'module.german_region.module.dbserver.azurerm_subnet_network_security_gassociation.association_subnet_db

Ссылаться:

https://github.com/azurerm/terraform-azure-resources/tree/v1.0.10/modules/subnet_network_security_group_association

https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/subnet_network_security_group_association

https://github.com/Azure/terraform-azurerm-network-security-group

Спасибо, что уделили время, Винай. Я так и не понял, зачем мне запускать этот скрипт, удалять подсеть из состояния и потом заново импортировать? Должен ли быть лучший способ связать две группы сетевой безопасности в одной группе ресурсов с одной подсетью?

s3b 17.07.2024 19:23

Я отредактировал свой вопрос. Надеюсь, теперь я смогу продемонстрировать проблему немного лучше.

s3b 18.07.2024 10:24

Теперь я знаю, что я сделал не так. Я предположил, что мне нужна группа безопасности сети для каждой виртуальной машины. И я предположил, что у меня может быть только один ресурс подсети для каждой группы безопасности сети. Это не правильно. С одной группой безопасности сети можно связать только одну подсеть. Если вы попытаетесь связать уже используемую подсеть с другой группой безопасности сети, произойдет эта ошибка.

s3b 18.07.2024 13:54

Ошибка: ресурс с идентификатором xxxxxx уже существует. Для управления через Terraform этот ресурс необходимо импортировать в состояние.

Существует несколько возможных сценариев, которые могут привести к этой ошибке:

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

Подробную информацию о том, как решить эту проблему, можно найти в разделе Ответ Виная Б. или Перемещение ресурсов.

Спасибо за ваш ответ. Однако я получаю эту ошибку, даже если запускаю этот скрипт впервые. Никакие ресурсы не переименовываются и не перемещаются вручную. Проблема связана со второй (или, в данном случае, первой) связью между подсетью и группой безопасности сети. Я начинаю задаваться вопросом, не является ли это ошибкой?

s3b 18.07.2024 12:19

@s3b проверьте, не создаете ли вы дублированные ресурсы случайно. найдите имя или идентификатор ресурса в файле плана. Кроме того, запустите код terraform с пустым файлом состояния, чтобы посмотреть, что произойдет.

Rui Jarimba 18.07.2024 12:25

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

s3b 18.07.2024 12:36

Теперь я знаю, что я сделал не так. Я предположил, что мне нужна группа безопасности сети для каждой виртуальной машины. И я предположил, что у меня может быть только один ресурс подсети для каждой группы безопасности сети. Это не правильно. С одной группой безопасности сети можно связать только одну подсеть. Если вы попытаетесь связать уже используемую подсеть с другой группой безопасности сети, произойдет эта ошибка.

s3b 18.07.2024 13:54

@s3b, это правильно: одна подсеть может быть связана с одной и только одной группой безопасности сети; но одна группа безопасности сети может быть связана с несколькими подсетями.

Rui Jarimba 18.07.2024 13:59

Хорошо, тогда это решено. Спасибо за ваше время.

s3b 18.07.2024 14:00

@s3b нп. Подумайте о том, чтобы добавить ответ на свой вопрос — это может быть полезно другим, кто делает ту же ошибку.

Rui Jarimba 18.07.2024 14:02
Ответ принят как подходящий

Проблема заключалась в том, что я связывал несколько групп сетевой безопасности с одним и тем же ресурсом подсети. Очевидно, это невозможно, вам придется создать подсеть для каждой группы сетевой безопасности.

Правильным примером использования кода в моем вопросе будет (обратите внимание на измененное адресное пространство в виртуальной сети и дополнительную подсеть):

# Resource Group
resource "azurerm_resource_group" "rg_subnet_test" {
  location = "germanywestcentral"
  name     = "rg-subnet-test"
}

# VNET
resource "azurerm_virtual_network" "vnet_subnet_test" {
  address_space       = ["10.100.0.0/16"]
  location            = azurerm_resource_group.rg_subnet_test.location
  name                = "subnet-test-vnet"
  resource_group_name = azurerm_resource_group.rg_subnet_test.name
}

# Subnet
resource "azurerm_subnet" "subnet1" {
  name                 = "subnet-test-subnet1"
  address_prefixes     = ["10.100.2.0/24"]
  resource_group_name  = azurerm_virtual_network.vnet_subnet_test.resource_group_name
  virtual_network_name = azurerm_virtual_network.vnet_subnet_test.name
}

resource "azurerm_subnet" "subnet2" {
  name                 = "subnet-test-subnet2"
  address_prefixes     = ["10.100.3.0/24"]
  resource_group_name  = azurerm_virtual_network.vnet_subnet_test.resource_group_name
  virtual_network_name = azurerm_virtual_network.vnet_subnet_test.name
}

# First Network Security Group
resource "azurerm_network_security_group" "app_server_nsg_1" {
  name                = "subnet-test-nsg-1"
  location            = azurerm_resource_group.rg_subnet_test.location
  resource_group_name = azurerm_resource_group.rg_subnet_test.name
}

# Second Network Security Group
resource "azurerm_network_security_group" "app_server_nsg_2" {
  name                = "subnet-test-nsg-2"
  location            = azurerm_resource_group.rg_subnet_test.location
  resource_group_name = azurerm_resource_group.rg_subnet_test.name
}

# Association between first NSG to subnet
resource "azurerm_subnet_network_security_group_association" "association1" {
  subnet_id                 = azurerm_subnet.subnet1.id
  network_security_group_id = azurerm_network_security_group.app_server_nsg_1.id
}

# Association between second NSG to subnet
resource "azurerm_subnet_network_security_group_association" "association2" {
  subnet_id                 = azurerm_subnet.subnet2.id
  network_security_group_id = azurerm_network_security_group.app_server_nsg_2.id
}

Другие вопросы по теме

Похожие вопросы