クイック スタート: ARM テンプレートを使用して Azure Web Application Firewall v2 を作成する

このクイックスタートでは、Azure Resource Manager テンプレート (ARM テンプレート) を使用して、Azure Application Gateway に Azure Web アプリケーション ファイアウォール (WAF) v2 を作成します。

Azure Resource Manager テンプレートは JavaScript Object Notation (JSON) ファイルであり、プロジェクトのインフラストラクチャと構成が定義されています。 このテンプレートでは、宣言型の構文が使用されています。 デプロイしようとしているものを、デプロイを作成する一連のプログラミング コマンドを記述しなくても記述できます。

環境が前提条件を満たしていて、ARM テンプレートの使用に慣れている場合は、[Azure へのデプロイ] ボタンを選んで Azure portal でテンプレートを開くことができます。

Resource Manager テンプレートを Azure にデプロイするボタン。

前提条件

テンプレートを確認する

このテンプレートは、Azure Application Gateway に 単純な Web アプリケーション ファイアウォール v2 を作成します。 このテンプレートでは、パブリック IP フロントエンド IP アドレス、HTTP 設定、ポート 80 の基本リスナーのルール、バックエンド プールが作成されます。 カスタム ルールを含む WAF ポリシーは、IP アドレスの一致の種類に基づいて、バックエンド プールへのトラフィックをブロックします。

このテンプレートでは、次の Azure リソースが定義されています。

このテンプレートは、Azure クイックスタート テンプレートからのものです。

