閱讀英文

共用方式為


快速入門:使用 Azure 防火牆 Manager 保護虛擬中樞 - Terraform

在本快速入門中,您會使用 Terraform,使用 Azure 防火牆 Manager 保護您的虛擬中樞。 已部署的防火牆具有允許連線到 www.microsoft.com 的應用程式規則。 已部署兩部 Windows Server 2019 虛擬機器來測試防火牆。 一部跳躍伺服器用來連線到工作負載伺服器。 從工作負載伺服器,您只能連線到 www.microsoft.com

如需 Azure 防火牆管理員的詳細資訊,請參閱什麼是 Azure 防火牆管理員?

必要條件

  • Azure 訂用帳戶:如果您沒有 Azure 訂用帳戶,請在開始前建立免費帳戶

檢閱並實作 Terraform 程式碼

注意

本文中的範例程式碼位於 Azure Terraform GitHub 存放庫 (英文)。 您可以檢視記錄檔,內含目前和舊版 Terraform 的測試結果 (英文)。

請參閱更多文章和範例程式碼,其中顯示如何使用 Terraform 來管理 Azure 資源

Terraform 程式碼中定義了多個 Azure 資源。 main.tf 檔案中會定義下列資源:

  1. 建立目錄,然後在目錄中測試範例 Terraform 程式碼,並將其設為目前的目錄。

  2. 建立名為 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
        }
      }
    }
    
  3. 建立名為 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
    }
    
  4. 建立名為 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"
    }
    
  5. 建立名為 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 plan 命令會建立執行計畫,但不會執行。 相反地,其會決定要在您指定的設定檔中建立設定所需的動作。 此模式可讓您在對實際資源進行任何變更之前,先確認執行方案是否符合您的預期。
  • 選用的 -out 參數可讓您指定計畫的輸出檔。 使用 -out 參數可確保您所檢閱的方案就是所套用的方案。

套用 Terraform 執行計畫

執行 terraform apply 將執行計畫套用至您的雲端基礎結構。

terraform apply main.tfplan

重點︰

  • 範例 terraform apply 命令會假設您先前已執行 terraform plan -out main.tfplan
  • 如果您為 -out 參數指定了不同的檔案名稱,請在呼叫 terraform apply 時使用該檔案名稱。
  • 若您未使用 -out 參數,請呼叫 terraform apply,不需要使用參數。

清除資源

當您不再需要透過 Terraform 建立的資源時,請執行下列步驟:

  1. 執行 terraform plan 並指定 destroy 旗標。

    terraform plan -destroy -out main.destroy.tfplan
    

    重點︰

    • terraform plan 命令會建立執行計畫,但不會執行。 相反地,其會決定要在您指定的設定檔中建立設定所需的動作。 此模式可讓您在對實際資源進行任何變更之前,先確認執行方案是否符合您的預期。
    • 選用的 -out 參數可讓您指定計畫的輸出檔。 使用 -out 參數可確保您所檢閱的方案就是所套用的方案。
  2. 執行 terraform apply 以套用執行方案。

    terraform apply main.destroy.tfplan
    

對 Azure 上的 Terraform 進行疑難排解

針對在 Azure 上使用 Terraform 時的常見問題進行疑難排解

下一步