问题描述
这链接到我的上一个问题,单击链接了解我的其余代码以及它们如何组合在一起:Use output value from module that has a for_each set
虽然答案有助于解决问题并允许我运行管道,但我认为存在错误,因为使用模块上的 for_each 生成 VM 的方式。这会导致传递给 network_security_rule 的值不正确。以下是错误示例:
Error: Error Creating/Updating Network Security Rule "nsr-sBox-http80" (NSG "module.fico_app_vm.linux_vm_nsg" / Resource Group "rg-sBox-app"): network.SecurityRulesClient#CreateOrUpdate: Failure sending request: StatusCode=404 -- Original Error: Code="ResourceNotFound" Message="The Resource 'Microsoft.Network/networkSecurityGroups/module.fico_app_vm.linux_vm_nsg' under resource group 'rg-sBox-app' was not found. For more details please go to https://aka.ms/ARMResourceNotFoundFix"
on main.tf line 58,in resource "azurerm_network_security_rule" "fico-app-sr-80":
58: resource "azurerm_network_security_rule" "fico-app-sr-80" {
输出.tf
output "linux_vm_ips" {
value = azurerm_network_interface.dwp_network_interface.private_ip_address
}
output "linux_vm_nsg" {
value = azurerm_network_security_group.dwp_network_security_group.name
}
起初我以为是因为没有创建 NSG,但我检查了控制台,它确实创建了它。问题是 NSG 是在模块中为每个 VM 创建的。 VM 是通过循环 tfvars 文件中的变量创建的。如何将模块中创建的 NSG 名称传递给模块外部的安全规则?:
resource "azurerm_network_security_rule" "fico-app-sr-80" {
name = "nsr-${var.environment}-${var.directorate}-${var.business_unit}-${var.vm_identifier}${var.instance_number}-http80"
priority = 100
direction = "Inbound"
access = "Allow"
protocol = "*"
source_port_range = "*"
destination_port_range = "80"
source_address_prefixes = ["module.fico_web_vm.linux_vm_ips"]
destination_address_prefix = "VirtualNetwork"
resource_group_name = azurerm_resource_group.rg_fico_app.name
network_security_group_name = "module.fico_app_vm.linux_vm_nsg"
}
# Network Security Group
resource "azurerm_network_security_group" "network_security_group" {
name = "nsg-${var.environment}-${var.directorate}-${var.business_unit}-${var.vm_identifier}-${var.vm_name}"
resource_group_name = var.resource_group
location = var.location
}
还有一点需要注意,var.vm_name 遍历每个映射的键,这构成了 NSG 名称的一部分。
main.tf 中的模块:
module "fico_app_vm" {
for_each = var.app_servers
source = "../modules/compute/linux_vm"
source_image_id = var.app_image_id
location = var.location
vm_name = each.key
vm_identifier = "${var.vm_identifier}${var.instance_number}"
vm = each.value
disks = each.value["disks"]
resource_group = azurerm_resource_group.rg_fico_app.name
directorate = var.directorate
business_unit = var.business_unit
environment = var.environment
network_rg_identifier = var.network_rg_identifier
subnet_name = "sub-${var.environment}-${var.directorate}-${var.business_unit}-be01"
diag_storage_account_name = var.diag_storage_account_name
ansible_storage_account_name = var.ansible_storage_account_name
ansible_storage_account_key = var.ansible_storage_account_key
log_analytics_workspace_name = var.log_analytics_workspace_name
backup_policy_name = var.backup_policy_name
enable_management_locks = true
}
tfvars:
app_servers ={
app-1 = {
size = "Standard_E2s_v3"
admin_username = "xxx"
public_key = "xxx"
disks = [32,32]
zone_vm = "1"
zone_disk = ["1"]
}
}
解决方法
我认为是你没有仔细阅读前面的答案的问题。答案显示您需要像这样更改安全组名称:
network_security_group_name = module.fico_app_vm.linux_vm_nsg
没有双引号。双引号表示它是一个字符串。但是您需要使用模块属性,而不是值为 "module.fico_app_vm.linux_vm_nsg"
的字符串。错误也直接显示出来了。
我意识到我的错误是什么。我需要改变这个:
network_security_group_name = "module.fico_app_vm.linux_vm_nsg"
到这里
network_security_group_name = module.fico_app_vm[each.key].linux_vm_nsg
但我还需要引用源地址前缀中的值。因此,为了引用密钥,我创建了另一个变量并对其进行了更改:
source_address_prefixes = ["module.fico_web_vm.linux_vm_ips"]
为此:
source_address_prefix = module.fico_web_vm[each.value.web_server].linux_vm_ip
我还必须更改为 source_address_prefix,这就是发生类型错误的原因!
安全规则现在看起来像这样:
resource "azurerm_network_security_rule" "fico-app-sr-80" {
for_each = var.app_servers
name = "nsr-${var.environment}-${var.directorate}-${var.business_unit}-${var.vm_identifier}${var.instance_number}-http80"
priority = 100
direction = "Inbound"
access = "Allow"
protocol = "*"
source_port_range = "*"
destination_port_range = "80"
source_address_prefix = module.fico_web_vm[each.value.web_server].linux_vm_ip
destination_address_prefix = "VirtualNetwork"
resource_group_name = azurerm_resource_group.rg_dwp_fico_app.name
network_security_group_name = module.fico_app_vm[each.key].linux_vm_nsg
变量看起来像这样:
app_servers = {
app-1 = {
size = "Standard_E2s_v3"
admin_username = "azureuser"
public_key = xxxx
disks = [32,32]
zone_vm = "1"
zone_disk = ["1"]
web_server = "web-1"
}
}