Azure
子網沒有在 azure 上使用 terraform 創建,如何解決?
我正在嘗試在 azure 上創建兩台帶有 terraform 的 centos 8 機器。
我的模板 github連結
當我嘗試申請時,我遇到了與政策相關的錯誤。你能建議如何解決這個問題嗎?
> │ Error: creating Subnet: (Name "subnetforAutomation" / Virtual Network Name "vnetforAutomation" / Resource Group "automation_mart"): > network.SubnetsClient#CreateOrUpdate: Failure sending request: > StatusCode=0 -- Original Error: Code="RequestDisallowedByPolicy" > Message="Resource 'subnetforAutomation' was disallowed by policy. > Policy identifiers: > '[{\"policyAssignment\":{\"name\":\"Deny-Subnet-Without-Nsg\",\"id\":\"/providers/Microsoft.Management/managementGroups/QSFT-landingzones/providers/Microsoft.Authorization/policyAssignments/Deny-Subnet-Without-Nsg\"},\"policyDefinition\":{\"name\":\"Subnets > should have a Network Security Group > \",\"id\":\"/providers/Microsoft.Management/managementGroups/QSFT/providers/Microsoft.Authorization/policyDefinitions/Deny-Subnet-Without-Nsg\"}}]'." > Target="subnetforAutomation" > AdditionalInfo=[{"info":{"evaluationDetails":{"evaluatedExpressions":[{"expression":"type","expressionKind":"Field","expressionValue":"Microsoft.Network/virtualNetworks/subnets","operator":"Equals","path":"type","result":"True","targetValue":"Microsoft.Network/virtualNetworks/subnets"},{"expression":"Microsoft.Network/virtualNetworks/subnets/networkSecurityGroup.id","expressionKind":"Field","operator":"Exists","path":"properties.networkSecurityGroup.id","result":"True","targetValue":"false"}]},"policyAssignmentDisplayName":"Deny-Subnet-Without-Nsg","policyAssignmentId":"/providers/Microsoft.Management/managementGroups/QSFT-landingzones/providers/Microsoft.Authorization/policyAssignments/Deny-Subnet-Without-Nsg","policyAssignmentName":"Deny-Subnet-Without-Nsg","policyAssignmentScope":"/providers/Microsoft.Management/managementGroups/QSFT-landingzones","policyDefinitionDisplayName":"Subnets > should have a Network Security Group > ","policyDefinitionEffect":"Deny","policyDefinitionId":"/providers/Microsoft.Management/managementGroups/QSFT/providers/Microsoft.Authorization/policyDefinitions/Deny-Subnet-Without-Nsg","policyDefinitionName":"Deny-Subnet-Without-Nsg"},"type":"PolicyViolation"}] > > │ > │ with azurerm_subnet.subnet, > │ on main.tf line 24, in resource "azurerm_subnet" "subnet": > │ 24: resource "azurerm_subnet" "subnet" { > │
我嘗試保持內聯,即 vnet 內的子網。在計劃階段本身從 VM 實例資源塊中引用子網時,問題就出現了。
Error: Unsupported attribute │ │ on network.tf line 26, in resource "azurerm_network_interface" "example": │ 26: subnet_id = azurerm_virtual_network.vnet.subnet.id #azurerm_subnet.subnet.id │ │ Can't access attributes on a set of objects. Did you mean to access an attribute across all elements of the set? ╵
//main.tf
## <https://www.terraform.io/docs/providers/azurerm/r/windows_virtual_machine.html> resource "azurerm_windows_virtual_machine" "example" { name = var.machine_details.name computer_name = var.machine_details.name resource_group_name = azurerm_resource_group.rg.name location = azurerm_resource_group.rg.location size = var.machine_details.size admin_username = var.machine_details.username admin_password = var.machine_details.password network_interface_ids = [ azurerm_network_interface.example.id, ] os_disk { caching = "ReadWrite" storage_account_type = "Standard_LRS" } source_image_reference { publisher = "MicrosoftWindowsServer" offer = "WindowsServer" sku = "2019-Datacenter" version = "latest" } }
//network.tf
## <https://www.terraform.io/docs/providers/azurerm/r/virtual_network.html> resource "azurerm_virtual_network" "vnet" { name = "vNet" address_space = ["10.0.0.0/16"] location = azurerm_resource_group.rg.location resource_group_name = azurerm_resource_group.rg.name subnet{ name = "internal" address_prefix = "10.0.2.0/24" security_group = azurerm_network_security_group.example.id } } ## <https://www.terraform.io/docs/providers/azurerm/r/network_interface.html> resource "azurerm_network_interface" "example" { name = "example-nic" location = azurerm_resource_group.rg.location resource_group_name = azurerm_resource_group.rg.name ip_configuration { name = "internal" subnet_id = azurerm_virtual_network.vnet.subnet.id #azurerm_subnet.subnet.id private_ip_address_allocation = "Dynamic" public_ip_address_id = azurerm_public_ip.myvm1publicip.id } } resource "azurerm_public_ip" "myvm1publicip" { name = var.public_ip.name location = azurerm_resource_group.rg.location resource_group_name = azurerm_resource_group.rg.name allocation_method = var.public_ip.allocation_method sku = var.public_ip.sku } resource "azurerm_network_security_group" "example" { name = var.nsg location = azurerm_resource_group.rg.location resource_group_name = azurerm_resource_group.rg.name security_rule { name = "test123" priority = 100 direction = "Inbound" access = "Allow" protocol = "Tcp" source_port_range = "*" destination_port_range = "*" source_address_prefix = "*" destination_address_prefix = "*" } }
//provider.tf
## <https://www.terraform.io/docs/providers/azurerm/index.html> provider "azurerm" { features {} }
//rg.tf
## <https://www.terraform.io/docs/providers/azurerm/r/resource_group.html> resource "azurerm_resource_group" "rg" { name = "TerraformTesting2" location = var.location }
//variables.tf
variable "location" { type = string description = "Azure Region where all these resources will be provisioned" default = "eastus2" } variable "public_ip" { default = { name = "pip1" allocation_method = "Dynamic" sku = "Basic" } } variable "nsg" { type = string description = "Azure NSG" default = "example-nsg" } variable "machine_details" { default = { name = "example-vm2" size = "Standard_E2s_v3" #"Standard_F2" username = "adminnasme" password = "MyPaword!@3" } }
子網創建失敗,因為它不符合您的管理員應用的策略。這表明子網必須先應用 NSG,然後才能創建它。不幸的是,Terraform 創建資源的方式是先創建子網,然後將 NSG 與其關聯。這是兩個 API 呼叫,第一個呼叫失敗,因為它沒有關聯的 NSG。策略不知道第二個呼叫即將到來以將 NSG 與子網相關聯。
這是 Terraform 在 ARM API 之上建構方式的缺點。除了讓您的管理員放寬此政策外,沒有很好的解決方案。
編輯:
因此,看看這個與您所看到的非常相似的問題,您似乎可以通過在
virtual_network
資源中定義子網而不是作為單獨的子網資源來解決這個問題。使用它,您可以定義 NSG 關聯內聯,這可以在一個單一的 cale 中完成:resource "azurerm_virtual_network" "example" { name = "virtualNetwork1" location = azurerm_resource_group.example.location resource_group_name = azurerm_resource_group.example.name address_space = ["10.0.0.0/16"] dns_servers = ["10.0.0.4", "10.0.0.5"] ddos_protection_plan { id = azurerm_network_ddos_protection_plan.example.id enable = true } subnet { name = "subnet3" address_prefix = "10.0.3.0/24" security_group = azurerm_network_security_group.example.id } tags = { environment = "Production" } }