Azure Firewall を疑似的に 起動＆停止 するには？

# はじめに
Azure Firewall は、マネージドサービスです。
目には見えませんが、内部的に LB , VM , NIC , Storage が自動的に手配されて AzureFirewallSubnet 上で稼働しています。

課金は、時間単価ではありますが、停止することができないため、リソースが存在している間は 継続して課金されつづけます。

業務運用の環境であれば、それでも構いませんが、PoC 環境の場合は 利用していない時間の課金は抑えたいというニーズがあることと思います。

今回は、そのニーズに応える事を目標として検証し、記事に纏めました。

:::note info
私は この方法を使って デモを行う際に、Azure Firewall がある場合の動作と、無い場合の動作 を比較して見て頂くような場合にも、活用しています。
:::

---

# Azure Firewall の運用コスト
2024 年 10 月 20 時点、Japan East の コスト です。
連続使用していると、以下のコストが発生します。
Basic でも、デプロイ後に放置して 連続稼働していると、約４万円も掛かります。
そして、Standard では 10 万円を超えてきますので、結構な出費です。

|SKU|時間単価|月額コスト|
|:-:|:-:|:-:|
|Basic|57.2 円|41,754 円|
|Standard|181.01 円|132,135 円|
|Premium|253.41 円|184,989 円|

**料金計算ツールにて算出**

https://azure.microsoft.com/ja-jp/pricing/calculator?wt.mc_id=mvp_407731

**Azure Firewall の価格**

https://azure.microsoft.com/ja-jp/pricing/details/azure-firewall?wt.mc_id=mvp_407731

:::note info
**ポイント**
本記事で紹介する方法で、Azure Firewall を必要な時だけ稼働させるようにすることで、大幅なコスト削減に繋げられると思います。
:::

---

# 疑似的な 起動＆停止 の考え方
Azure Firewall には、起動＆停止 という仕組みが無い為、課金を止めるためには リソースを削除 する必要があります。

**削除すると、FW 規則（ポリシー）や パブリック IP、アクセスログ はどうなるのか？**
本作業では、Azure Firewall がマネージドで管理されている目に見えない 内部リソース（VM , LB , Storage , NIC）だけが削除され、ポリシー や、パブリック IP、アクセスログは 残ります。

そのため、利用者固有の情報は残り続け、単に 動作のために必要な 共通コンポーネント のみを削除することが可能です。その仕組みを逆手にとって、効率よく リソースの 削除＆再作成 を行えば、疑似的な 停止＆起動 が実現できます。

---

以降の記事は、以下の３章で構成されており、１章の **事前準備** で構成を行っておけば、以後 ２章と３章の **疑似停止** と **疑似起動** を交互に繰り返しで 利用する事ができるようになっています。

**1. 事前準備**（初回のみ）
　1-1. Azure Firewall の 初回作成
　1-2. ARM テンプレートの取得
**2. Azure Firewall の 疑似停止**
　2-1. ルートテーブルの変更（切り離し）
　2-2. Azure Firewall の削除
**3. Azure Firewall の 疑似起動**
　3-1. Azure Firewall の再作成
　3-2. ルートテーブルの変更（切り戻し）

---

# 1. 事前準備
## 1-1. Azure Firewall の 初回作成
### ① Firewall 本体 の デプロイ
初回の作成は、通常の手順で構成済みであることを前提としています。
以下の記事を参考に、手動でデプロイ してください。

https://qiita.com/carol0226/items/c40de99f11fb1593f26b

### ② アクセスログ取得 の デプロイ
さらに、以下の手順で Azure Firewall のアクセスログを取得する構成がおススメです。
本記事の方法を使う事で、Azure Firewall の課金を止めつつ、アクセスログは そのまま残ります。
※保存されているアクセスログのストレージ使用量には課金が発生しますので、ご注意ください。

https://qiita.com/carol0226/items/b626d67a74c27b4a224b

---

