在本快速入门中,你将使用 Terraform 通过 Azure 防火墙管理器保护虚拟中心。 部署的防火墙具有允许连接到 www.microsoft.com 的应用程序规则。 部署两个 Windows Server 2019 虚拟机来测试防火墙。 一个跳转服务器用于连接到工作负荷服务器。 在工作负荷服务器中,你只能连接到 www.microsoft.com。
有关 Azure 防火墙管理器的详细信息,请参阅什么是 Azure 防火墙管理器?
先决条件
- 拥有有效订阅的 Azure 帐户。 创建试用版订阅。
author:wendiz ms.service:ansible ms.topic:include origin.date:04/30/2019 origin.date:'' author:wendiz ms.date:10/27/2025 ms.author:v-wendyzhang
Azure 订阅:如果没有 Azure 订阅,请在开始之前创建 一个试用订阅 。
查看并实现 Terraform 代码
注释
本文中的示例代码位于 Azure Terraform GitHub 存储库中。 你可以查看包含当前和以前 Terraform 版本的测试结果的日志文件。
查看更多文章和示例代码,演示如何使用 Terraform 管理 Azure 资源
Terraform 代码中定义了多个 Azure 资源。 在 main.tf 文件中定义了以下资源:
- azurerm_resource_group
- azurerm_virtual_wan
- azurerm_virtual_hub
- azurerm_virtual_hub_connection
- azurerm_public_ip
- azurerm_firewall_policy
- azurerm_firewall_policy_rule_collection_group
- azurerm_virtual_network
- azurerm_subnet
- azurerm_network_interface
- azurerm_network_security_group
- azurerm_network_interface_security_group_association
- azurerm_windows_virtual_machine
- azurerm_route_table
- azurerm_子网路由表关联
- azurerm_virtual_hub_route_table
创建用于测试和运行示例 Terraform 代码的目录,并将其设为当前目录。
创建名为
provider.tf的文件并插入下列代码:terraform { required_providers { azurerm = { source = "hashicorp/azurerm" version = "~>3.0" } random = { source = "hashicorp/random" version = "~>3.0" } } } provider "azurerm" { features { virtual_machine { delete_os_disk_on_deletion = true skip_shutdown_and_force_delete = true } } }创建名为
main.tf的文件并插入下列代码:resource "random_pet" "rg-name" { prefix = var.resource_group_name_prefix } resource "azurerm_resource_group" "rg" { name = random_pet.rg-name.id location = var.resource_group_location } resource "azurerm_virtual_wan" "azfw_vwan" { name = "vwan-azfw-securehub-eus" location = azurerm_resource_group.rg.location resource_group_name = azurerm_resource_group.rg.name allow_branch_to_branch_traffic = true disable_vpn_encryption = false } resource "azurerm_virtual_hub" "azfw_vwan_hub" { name = "hub-azfw-securehub-eus" location = azurerm_resource_group.rg.location resource_group_name = azurerm_resource_group.rg.name virtual_wan_id = azurerm_virtual_wan.azfw_vwan.id address_prefix = "10.20.0.0/23" } resource "azurerm_virtual_hub_connection" "azfw_vwan_hub_connection" { name = "hub-to-spoke" virtual_hub_id = azurerm_virtual_hub.azfw_vwan_hub.id remote_virtual_network_id = azurerm_virtual_network.azfw_vnet.id internet_security_enabled = true routing { associated_route_table_id = azurerm_virtual_hub_route_table.vhub_rt.id propagated_route_table { route_table_ids = [azurerm_virtual_hub_route_table.vhub_rt.id] labels = ["VNet"] } } } resource "azurerm_public_ip" "pip_azfw" { name = "pip-azfw-securehub-eus" location = azurerm_resource_group.rg.location resource_group_name = azurerm_resource_group.rg.name allocation_method = "Static" sku = "Standard" } resource "azurerm_firewall_policy" "azfw_policy" { name = "policy-azfw-securehub-eus" resource_group_name = azurerm_resource_group.rg.name location = azurerm_resource_group.rg.location sku = var.firewall_sku_name threat_intelligence_mode = "Alert" } resource "azurerm_firewall_policy_rule_collection_group" "app_policy_rule_collection_group" { name = "DefaulApplicationtRuleCollectionGroup" firewall_policy_id = azurerm_firewall_policy.azfw_policy.id priority = 300 application_rule_collection { name = "DefaultApplicationRuleCollection" action = "Allow" priority = 100 rule { name = "Allow-MSFT" description = "Allow access to Microsoft.com" protocols { type = "Https" port = 443 } protocols { type = "Http" port = 80 } destination_fqdns = ["*.microsoft.com"] terminate_tls = false source_addresses = ["*"] } } } resource "azurerm_firewall" "fw" { name = "fw-azfw-securehub-eus" location = azurerm_resource_group.rg.location resource_group_name = azurerm_resource_group.rg.name sku_name = "AZFW_Hub" sku_tier = var.firewall_sku_name virtual_hub { virtual_hub_id = azurerm_virtual_hub.azfw_vwan_hub.id public_ip_count = 1 } firewall_policy_id = azurerm_firewall_policy.azfw_policy.id } resource "azurerm_virtual_network" "azfw_vnet" { name = "vnet-azfw-securehub-eus" location = azurerm_resource_group.rg.location resource_group_name = azurerm_resource_group.rg.name address_space = ["10.10.0.0/16"] } resource "azurerm_subnet" "workload_subnet" { name = "subnet-workload" resource_group_name = azurerm_resource_group.rg.name virtual_network_name = azurerm_virtual_network.azfw_vnet.name address_prefixes = ["10.10.1.0/24"] } resource "azurerm_subnet" "jump_subnet" { name = "subnet-jump" resource_group_name = azurerm_resource_group.rg.name virtual_network_name = azurerm_virtual_network.azfw_vnet.name address_prefixes = ["10.10.2.0/24"] } resource "azurerm_network_interface" "vm_workload_nic" { name = "nic-workload" location = azurerm_resource_group.rg.location resource_group_name = azurerm_resource_group.rg.name ip_configuration { name = "ipconfig-workload" subnet_id = azurerm_subnet.workload_subnet.id private_ip_address_allocation = "Dynamic" } } resource "azurerm_public_ip" "vm_jump_pip" { name = "pip-jump" location = azurerm_resource_group.rg.location resource_group_name = azurerm_resource_group.rg.name allocation_method = "Static" sku = "Standard" } resource "azurerm_network_interface" "vm_jump_nic" { name = "nic-jump" location = azurerm_resource_group.rg.location resource_group_name = azurerm_resource_group.rg.name ip_configuration { name = "ipconfig-jump" subnet_id = azurerm_subnet.jump_subnet.id private_ip_address_allocation = "Dynamic" public_ip_address_id = azurerm_public_ip.vm_jump_pip.id } } resource "azurerm_network_security_group" "vm_workload_nsg" { name = "nsg-workload" location = azurerm_resource_group.rg.location resource_group_name = azurerm_resource_group.rg.name } resource "azurerm_network_security_group" "vm_jump_nsg" { name = "nsg-jump" location = azurerm_resource_group.rg.location resource_group_name = azurerm_resource_group.rg.name security_rule { name = "Allow-RDP" priority = 300 direction = "Inbound" access = "Allow" protocol = "Tcp" source_port_range = "*" destination_port_range = "3389" source_address_prefix = "*" destination_address_prefix = "*" } } resource "azurerm_network_interface_security_group_association" "vm_workload_nsg_association" { network_interface_id = azurerm_network_interface.vm_workload_nic.id network_security_group_id = azurerm_network_security_group.vm_workload_nsg.id } resource "azurerm_network_interface_security_group_association" "vm_jump_nsg_association" { network_interface_id = azurerm_network_interface.vm_jump_nic.id network_security_group_id = azurerm_network_security_group.vm_jump_nsg.id } resource "azurerm_windows_virtual_machine" "vm_workload" { name = "workload-vm" resource_group_name = azurerm_resource_group.rg.name location = azurerm_resource_group.rg.location size = var.virtual_machine_size admin_username = var.admin_username admin_password = random_password.password.result network_interface_ids = [azurerm_network_interface.vm_workload_nic.id] os_disk { caching = "ReadWrite" storage_account_type = "Standard_LRS" } source_image_reference { publisher = "MicrosoftWindowsServer" offer = "WindowsServer" sku = "2019-Datacenter" version = "latest" } } resource "azurerm_windows_virtual_machine" "vm_jump" { name = "jump-vm" resource_group_name = azurerm_resource_group.rg.name location = azurerm_resource_group.rg.location size = var.virtual_machine_size admin_username = var.admin_username admin_password = random_password.password.result network_interface_ids = [azurerm_network_interface.vm_jump_nic.id] os_disk { caching = "ReadWrite" storage_account_type = "Standard_LRS" } source_image_reference { publisher = "MicrosoftWindowsServer" offer = "WindowsServer" sku = "2019-Datacenter" version = "latest" } } resource "azurerm_route_table" "rt" { name = "rt-azfw-securehub-eus" location = azurerm_resource_group.rg.location resource_group_name = azurerm_resource_group.rg.name disable_bgp_route_propagation = false route { name = "jump-to-internet" address_prefix = "0.0.0.0/0" next_hop_type = "Internet" } } resource "azurerm_subnet_route_table_association" "jump_subnet_rt_association" { subnet_id = azurerm_subnet.jump_subnet.id route_table_id = azurerm_route_table.rt.id } resource "azurerm_virtual_hub_route_table" "vhub_rt" { name = "vhub-rt-azfw-securehub-eus" virtual_hub_id = azurerm_virtual_hub.azfw_vwan_hub.id route { name = "workload-SNToFirewall" destinations_type = "CIDR" destinations = ["10.10.1.0/24"] next_hop_type = "ResourceId" next_hop = azurerm_firewall.fw.id } route { name = "InternetToFirewall" destinations_type = "CIDR" destinations = ["0.0.0.0/0"] next_hop_type = "ResourceId" next_hop = azurerm_firewall.fw.id } labels = ["VNet"] } resource "random_password" "password" { length = 20 min_lower = 1 min_upper = 1 min_numeric = 1 min_special = 1 special = true }创建名为
variables.tf的文件并插入下列代码:variable "resource_group_location" { type = string description = "Location for all resources." default = "chinaeast" } variable "resource_group_name_prefix" { type = string description = "Prefix for the Resource Group Name that's combined with a random id so name is unique in your Azure subcription." default = "rg" } variable "firewall_sku_name" { type = string description = "SKU name for the firewall." default = "Premium" # Valid values are Standard and Premium } variable "virtual_machine_size" { type = string description = "Size of the virtual machine." default = "Standard_D2_v3" } variable "admin_username" { default = "azureuser" }创建一个名为
outputs.tf并插入以下代码的文件,确保将值更新为自己的后端主机名:output "resource_group_name" { value = azurerm_resource_group.rg.name } output "virtual_hub_name" { value = azurerm_virtual_hub.azfw_vwan_hub.name } output "jump_admin_password" { sensitive = true value = azurerm_windows_virtual_machine.vm_jump.admin_password } output "workload_admin_password" { sensitive = true value = azurerm_windows_virtual_machine.vm_workload.admin_password }
初始化 Terraform
运行 terraform init,将 Terraform 部署进行初始化。 此命令下载 Azure 提供程序,以便管理您的 Azure 资源。
terraform init -upgrade
要点:
- 参数
-upgrade可将必要的提供程序插件升级到符合配置版本约束的最新版本。
创建 Terraform 执行计划
运行 terraform plan 以创建执行计划。
terraform plan -out main.tfplan
应用 Terraform 执行计划
运行 terraform apply 以将执行计划应用到您的云基础架构。
terraform apply main.tfplan
要点:
- 示例
terraform apply命令假设你先前运行了terraform plan -out main.tfplan。 - 如果为
-out参数指定了不同的文件名,请在对terraform apply的调用中使用该相同文件名。 - 如果未使用
-out参数,请调用不带任何参数的terraform apply。
清理资源
不再需要通过 Terraform 创建的资源时,请执行以下步骤:
运行 terraform plan 并指定
destroy标志。terraform plan -destroy -out main.destroy.tfplan运行 terraform apply 来应用执行计划。
terraform apply main.destroy.tfplan