次の方法で共有


クイック スタート: Terraform を使用して Azure Application Gateway で Azure Web Application Firewall v2 を構成する

このクイックスタートでは、Terraform を使用して、Azure Web Application Firewall (WAF) v2 ポリシーを使用して Azure Application Gateway を作成します。 Application Gateway は、Azure でスケーラブルで信頼性が高く、セキュリティで保護された Web フロントエンドを作成するための重要なコンポーネントです。Application Gateway は、Web アプリケーションへのトラフィックを管理するのに役立つ Web トラフィック ロード バランサーです。 Application Gateway は、ラウンド ロビン、Cookie ベースのセッションなどを含む要因に基づいてトラフィックをルーティングする方法をベースとしています。 Application Gateway に加えて、このコードでは、リソース グループ、仮想ネットワーク、仮想ネットワーク内のサブネット、パブリック IP アドレス、および特定の IP アドレスからのトラフィックをブロックするカスタム 規則を含む WAF ポリシーも作成します。

Terraformはクラウドインフラストラクチャの定義、プレビュー、そしてデプロイメントを可能にします。 Terraform を使用する際は、HCL 構文を使って構成ファイルを作成します。 HCL 構文を使用すると、クラウド プロバイダー (Azure など) とクラウド インフラストラクチャを構成する要素を指定できます。 あなたの設定ファイルを作成した後、実行計画を作成します。これにより、インフラストラクチャの変更をデプロイする前にプレビューすることができます。 変更を確認したら、実行プランを適用してインフラストラクチャをデプロイします。

  • WAF カスタム規則でブロックする必要がある IP アドレスを定義します。
  • 一意の名前を持つ Azure リソース グループを作成します。
  • 特定の名前とアドレスを持つ仮想ネットワークを確立します。
  • サブネットのランダムな名前を生成し、仮想ネットワークにサブネットを作成します。
  • パブリック IP アドレスを生成します。
  • WAF ポリシーを作成します。
  • 設定を構成し、WAF ポリシーの管理規則を定義します。
  • 特定の IP アドレスからのトラフィックをブロックするカスタム ルールを作成します。
  • Application Gateway を設定します。
  • Application Gateway の SKU と容量を構成します。
  • Application Gateway の自動スケールを有効にします。
  • ゲートウェイの IP 設定を構成します。
  • フロントエンド IP 構成を設定し、フロントエンド ポートを定義します。
  • IP アドレスを使用してバックエンド アドレス プールを定義し、バックエンドの HTTP 設定を構成します。
  • HTTP リスナーを定義します。
  • 要求ルーティング規則を定義します。
  • WAF ポリシーを Application Gateway に関連付けます。
  • リソース グループ名、パブリック IP アドレス、Application Gateway ID、WAF ポリシー ID、および Application Gateway を出力します。

[前提条件]

Terraform コードを実装する