## 1-2. ARM テンプレートの取得
本章の作業は、再作成を行うための ARM テンプレート を取得する事が目的です。
取得した ARM テンプレートは、あとの章で使用します。

**ARM テンプレート取得手順**

0. 目的となる Azure Firewall のリソースを表示させ、左ペインの **テンプレートのエクスポート** を選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1619637/314e59ea-fd15-e0ea-e082-eaf55ee666cd.png)
　<br>
0. **テンプレートのエクスポート** の画面に遷移します。
初めに、以下のように **テンプレートを生成しています** と表示されている間は 暫く待ちます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1619637/0dcb3950-cfd6-b39f-7833-4eea2d988b2f.png)
　<br>
0. 以下のように テンプレートのソースコードが表示されたら、**パラメーターを含める** にチェックが入っていることを確認して **ダウンロード** をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1619637/a4b482d7-2b91-c852-ca55-40e72601e0eb.png)
　<br>
0. 以下のような ZIP ファイル がダウンロードされます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1619637/97d9f641-d33e-3240-f953-4f5f16c283bc.png)
　<br>
0. ダウンロードされた ZIP 内には、以下の２つのファイルがありますが、本記事で使用するのは、template.json のみとなります。
- template.json
- parameters.json

---

# 2. Azure Firewall の 疑似停止
## 2-1. ルートテーブルの変更（切り離し）
Azure Firewall を削除したあとに、VM からインターネットへの通信を禁止する場合は、本章は SKIP してください。

Azure Firewall を削除したあとでも、VM からインターネットへの通信を利用できるようにするためには、ルートテーブルの変更を行い、Azure Firewall を経由せずに インターネットに抜ける代替ルートに切替えます。

このルート切替を 削除の前に実施することで、通信への影響を抑える事ができます。

**インターネットへ抜けるルートに切り替える手順** 

0. 作業前は、以下のように サブネット に、**Firewall-Route** という ルートが関連付けられています。ここで、ルートを変更するために、サブネット名 をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1619637/23198049-0c42-5bd6-9127-bdafb13f375f.png)
　<br>
0. **ルート テーブル** の項目の リストダウン から **なし** または **事前作成済みの FW を経由しないルート**（下図では OpenVPN-RT）を選択して **保存** を押します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1619637/7c055f1a-7988-7bb6-f41b-b3bca4f92983.png)
　<br>
0. 以下のような表示に変更されれば、ルートの切替 は完了です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1619637/da233ada-6753-7b05-54d0-747a8516cbf6.png)

この状態で、トラフィックは Azure Firewall では制御されず、代替ルートを利用して インターネットに抜けていきます。

---

## 2-2. Azure Firewall の削除
**① コマンド での削除** と、**② GUI での削除** の２通り紹介します。
いずれかを実施してください。

### ① コマンド での削除
~~~
az resource delete --resource-group 'AVD-Environment' --name 'AZFW' --resource-type 'Microsoft.Network/azureFirewalls'
~~~

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1619637/fe5e94fc-5ac8-de76-3fcc-e9abb834b93a.png)

### ② GUI での削除

0. 課金を停止させたい Azure Firewall のリソースの 概要ページを開きます。
続けて、**①：Delete** 、 **②：OK** の順にクリックして 削除 を実行します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1619637/75eb1c64-de5f-595d-6533-2545f4355534.png)
　<br>
0. 削除が開始されると、以下の通知が表示されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1619637/055ec4b7-3cd9-4893-8381-f219cb0e2b19.png)
　<br>
0. 削除が完了すると、以下の通知が表示されます。※削除されるまでは、約５分 程度掛かります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1619637/c348397f-9afb-af0c-7251-ea7386056d5d.png)
　<br>
0. 以下の通り、Azure Firewall は削除され、これで、課金が止まります。
なお、Firewall の設定（ポリシー）と パブリック IP アドレス は残っていますが、再作成時に これらが自動的に利用されますので、残しておいてください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1619637/25825429-9cd5-b88e-c8bb-8dfe92928c78.png)
※ パブリック IP アドレス のリソースは、微々たる課金が発生します。

