快速入門:使用 Azure 防火牆 Manager 保護虛擬中樞 - Terraform
在本快速入門中,您會使用 Terraform,使用 Azure 防火牆 Manager 保護您的虛擬中樞。 已部署的防火牆具有允許連線到 www.microsoft.com
的應用程式規則。 已部署兩部 Windows Server 2019 虛擬機器來測試防火牆。 一部跳躍伺服器用來連線到工作負載伺服器。 從工作負載伺服器,您只能連線到 www.microsoft.com
。
如需 Azure 防火牆管理員的詳細資訊,請參閱什麼是 Azure 防火牆管理員?。
- 具有有效訂用帳戶的 Azure 帳戶。 免費建立帳戶。
- Azure 訂用帳戶:如果您沒有 Azure 訂用帳戶,請在開始前建立免費帳戶。
注意
本文中的範例程式碼位於 Azure Terraform GitHub 存放庫 (英文)。 您可以檢視記錄檔,內含目前和舊版 Terraform 的測試結果 (英文)。
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_subnet_route_table_association
- 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 = "eastus" } 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 init 來初始化 Terraform 部署。 此命令會下載管理 Azure 資源所需的 Azure 提供者。
terraform init -upgrade
重點︰
-upgrade
參數會將必要的提供者外掛程式升級至符合設定版本條件約束的最新版本。
執行 terraform plan 以建立執行計畫。
terraform plan -out main.tfplan
重點︰
terraform plan
命令會建立執行計畫,但不會執行。 相反地,其會決定要在您指定的設定檔中建立設定所需的動作。 此模式可讓您在對實際資源進行任何變更之前,先確認執行方案是否符合您的預期。- 選用的
-out
參數可讓您指定計畫的輸出檔。 使用-out
參數可確保您所檢閱的方案就是所套用的方案。
執行 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 plan
命令會建立執行計畫,但不會執行。 相反地,其會決定要在您指定的設定檔中建立設定所需的動作。 此模式可讓您在對實際資源進行任何變更之前,先確認執行方案是否符合您的預期。- 選用的
-out
參數可讓您指定計畫的輸出檔。 使用-out
參數可確保您所檢閱的方案就是所套用的方案。
執行 terraform apply 以套用執行方案。
terraform apply main.destroy.tfplan