この記事のサンプル コードは、 Azure Terraform GitHub リポジトリにあります。 Terraform の現在および以前のバージョンからのテスト結果を含むログ ファイルを表示できます。 Terraform を使用して Azure リソースを管理する方法を示すその他の記事とサンプル コードを参照してください。

  1. サンプル Terraform コードをテストして実行するディレクトリを作成し、それを現在のディレクトリにします。

  2. main.tf という名前のファイルを作成し、次のコードを挿入します。

    # Create random pet name for resource group
    resource "random_pet" "rg_name" {
      prefix = var.resource_group_name_prefix
    }
    
    # Create resource group
    resource "azurerm_resource_group" "example" {
      location = var.resource_group_location
      name     = random_pet.rg_name.id
    }
    
    # Create a virtual network
    resource "azurerm_virtual_network" "example" {
      name                = "example-vnet"
      address_space       = ["10.0.0.0/16"]
      location            = azurerm_resource_group.example.location
      resource_group_name = azurerm_resource_group.example.name
    }
    
    # Create a subnet within the virtual network
    resource "azurerm_subnet" "example" {
      name                 = "example-subnet"
      resource_group_name  = azurerm_resource_group.example.name
      virtual_network_name = azurerm_virtual_network.example.name
      address_prefixes     = ["10.0.1.0/24"]
    }
    
    # Create a public IP address
    resource "azurerm_public_ip" "example" {
      name                = "example-pip"
      location            = azurerm_resource_group.example.location
      resource_group_name = azurerm_resource_group.example.name
      allocation_method   = "Static"
      sku                 = "Standard"
    }
    
    # Create a Web Application Firewall (WAF) policy
    resource "azurerm_web_application_firewall_policy" "example" {
      name                = "example-waf-policy"
      resource_group_name = azurerm_resource_group.example.name
      location            = azurerm_resource_group.example.location
    
      # Configure the policy settings
      policy_settings {
        enabled                                   = false
        file_upload_limit_in_mb                   = 100
        js_challenge_cookie_expiration_in_minutes = 5
        max_request_body_size_in_kb               = 128
        mode                                      = "Detection"
        request_body_check                        = true
        request_body_inspect_limit_in_kb          = 128
      }
    
      # Define managed rules for the WAF policy
      managed_rules {
        managed_rule_set {
          type    = "OWASP"
          version = "3.2"
        }
      }
    
      # Define a custom rule to block traffic from a specific IP address
      custom_rules {
        name      = "BlockSpecificIP"
        priority  = 1
        rule_type = "MatchRule"
    
        match_conditions {
          match_variables {
            variable_name = "RemoteAddr"
          }
          operator           = "IPMatch"
          negation_condition = false
          match_values       = ["192.168.1.1"] # Replace with the IP address to block
        }
    
        action = "Block"
      }
    }
    
    # Create the Application Gateway
    resource "azurerm_application_gateway" "example" {
      name                = "example-appgw"
      location            = azurerm_resource_group.example.location
      resource_group_name = azurerm_resource_group.example.name
    
      # Configure the SKU and capacity
      sku {
        name = "WAF_v2"
        tier = "WAF_v2"
      }
    
      # Enable autoscaling (optional)
      autoscale_configuration {
        min_capacity = 2
        max_capacity = 10
      }
    
      # Configure the gateway's IP settings
      gateway_ip_configuration {
        name      = "appgw-ip-config"
        subnet_id = azurerm_subnet.example.id
      }
    
      # Configure the frontend IP
      frontend_ip_configuration {
        name                 = "appgw-frontend-ip"
        public_ip_address_id = azurerm_public_ip.example.id
      }
    
      # Define the frontend port
      frontend_port {
        name = "appgw-frontend-port"
        port = 80
      }
    
      # Define the backend address pool with IP addresses
      backend_address_pool {
        name         = "appgw-backend-pool"
        ip_addresses = ["10.0.2.4"] # Replace with your backend IP addresses
      }
    
      # Configure backend HTTP settings
      backend_http_settings {
        name                  = "appgw-backend-http-settings"
        cookie_based_affinity = "Disabled"
        port                  = 80
        protocol              = "Http"
        request_timeout       = 20
      }
    
      # Define the HTTP listener
      http_listener {
        name                           = "appgw-http-listener"
        frontend_ip_configuration_name = "appgw-frontend-ip"
        frontend_port_name             = "appgw-frontend-port"
        protocol                       = "Http"
      }
    
      # Define the request routing rule
      request_routing_rule {
        name                       = "appgw-routing-rule"
        priority                   = 9
        rule_type                  = "Basic"
        http_listener_name         = "appgw-http-listener"
        backend_address_pool_name  = "appgw-backend-pool"
        backend_http_settings_name = "appgw-backend-http-settings"
      }
    
      # Associate the WAF policy with the Application Gateway
      waf_configuration {
        enabled          = true
        firewall_mode    = "Prevention"
        rule_set_type    = "OWASP"
        rule_set_version = "3.2"
      }
    }
    
  3. outputs.tf という名前のファイルを作成し、次のコードを挿入します。

    output "resource_group_name" {
      value = azurerm_resource_group.example
    }
    
    output "public_ip_address" {
      value = azurerm_public_ip.example.ip_address
    }
    
    output "application_gateway_id" {
      value = azurerm_application_gateway.example.id
    }
    
    output "web_application_firewall_policy_id" {
      value = azurerm_web_application_firewall_policy.example.id
    }
    
  4. providers.tf という名前のファイルを作成し、次のコードを挿入します。

    terraform {
      required_providers {
        azurerm = {
          source  = "hashicorp/azurerm"
          version = "~>3.0"
        }
        random = {
          source  = "hashicorp/random"
          version = "~>3.0"
        }
      }
    }
    
    provider "azurerm" {
      features {
        resource_group {
          prevent_deletion_if_contains_resources = false
        }
      }
    }
    
  5. variables.tf という名前のファイルを作成し、次のコードを挿入します。

    variable "resource_group_location" {
      type        = string
      default     = "West Europe"
      description = "Location of the resource group."
    }
    
    variable "resource_group_name_prefix" {
      type        = string
      default     = "rg"
      description = "Prefix of the resource group name that's combined with a random ID so name is unique in your Azure subscription."
    }
    
    variable "blocked_ip_address" {
      type        = string
      default     = ""
      description = "The IP address to be blocked by the WAF custom rule."
    }
    

重要

4.x azurerm プロバイダーを使用している場合は、Terraform コマンドを実行する前に、Azure に対して認証する Azure サブスクリプション ID を明示的に指定 する必要があります。

azure サブスクリプション ID を providers ブロックに入れずに指定する 1 つの方法は、 ARM_SUBSCRIPTION_IDという名前の環境変数にサブスクリプション ID を指定することです。

詳細については、 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 リソース グループ名を取得します。

    resource_group_name=$(terraform output -raw resource_group_name)
    
  2. パブリック IP アドレスを取得します。

    public_ip_address=$(terraform output -raw public_ip_address)
    
  3. WAF ポリシー ID を取得します。

    web_application_firewall_policy_id=$(terraform output -raw web_application_firewall_policy_id)
    
  4. Application Gateway ID を取得します。

    application_gateway_id=$(terraform output -raw application_gateway_id)
    
  5. az network application-gateway showを実行して、Application Gateway を表示します。

    az appservice ase show --name $application_gateway_name --resource-group $resource_group_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 を使用する場合の一般的な問題のトラブルシューティング