使用 Terraform 创建虚拟网络流日志

虚拟网络流日志记录通过虚拟网络流转的IP流量信息。 在本文中,你将使用 Terraform 创建虚拟网络流日志和为已有虚拟网络创建专用存储账户。 有关详细信息,请参阅 虚拟网络流日志概述

Terraform 配置使用了 Azure 在启用 网络观察程序 时自动创建的区域 网络观察程序 实例。 你要在 网络观察程序 资源组里创建流量日志和存储账户。

Prerequisites

  • 拥有有效订阅的 Azure 帐户。 创建试用版订阅
  • 安装和配置Terraform
  • 现有虚拟网络。 要创建虚拟网络,请参见 创建虚拟网络
  • 网络观察程序 在虚拟网络区域已启用。 除非你明确禁用,否则默认启用了 网络观察程序。
  • 已在你的订阅中注册的 Microsoft.Insights 资源提供程序。 更多信息请参见 “注册洞察提供商”。
  • 在包含区域网络观察程序实例的资源组中创建流量日志和存储账户的权限。

请查看Terraform配置

您可以在 Azure Terraform GitHub 仓库中找到本文的示例配置。

该配置创建以下资源:

配置还使用网络观察程序数据源来引用现有的区域网络观察程序实例。

  1. 创建一个目录来测试示例的 Terraform 配置,并将其设为当前目录。

  2. 创建名为 providers.tf 的文件并插入以下代码:

    terraform {
      required_version = ">= 1.5.0"
    
      required_providers {
        azurerm = {
          source  = "hashicorp/azurerm"
          version = "~> 5.0"
        }
        random = {
          source  = "hashicorp/random"
          version = "~> 3.7"
        }
      }
    }
    
    provider "azurerm" {
      features {}
    }
    
  3. 创建名为 main.tf 的文件并插入以下代码:

    data "azurerm_network_watcher" "network_watcher" {
      name                = var.network_watcher_name
      resource_group_name = var.network_watcher_resource_group_name
    }
    
    resource "random_string" "storage_account_suffix" {
      length  = 8
      lower   = true
      numeric = true
      special = false
      upper   = false
    }
    
    resource "azurerm_storage_account" "flow_logs" {
      name                     = "flowlogs${random_string.storage_account_suffix.result}"
      resource_group_name      = data.azurerm_network_watcher.network_watcher.resource_group_name
      location                 = data.azurerm_network_watcher.network_watcher.location
      account_tier             = "Standard"
      account_kind             = "StorageV2"
      account_replication_type = var.storage_account_replication_type
    }
    
    resource "azurerm_network_watcher_flow_log" "vnet_flow_log" {
      name                 = var.flow_log_name
      network_watcher_name = data.azurerm_network_watcher.network_watcher.name
      resource_group_name  = data.azurerm_network_watcher.network_watcher.resource_group_name
      location             = data.azurerm_network_watcher.network_watcher.location
    
      target_resource_id = var.virtual_network_id
      storage_account_id = azurerm_storage_account.flow_logs.id
      enabled            = true
      version            = var.flow_log_version
    
      retention_policy {
        enabled = var.retention_days > 0
        days    = var.retention_days
      }
    }
    
  4. 创建名为 variables.tf 的文件并插入以下代码:

    variable "network_watcher_name" {
      type        = string
      default     = "NetworkWatcher_chinaeast2"
      description = "Name of the existing regional Network Watcher instance."
    }
    
    variable "network_watcher_resource_group_name" {
      type        = string
      default     = "NetworkWatcherRG"
      description = "Name of the resource group that contains the Network Watcher instance."
    }
    
    variable "virtual_network_id" {
      type        = string
      description = "Resource ID of the existing virtual network to monitor."
    
      validation {
        condition     = can(regex("(?i)^/subscriptions/[^/]+/resourceGroups/[^/]+/providers/Microsoft.Network/virtualNetworks/[^/]+$", var.virtual_network_id))
        error_message = "The virtual_network_id value must be a full Azure virtual network resource ID."
      }
    }
    
    variable "flow_log_name" {
      type        = string
      default     = "vnet-flow-log"
      description = "Name of the virtual network flow log."
    }
    
    variable "flow_log_version" {
      type        = number
      default     = 2
      description = "Flow log format version. Valid values are 1 and 2."
    
      validation {
        condition     = contains([1, 2], var.flow_log_version)
        error_message = "The flow_log_version value must be 1 or 2."
      }
    }
    
    variable "retention_days" {
      type        = number
      default     = 0
      description = "Number of days to retain flow log data. Use 0 to retain data indefinitely."
    
      validation {
        condition     = var.retention_days >= 0 && var.retention_days <= 365
        error_message = "The retention_days value must be between 0 and 365."
      }
    }
    
    variable "storage_account_replication_type" {
      type        = string
      default     = "LRS"
      description = "Replication type for the flow log storage account."
    
      validation {
        condition     = contains(["LRS", "GRS", "ZRS"], var.storage_account_replication_type)
        error_message = "The storage_account_replication_type value must be LRS, GRS, or ZRS."
      }
    }
    
  5. 创建名为 outputs.tf 的文件并插入以下代码:

    output "flow_log_id" {
      description = "Resource ID of the virtual network flow log."
      value       = azurerm_network_watcher_flow_log.vnet_flow_log.id
    }
    
    output "flow_log_name" {
      description = "Name of the virtual network flow log."
      value       = azurerm_network_watcher_flow_log.vnet_flow_log.name
    }
    
    output "storage_account_name" {
      description = "Name of the storage account that contains the flow log data."
      value       = azurerm_storage_account.flow_logs.name
    }
    

设置现有资源值

创建名为 的文件 terraform.tfvars。 用你现有的虚拟网络和区域 网络观察程序 实例的值替换占位符。

network_watcher_name                = "NetworkWatcher_chinaeast2"
network_watcher_resource_group_name = "NetworkWatcherRG"
virtual_network_id                  = "/subscriptions/<subscription-id>/resourceGroups/<resource-group-name>/providers/Microsoft.Network/virtualNetworks/<virtual-network-name>"

虚拟网络和 网络观察程序 实例必须处于同一 Azure 区域。 如果你的 网络观察程序 实例使用自定义名称或资源组,请更新两个 网络观察程序 值。

初始化 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

验证流量日志

  1. 登录到 Azure 门户

  2. 搜索并选择“网络观察程序”

  3. 在“日志”下,选择“流日志”。

  4. 确认流量日志已启用,且其目标资源是你的虚拟网络。

你也可以显示Terraform输出中的流量日志和存储账户名称:

terraform output flow_log_name
terraform output storage_account_name

清理资源

如果不再需要通过 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 时遇到的常见问题