{
  "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
  "contentVersion": "1.0.0.0",
  "metadata": {
    "_generator": {
      "name": "bicep",
      "version": "0.15.31.15270",
      "templateHash": "7253194970749033988"
    }
  },
  "parameters": {
    "adminUsername": {
      "type": "string",
      "metadata": {
        "description": "Admin username for the backend servers"
      }
    },
    "adminPassword": {
      "type": "securestring",
      "metadata": {
        "description": "Password for the admin account on the backend servers"
      }
    },
    "location": {
      "type": "string",
      "defaultValue": "[resourceGroup().location]",
      "metadata": {
        "description": "Location for all resources."
      }
    },
    "vmSize": {
      "type": "string",
      "defaultValue": "Standard_B2ms",
      "metadata": {
        "description": "Size of the virtual machine."
      }
    }
  },
  "variables": {
    "virtualMachines_myVM_name": "myVM",
    "virtualNetworks_myVNet_name": "myVNet",
    "myNic_name": "net-int",
    "ipconfig_name": "ipconfig",
    "publicIPAddress_name": "public_ip",
    "nsg_name": "vm-nsg",
    "applicationGateways_myAppGateway_name": "myAppGateway",
    "vnet_prefix": "10.0.0.0/16",
    "ag_subnet_prefix": "10.0.0.0/24",
    "backend_subnet_prefix": "10.0.1.0/24",
    "AppGW_AppFW_Pol_name": "WafPol01"
  },
  "resources": [
    {
      "copy": {
        "name": "nsg",
        "count": "[length(range(0, 2))]"
      },
      "type": "Microsoft.Network/networkSecurityGroups",
      "apiVersion": "2021-08-01",
      "name": "[format('{0}{1}', variables('nsg_name'), add(range(0, 2)[copyIndex()], 1))]",
      "location": "[parameters('location')]",
      "properties": {
        "securityRules": [
          {
            "name": "RDP",
            "properties": {
              "protocol": "Tcp",
              "sourcePortRange": "*",
              "destinationPortRange": "3389",
              "sourceAddressPrefix": "*",
              "destinationAddressPrefix": "*",
              "access": "Allow",
              "priority": 300,
              "direction": "Inbound"
            }
          }
        ]
      }
    },
    {
      "copy": {
        "name": "publicIPAddress",
        "count": "[length(range(0, 3))]"
      },
      "type": "Microsoft.Network/publicIPAddresses",
      "apiVersion": "2021-08-01",
      "name": "[format('{0}{1}', variables('publicIPAddress_name'), range(0, 3)[copyIndex()])]",
      "location": "[parameters('location')]",
      "sku": {
        "name": "Standard"
      },
      "properties": {
        "publicIPAddressVersion": "IPv4",
        "publicIPAllocationMethod": "Static",
        "idleTimeoutInMinutes": 4
      }
    },
    {
      "type": "Microsoft.Network/virtualNetworks",
      "apiVersion": "2021-08-01",
      "name": "[variables('virtualNetworks_myVNet_name')]",
      "location": "[parameters('location')]",
      "properties": {
        "addressSpace": {
          "addressPrefixes": [
            "[variables('vnet_prefix')]"
          ]
        },
        "subnets": [
          {
            "name": "myAGSubnet",
            "properties": {
              "addressPrefix": "[variables('ag_subnet_prefix')]",
              "privateEndpointNetworkPolicies": "Enabled",
              "privateLinkServiceNetworkPolicies": "Enabled"
            }
          },
          {
            "name": "myBackendSubnet",
            "properties": {
              "addressPrefix": "[variables('backend_subnet_prefix')]",
              "privateEndpointNetworkPolicies": "Enabled",
              "privateLinkServiceNetworkPolicies": "Enabled"
            }
          }
        ],
        "enableDdosProtection": false,
        "enableVmProtection": false
      }
    },
    {
      "copy": {
        "name": "myVM",
        "count": "[length(range(0, 2))]"
      },
      "type": "Microsoft.Compute/virtualMachines",
      "apiVersion": "2021-11-01",
      "name": "[format('{0}{1}', variables('virtualMachines_myVM_name'), add(range(0, 2)[copyIndex()], 1))]",
      "location": "[parameters('location')]",
      "properties": {
        "hardwareProfile": {
          "vmSize": "[parameters('vmSize')]"
        },
        "storageProfile": {
          "imageReference": {
            "publisher": "MicrosoftWindowsServer",
            "offer": "WindowsServer",
            "sku": "2019-Datacenter",
            "version": "latest"
          },
          "osDisk": {
            "osType": "Windows",
            "createOption": "FromImage",
            "caching": "ReadWrite",
            "managedDisk": {
              "storageAccountType": "StandardSSD_LRS"
            },
            "diskSizeGB": 127
          }
        },
        "osProfile": {
          "computerName": "[format('{0}{1}', variables('virtualMachines_myVM_name'), add(range(0, 2)[copyIndex()], 1))]",
          "adminUsername": "[parameters('adminUsername')]",
          "adminPassword": "[parameters('adminPassword')]",
          "windowsConfiguration": {
            "provisionVMAgent": true,
            "enableAutomaticUpdates": true
          },
          "allowExtensionOperations": true
        },
        "networkProfile": {
          "networkInterfaces": [
            {
              "id": "[resourceId('Microsoft.Network/networkInterfaces', format('{0}{1}', variables('myNic_name'), add(range(0, 2)[copyIndex()], 1)))]"
            }
          ]
        }
      },
      "dependsOn": [
        "myNic"
      ]
    },
    {
      "copy": {
        "name": "myVM_IIS",
        "count": "[length(range(0, 2))]"
      },
      "type": "Microsoft.Compute/virtualMachines/extensions",
      "apiVersion": "2021-11-01",
      "name": "[format('{0}{1}/IIS', variables('virtualMachines_myVM_name'), add(range(0, 2)[copyIndex()], 1))]",
      "location": "[parameters('location')]",
      "properties": {
        "autoUpgradeMinorVersion": true,
        "publisher": "Microsoft.Compute",
        "type": "CustomScriptExtension",
        "typeHandlerVersion": "1.4",
        "settings": {
          "commandToExecute": "powershell Add-WindowsFeature Web-Server; powershell Add-Content -Path \"C:\\inetpub\\wwwroot\\Default.htm\" -Value $($env:computername)"
        }
      },
      "dependsOn": [
        "myVM"
      ]
    },
    {
      "type": "Microsoft.Network/applicationGateways",
      "apiVersion": "2021-08-01",
      "name": "[variables('applicationGateways_myAppGateway_name')]",
      "location": "[parameters('location')]",
      "properties": {
        "sku": {
          "name": "WAF_v2",
          "tier": "WAF_v2",
          "capacity": 2
        },
        "gatewayIPConfigurations": [
          {
            "name": "appGatewayIpConfig",
            "properties": {
              "subnet": {
                "id": "[resourceId('Microsoft.Network/virtualNetworks/subnets', variables('virtualNetworks_myVNet_name'), 'myAGSubnet')]"
              }
            }
          }
        ],
        "frontendIPConfigurations": [
          {
            "name": "appGwPublicFrontendIp",
            "properties": {
              "privateIPAllocationMethod": "Dynamic",
              "publicIPAddress": {
                "id": "[resourceId('Microsoft.Network/publicIPAddresses', format('{0}0', variables('publicIPAddress_name')))]"
              }
            }
          }
        ],
        "frontendPorts": [
          {
            "name": "port_80",
            "properties": {
              "port": 80
            }
          }
        ],
        "backendAddressPools": [
          {
            "name": "myBackendPool",
            "properties": {}
          }
        ],
        "backendHttpSettingsCollection": [
          {
            "name": "myHTTPSetting",
            "properties": {
              "port": 80,
              "protocol": "Http",
              "cookieBasedAffinity": "Disabled",
              "pickHostNameFromBackendAddress": false,
              "requestTimeout": 20
            }
          }
        ],
        "httpListeners": [
          {
            "name": "myListener",
            "properties": {
              "firewallPolicy": {
                "id": "[resourceId('Microsoft.Network/ApplicationGatewayWebApplicationFirewallPolicies', variables('AppGW_AppFW_Pol_name'))]"
              },
              "frontendIPConfiguration": {
                "id": "[resourceId('Microsoft.Network/applicationGateways/frontendIPConfigurations', variables('applicationGateways_myAppGateway_name'), 'appGwPublicFrontendIp')]"
              },
              "frontendPort": {
                "id": "[resourceId('Microsoft.Network/applicationGateways/frontendPorts', variables('applicationGateways_myAppGateway_name'), 'port_80')]"
              },
              "protocol": "Http",
              "requireServerNameIndication": false
            }
          }
        ],
        "requestRoutingRules": [
          {
            "name": "myRoutingRule",
            "properties": {
              "ruleType": "Basic",
              "priority": 10,
              "httpListener": {
                "id": "[resourceId('Microsoft.Network/applicationGateways/httpListeners', variables('applicationGateways_myAppGateway_name'), 'myListener')]"
              },
              "backendAddressPool": {
                "id": "[resourceId('Microsoft.Network/applicationGateways/backendAddressPools', variables('applicationGateways_myAppGateway_name'), 'myBackendPool')]"
              },
              "backendHttpSettings": {
                "id": "[resourceId('Microsoft.Network/applicationGateways/backendHttpSettingsCollection', variables('applicationGateways_myAppGateway_name'), 'myHTTPSetting')]"
              }
            }
          }
        ],
        "enableHttp2": false,
        "firewallPolicy": {
          "id": "[resourceId('Microsoft.Network/ApplicationGatewayWebApplicationFirewallPolicies', variables('AppGW_AppFW_Pol_name'))]"
        }
      },
      "dependsOn": [
        "[resourceId('Microsoft.Network/ApplicationGatewayWebApplicationFirewallPolicies', variables('AppGW_AppFW_Pol_name'))]",
        "[resourceId('Microsoft.Network/virtualNetworks', variables('virtualNetworks_myVNet_name'))]",
        "publicIPAddress"
      ]
    },
    {
      "type": "Microsoft.Network/ApplicationGatewayWebApplicationFirewallPolicies",
      "apiVersion": "2021-08-01",
      "name": "[variables('AppGW_AppFW_Pol_name')]",
      "location": "[parameters('location')]",
      "properties": {
        "customRules": [
          {
            "name": "CustRule01",
            "priority": 100,
            "ruleType": "MatchRule",
            "action": "Block",
            "matchConditions": [
              {
                "matchVariables": [
                  {
                    "variableName": "RemoteAddr"
                  }
                ],
                "operator": "IPMatch",
                "negationConditon": true,
                "matchValues": [
                  "10.10.10.0/24"
                ]
              }
            ]
          }
        ],
        "policySettings": {
          "requestBodyCheck": true,
          "maxRequestBodySizeInKb": 128,
          "fileUploadLimitInMb": 100,
          "state": "Enabled",
          "mode": "Prevention"
        },
        "managedRules": {
          "managedRuleSets": [
            {
              "ruleSetType": "OWASP",
              "ruleSetVersion": "3.1"
            }
          ]
        }
      }
    },
    {
      "copy": {
        "name": "myNic",
        "count": "[length(range(0, 2))]"
      },
      "type": "Microsoft.Network/networkInterfaces",
      "apiVersion": "2021-08-01",
      "name": "[format('{0}{1}', variables('myNic_name'), add(range(0, 2)[copyIndex()], 1))]",
      "location": "[parameters('location')]",
      "properties": {
        "ipConfigurations": [
          {
            "name": "[format('{0}{1}', variables('ipconfig_name'), add(range(0, 2)[copyIndex()], 1))]",
            "properties": {
              "privateIPAllocationMethod": "Dynamic",
              "publicIPAddress": {
                "id": "[resourceId('Microsoft.Network/publicIPAddresses', format('{0}{1}', variables('publicIPAddress_name'), add(range(0, 2)[copyIndex()], 1)))]"
              },
              "subnet": {
                "id": "[resourceId('Microsoft.Network/virtualNetworks/subnets', variables('virtualNetworks_myVNet_name'), 'myBackendSubnet')]"
              },
              "primary": true,
              "privateIPAddressVersion": "IPv4",
              "applicationGatewayBackendAddressPools": [
                {
                  "id": "[resourceId('Microsoft.Network/applicationGateways/backendAddressPools', variables('applicationGateways_myAppGateway_name'), 'myBackendPool')]"
                }
              ]
            }
          }
        ],
        "enableAcceleratedNetworking": false,
        "enableIPForwarding": false,
        "networkSecurityGroup": {
          "id": "[resourceId('Microsoft.Network/networkSecurityGroups', format('{0}{1}', variables('nsg_name'), add(range(0, 2)[copyIndex()], 1)))]"
        }
      },
      "dependsOn": [
        "[resourceId('Microsoft.Network/applicationGateways', variables('applicationGateways_myAppGateway_name'))]",
        "[resourceId('Microsoft.Network/virtualNetworks', variables('virtualNetworks_myVNet_name'))]",
        "nsg",
        "publicIPAddress"
      ]
    }
  ]
}