---

# 3. Azure Firewall の 疑似起動
## 3-1. Azure Firewall の再作成
**① Deplot to Azure ボタン を使う方法** と、**② 手動で テンプレートを開く方法** の２通り紹介します。

### ① Deplot to Azure ボタン を使う方法
以下のボタンを押すと、Azure Firewall 再作成のテンプレートが自動的に読み込まれます。
[![Deploy to Azure](https://aka.ms/deploytoazurebutton)](https://portal.azure.com/#create/Microsoft.Template/uri/https%3A%2F%2Fnogujapanese.blob.core.windows.net%2Favd-template%2FAzFWReDeploy.json "Push Me!")

このとき、リソースグループは AzureFirewallSubnet と同じリソースグループ を選択してください。

※この方法は、私が用意したテンプレートが読み込まれるため、ネットワーク設計 が完全に一致している場合に利用できます。

<details><summary>上記の ARM テンプレート のソース</summary>

**アドレス**
https://nogujapanese.blob.core.windows.net/avd-template/AzFWReDeploy.json

~~~
{
    "$schema": "http://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
    "contentVersion": "1.0.0.0",
    "parameters": {
        "location": {
            "type": "string",
            "defaultValue": "japaneast"
        },
        "resourceGroup": {
            "type": "string",
            "defaultValue": "AVD-Environment"
        },
        "azureFirewallName": {
            "type": "string",
            "defaultValue": "AZFW"
        },
        "azureFirewallTier": {
            "type": "string",
            "defaultValue": "Basic"
        },
        "vnetName": {
            "type": "string",
            "defaultValue": "AZ-DefaultVNet"
        },
        "zones": {
            "type": "array",
            "defaultValue": []
        },
        "azureFirewallManagementSubnet": {
            "type": "string",
            "defaultValue": "AzureFirewallManagementSubnet"
        },
        "managementPublicIpAddressName": {
            "type": "string",
            "defaultValue": "FW-mg-pip"
        },
        "publicIpAddressName": {
            "type": "string",
            "defaultValue": "FW-pip"
        },
        "FirewallRule": {
            "type": "string",
            "defaultValue": "FW-Rule"
        }
    },
    "variables": {
        "networkApiVersion": "?api-version=2019-09-01"
    },
    "resources": [
        {
            "apiVersion": "2020-05-01",
            "type": "Microsoft.Network/azureFirewalls",
            "name": "[parameters('azureFirewallName')]",
            "location": "[parameters('location')]",
            "zones": "[parameters('zones')]",
            "dependsOn": [],
            "properties": {
                "ipConfigurations": [
                    {
                        "name": "[parameters('publicIpAddressName')]",
                        "properties": {
                            "subnet": {
                                "id": "[resourceId(parameters('ResourceGroup'),'Microsoft.Network/virtualNetworks/subnets',parameters('vnetName'),'AzureFirewallSubnet')]"
                            },
                            "publicIpAddress": {
                                "id": "[resourceId(parameters('ResourceGroup'), 'Microsoft.Network/publicIPAddresses', parameters('publicIpAddressName'))]"
                            }
                        }
                    }
                ],
                "sku": {
                    "tier": "[parameters('azureFirewallTier')]"
                },
                "managementIpConfiguration": {
                    "name": "[parameters('managementPublicIpAddressName')]",
                    "properties": {
                        "subnet": {
                            "id": "[resourceId(parameters('ResourceGroup'),'Microsoft.Network/virtualNetworks/subnets',parameters('vnetName'),'AzureFirewallManagementSubnet')]"
                        },
                        "publicIPAddress": {
                            "id": "[resourceId(parameters('ResourceGroup'), 'Microsoft.Network/publicIPAddresses', parameters('managementPublicIpAddressName'))]"
                        }
                    }
                },
                "firewallPolicy": {
                     "id": "[resourceId(parameters('ResourceGroup'), 'Microsoft.Network/firewallPolicies', parameters('FirewallRule'))]"
                }
            },
            "tags": {}
        }
    ]
}
~~~

</details>

このあと、② を SKIP して、**③ 共通の手順** 以降の手順を実施してください。

### ② 手動で テンプレートを開く を使う方法

0. 以下の ① と ② の 手順で **カスタムテンプレートのデプロイ** を開きます。
そのあと、③ の **エディターで独自のテンプレートを作成する** を開きます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1619637/a730b9aa-f83f-f143-40bf-baecc9ab6d44.png)
　<br>
0. **ファイルの読み込み** を使って 事前作業で保存しておいた template.json ファイルを指定して読み込みます。
以下の緑枠の箇所に、テンプレートが読み込まれます。その後 **保存** ボタンを押します。
なお、template.json の中身を 直接 テキストで貼り付けることもできます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1619637/0d5ab188-dfe7-43b8-0526-1e74c8dee72a.png)

