我正在尝试在 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"
}
}
//网络.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 = "*"
}
}
//提供者.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
}
//变量.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 中完成:面对同样的问题,我们使用“审核”操作而不是“拒绝”重新分配了策略。如果您有权限这样做。