テンプレートのデプロイ

ARM テンプレートを Azure にデプロイします。

  1. [Azure に配置する] を選択して Azure にサインインし、テンプレートを開きます。 このテンプレートにより、アプリケーション ゲートウェイ、ネットワーク インフラストラクチャ、IIS を実行するバックエンドプール内の 2 つの VM が作成されます。

    Resource Manager テンプレートを Azure にデプロイするボタン。

  2. リソース グループを選択または作成します。

  3. [確認および作成] を選択し、検証に成功したら [作成] を選択します。 このデプロイの完了には、10 分以上かかる場合があります。

デプロイの検証

IIS は必要ありませんが、Azure によってアプリケーション ゲートウェイ上に WAF v2 が正常に作成されたことを確認できるよう、テンプレートによってバックエンド サーバーに IIS がインストールされます。

IIS を使用してアプリケーション ゲートウェイをテストします。

  1. [概要] ページから、アプリケーション ゲートウェイのパブリック IP アドレスをコピーします。

    アプリケーション ゲートウェイのパブリック IP アドレスを示すスクリーンショット。

    Azure の検索ボックスで "アプリケーション ゲートウェイ" を検索することもできます。 アプリケーション ゲートウェイの一覧の [パブリック IP アドレス] 列に、パブリック IP アドレスが表示されます。

  2. IP アドレスをブラウザーのアドレス バーに貼り付けて、そのアドレスを表示します。

  3. 応答を確認します。 403 Forbidden (403 禁止) 応答により、WAF が正常にバックエンド プールへの接続をブロックしていることが確認されます。

  4. トラフィックを許可するようにカスタム ルールを変更するには、次の Azure PowerShell スクリプトのリソース グループ名を置き換えて実行します。

    $rg = "<your resource group name>"
    $AppGW = Get-AzApplicationGateway -Name myAppGateway -ResourceGroupName $rg
    $pol = Get-AzApplicationGatewayFirewallPolicy -Name WafPol01 -ResourceGroupName $rg
    $pol[0].customrules[0].action = "allow"
    $rule = $pol.CustomRules
    Set-AzApplicationGatewayFirewallPolicy -Name WafPol01 -ResourceGroupName $rg -CustomRule $rule
    $AppGW.FirewallPolicy = $pol
    Set-AzApplicationGateway -ApplicationGateway $AppGW
    
  5. ブラウザーを数回更新します。 myVM1 と myVM2 の両方への接続が表示されるはずです。

リソースをクリーンアップする

このクイックスタートで作成したリソースが必要ない場合、リソース グループを削除すると、アプリケーション ゲートウェイとそのすべての関連リソースが削除されます。

リソース グループを削除するには、Remove-AzResourceGroup コマンドレットを呼び出します。

Remove-AzResourceGroup -Name "<your resource group name>"

次のステップ