このあと、**③ 共通の手順** 以降の手順を実施してください。

### ③ 共通の手順

0. **リソースグループ** の指定のみ必要です。既存の リソースグループ名 を選択して **確認と作成** を押します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1619637/0f4b6dd3-4c1e-07af-4c19-833cbf3eb72c.png)
　<br>
0. **確認と作成** タブでは そのまま **作成** を押します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1619637/fd03b46a-a33e-9d95-fd28-20b59e207b71.png)
　<br>
0. 以下のように Azure Firewall のデプロイが開始されます。完了まで およそ ６～７分掛かります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1619637/78dfc298-9c5f-97c7-d13a-a9440fb29d6d.png)
　<br>
0. 以下のように表示されれば 完了 です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1619637/c08f4c8e-c546-640c-5f55-1d6b10d9a7c9.png)

---

## 3-2. ルートテーブルの変更（切り戻し）
Azure Firewall を削除した際に、ルートテーブルの切り離しを行っていない場合は、本章は SKIP してください。

Azure Firewall を削除した際に、ルートテーブルの切り離しを行っていた場合は、ルートテーブルの変更を行い、Azure Firewall を経由して インターネットに抜けるルートに切り戻します。

このルート切替を 再作成の後に実施することで、通信への影響を抑える事ができます。

**ルートテーブルの切り戻し手順**

0. 作業開始前の確認を行います。この時点では、まだ ルートは、Azure Firewall を経由しないルートです。
（確認用のアドレス）
https://www.cman.jp/network/support/go_access.cgi
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1619637/84a3cb38-b3ea-4082-6d70-a468a0360d0e.png)
　<br>
0. ルートを変更したい サブネット を開きます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1619637/7f2975a7-7774-d49b-4628-87b88daecffc.png)

:::note info
**OpenVPN-RT 内容**
以下の通り、インターネットへの通信は、ダイレクトにルーティングされている状態です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1619637/e3370654-d8bf-adf6-8dee-4350b4ee8b89.png)
:::

3．**サブネットの編集** 画面にて、ルートテーブルを **Azure Firewall 経由のルート** に変更して **保存** を押します。
※下図では、**Firewall-Route** に変更しています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1619637/6220f105-64d6-3669-ee8f-ceef24917f5c.png)

4．下図の通り、インターネット（0.0.0.0/0）宛の通信が Azure Firewall 経由（仮想アプライアンス 10.10.30.4）に変更されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1619637/8d242a28-eb3a-2af6-847d-0985c68259f7.png)

5．作業後の確認を行います。ルートは、Azure Firewall を経由するルートに変更されていれば OK です。
（確認用のアドレス）
https://www.cman.jp/network/support/go_access.cgi
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1619637/0fa9c5a4-cd0c-2995-ae4f-881665153346.png)

:::note info
**Azure Firewall の パブリック IP アドレス の確認方法**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1619637/6b247d45-2f31-2210-c6ec-98a2dc8229c4.png)
:::

記事の内容は 以上です。
参考にしていただいて、コストの削減に活用いただけたら幸いです。