При применении скрипта 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
}
Я не понимаю ошибки, потому что я создаю подсеть только один раз. Почему вторая ассоциация пытается снова создать подсеть? Что я здесь делаю не так?
Нет, это не то. Даже если у меня будет чистый лист в Azure, эта ошибка будет выдана.
Если вы создали ресурс(ы) с помощью terraform, а затем переместили его, вам необходимо манипулировать файлом состояния и/или использовать блок move
, как указано в подстатьях по ссылке, которую я разместил. Попробуйте удалить соответствующую запись из состояния, а затем используйте команду import
, как указано в сообщении об ошибке.
Опять же, эта ошибка возникает, даже если я использую полностью чистую подписку Azure. Я ничего не двигаю.
Я отредактировал свой вопрос. Надеюсь, теперь я смогу продемонстрировать проблему немного лучше.
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/Azure/terraform-azurerm-network-security-group
Спасибо, что уделили время, Винай. Я так и не понял, зачем мне запускать этот скрипт, удалять подсеть из состояния и потом заново импортировать? Должен ли быть лучший способ связать две группы сетевой безопасности в одной группе ресурсов с одной подсетью?
Я отредактировал свой вопрос. Надеюсь, теперь я смогу продемонстрировать проблему немного лучше.
Теперь я знаю, что я сделал не так. Я предположил, что мне нужна группа безопасности сети для каждой виртуальной машины. И я предположил, что у меня может быть только один ресурс подсети для каждой группы безопасности сети. Это не правильно. С одной группой безопасности сети можно связать только одну подсеть. Если вы попытаетесь связать уже используемую подсеть с другой группой безопасности сети, произойдет эта ошибка.
Ошибка: ресурс с идентификатором xxxxxx уже существует. Для управления через Terraform этот ресурс необходимо импортировать в состояние.
Существует несколько возможных сценариев, которые могут привести к этой ошибке:
Подробную информацию о том, как решить эту проблему, можно найти в разделе Ответ Виная Б. или Перемещение ресурсов.
Спасибо за ваш ответ. Однако я получаю эту ошибку, даже если запускаю этот скрипт впервые. Никакие ресурсы не переименовываются и не перемещаются вручную. Проблема связана со второй (или, в данном случае, первой) связью между подсетью и группой безопасности сети. Я начинаю задаваться вопросом, не является ли это ошибкой?
@s3b проверьте, не создаете ли вы дублированные ресурсы случайно. найдите имя или идентификатор ресурса в файле плана. Кроме того, запустите код terraform с пустым файлом состояния, чтобы посмотреть, что произойдет.
Вот что я пытаюсь сказать: ошибка выдается, даже если я запускаю этот сценарий в первый раз с пустым файлом состояния и в пустой группе ресурсов. Приглашаю вас запустить скрипт в моих вопросах, в нем всего семь ресурсов.
Теперь я знаю, что я сделал не так. Я предположил, что мне нужна группа безопасности сети для каждой виртуальной машины. И я предположил, что у меня может быть только один ресурс подсети для каждой группы безопасности сети. Это не правильно. С одной группой безопасности сети можно связать только одну подсеть. Если вы попытаетесь связать уже используемую подсеть с другой группой безопасности сети, произойдет эта ошибка.
@s3b, это правильно: одна подсеть может быть связана с одной и только одной группой безопасности сети; но одна группа безопасности сети может быть связана с несколькими подсетями.
Хорошо, тогда это решено. Спасибо за ваше время.
@s3b нп. Подумайте о том, чтобы добавить ответ на свой вопрос — это может быть полезно другим, кто делает ту же ошибку.
Проблема заключалась в том, что я связывал несколько групп сетевой безопасности с одним и тем же ресурсом подсети. Очевидно, это невозможно, вам придется создать подсеть для каждой группы сетевой безопасности.
Правильным примером использования кода в моем вопросе будет (обратите внимание на измененное адресное пространство в виртуальной сети и дополнительную подсеть):
# 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
}
См. перемещение ресурсов .