快速入门:创建 Azure 防火墙和防火墙策略 - Terraform

在本快速入门中,你将使用 Terraform 创建 Azure 防火墙和防火墙策略。 防火墙策略具有一个应用程序规则,允许连接到 www.microsoft.com,以及一个使用 WindowsUpdate FQDN 标记允许连接到 Windows 更新的规则。 网络规则允许 UDP 连接到 13.86.101.172 的时间服务器。

此外,IP 组在规则中用于定义 IP 地址。

Hashicorp Terraform 是一种开源 IaC(基础结构即代码)工具,用于预配和管理云基础结构。 它在描述拓扑所需状态的配置文件中编写基础结构。 Terraform 允许使用 Terraform 提供程序管理任何基础结构,例如公有云、私有云和 SaaS 服务。

有关 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 {}
    }
    
    
  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_network" "azfw_vnet" {
      name                = "azfw-vnet"
      location            = azurerm_resource_group.rg.location
      resource_group_name = azurerm_resource_group.rg.name
      address_space       = ["10.10.0.0/24"]
    }
    
    resource "azurerm_ip_group" "workload_ip_group" {
      name                = "workload-ip-group"
      resource_group_name = azurerm_resource_group.rg.name
      location            = azurerm_resource_group.rg.location
      cidrs               = ["10.20.0.0/24", "10.30.0.0/24"]
    }
    resource "azurerm_ip_group" "infra_ip_group" {
      name                = "infra-ip-group"
      resource_group_name = azurerm_resource_group.rg.name
      location            = azurerm_resource_group.rg.location
      cidrs               = ["10.40.0.0/24", "10.50.0.0/24"]
    }
    
    resource "azurerm_subnet" "azfw_subnet" {
      name                 = "AzureFirewallSubnet"
      resource_group_name  = azurerm_resource_group.rg.name
      virtual_network_name = azurerm_virtual_network.azfw_vnet.name
      address_prefixes     = ["10.10.0.0/26"]
    }
    
    resource "azurerm_public_ip" "pip_azfw" {
      name                = "pip-azfw"
      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                     = "azfw-policy"
      resource_group_name      = azurerm_resource_group.rg.name
      location                 = azurerm_resource_group.rg.location
      sku                      = var.firewall_sku_tier
      threat_intelligence_mode = "Alert"
    }
    
    resource "azurerm_firewall_policy_rule_collection_group" "net_policy_rule_collection_group" {
      name               = "DefaultNetworkRuleCollectionGroup"
      firewall_policy_id = azurerm_firewall_policy.azfw_policy.id
      priority           = 200
      network_rule_collection {
        name     = "DefaultNetworkRuleCollection"
        action   = "Allow"
        priority = 200
        rule {
          name                  = "time-windows"
          protocols             = ["UDP"]
          source_ip_groups      = [azurerm_ip_group.workload_ip_group.id, azurerm_ip_group.infra_ip_group.id]
          destination_ports     = ["123"]
          destination_addresses = ["132.86.101.172"]
        }
      }
    }
    
    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 = 500
        rule {
          name = "AllowWindowsUpdate"
    
          description = "Allow Windows Update"
          protocols {
            type = "Http"
            port = 80
          }
          protocols {
            type = "Https"
            port = 443
          }
          source_ip_groups      = [azurerm_ip_group.workload_ip_group.id, azurerm_ip_group.infra_ip_group.id]
          destination_fqdn_tags = ["WindowsUpdate"]
        }
        rule {
          name        = "Global Rule"
          description = "Allow access to Microsoft.com"
          protocols {
            type = "Https"
            port = 443
          }
          destination_fqdns = ["*.microsoft.com"]
          terminate_tls     = false
          source_ip_groups  = [azurerm_ip_group.workload_ip_group.id, azurerm_ip_group.infra_ip_group.id]
        }
      }
    }
    
    resource "azurerm_firewall" "fw" {
      name                = "azfw"
      location            = azurerm_resource_group.rg.location
      resource_group_name = azurerm_resource_group.rg.name
      sku_name            = "AZFW_VNet"
      sku_tier            = var.firewall_sku_tier
      ip_configuration {
        name                 = "azfw-ipconfig"
        subnet_id            = azurerm_subnet.azfw_subnet.id
        public_ip_address_id = azurerm_public_ip.pip_azfw.id
      }
      firewall_policy_id = azurerm_firewall_policy.azfw_policy.id
    }
    
  4. 创建名为 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_tier" {
      type        = string
      description = "Firewall SKU."
      default     = "Premium" # Valid values are Standard and Premium
      validation {
        condition = contains(["Standard", "Premium"], var.firewall_sku_tier)
        error_message = "The sku must be one of the following: Standard, Premium"
      }
    }
    
    
  5. 创建一个名为 outputs.tf 并插入以下代码的文件,确保将值更新为自己的后端主机名:

    output "resource_group_name" {
      value = azurerm_resource_group.rg.name
    }
    
    output "firewall_name" {
      value = azurerm_firewall.fw.name
    }
    

初始化 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 创建的资源时,请执行以下步骤:

  1. 运行 terraform plan 并指定 destroy 标志。

    terraform plan -destroy -out main.destroy.tfplan
    
  2. 运行 terraform apply 来应用执行计划。

    terraform apply main.destroy.tfplan
    

后续步骤