【続】Azure Application Gatewayの課金を止めたい！（Automationで自動停止）

# きっかけ

以前、[Azure Application Gatewayの課金を止めたい！](https://qiita.com/yoshiyuki-iwata/items/edb9de0a2f93e1238f0e)にて、コマンドでApplication Gatewayを停止する記事を書きました。
ところが、金曜日の退勤時に停止するのを忘れ、土日そのまま無駄に稼働させてしまいました。
約15円/h × 48h として約720円の無駄遣い・・・。

## やっぱり自動停止したい

手動停止は忘れちゃいますよね。だって人間だもの。
というわけで、自動停止するようにしてみました。

# Azure Automationを使う

+ Azure Automation の概要
  - https://docs.microsoft.com/ja-jp/azure/automation/automation-intro

> **プロセスの自動化**
>
> このサービスでは、Runbook の作成をグラフィカルに行うか、PowerShell または Python を使用して実行できます。

+ Automation の価格
  - https://azure.microsoft.com/ja-jp/pricing/details/automation/

> |               | 含まれている無料ユニット (1 か月あたり) | 料金        |
> |:--------------|:-------------------------------------|:------------|
> | ジョブ実行時間 | 500 分                                | ¥0.224/分   |
> | ウォッチャー   | 744 時間                              | ¥0.224/時間 |

AutomationでPowerShell動かせますね。
たぶん無料分で収まるかな？仮に1か月分かかっても200円いかないくらい？
1日止め忘れを防止できれば元取れそう。

# さっそくやってみる

以下の手順で、Automationを利用して自動停止することができます。

## Automationアカウントの作成

参考記事の[Automation アカウントを作成する][link-1]を参考に、Automationアカウントを作成します。

**※記事のスクリーンショットが古いので、記事執筆時点[^1]の画面で手順を記載しました。**

1. **Azureホーム** から **Automationアカウント** を開く。

2. **[+追加]**ボタンを押す。
<details>
<summary>【参考】スクリーンショット</summary>
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/517338/3a7455a3-b5e1-e659-447e-292591f33dd9.png)
</details>

3. アカウント名等を入力して、**[作成]**を押す。
<details>
<summary>【参考】スクリーンショット</summary>
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/517338/060b64f9-73cc-2684-3499-b41cc47e98a3.png)
</details>

4. しばらく待つとアカウントが作成されます。
<details>
<summary>【参考】スクリーンショット</summary>
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/517338/dcf1e79f-3274-0231-bc63-962dd9854b7b.png)
</details>

## AzureRM.Networkモジュールの追加

[前回][link-previous]の記事で書いたコマンドを使うのですが、Automationでそのコマンドを実行すると`CommandNotFoundException`が出てしまいました。

```
Get-AzureRmApplicationGateway : The term 'Get-AzureRmApplicationGateway' is not recognized as the name of a cmdlet, 
function, script file, or operable program. Check the spelling of the name, or if a path was included, verify that the 
path is correct and try again.
At line:21 char:10
+ $AppGw = Get-AzureRmApplicationGateway -Name $appGatewayName -Resourc ...
+          ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : ObjectNotFound: (Get-AzureRmApplicationGateway:String) [], CommandNotFoundException
    + FullyQualifiedErrorId : CommandNotFoundException
```

Automationの初期状態では、このコマンドのモジュール(`AzureRM.Network`)が入っていないため、自分でインポートする必要があるとのこと。
[この記事][link-3]を参考に、`AzureRM.Network`をインポートします。

**※やはりスクリーンショットが古いので、記事執筆時点[^1]の画面で手順を記載しました。**

### モジュールのバージョン確認

1. 作成したAutomationアカウントを開く。

2. **[共有リソース]**の**[モジュール]**を開く。

3. **AzureRM.Profile**の**バージョン**を確認する。
   本記事執筆時点[^1]では、AzureRM.Networkをインストールする際に、**AzureRM.Profileのバージョンが5.8.2以上が必須**というエラーが出ました。
   それより古い場合は[AzureRM.profileの更新](#azurermprofileの更新)から、それ以上であれば[AzureRM.Networkのインポート](#azurermnetworkのインポート)の手順から実施して下さい。
<details>
<summary>【参考】スクリーンショット</summary>
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/517338/5f2d8d6b-e5a1-1cd8-82da-f191186c6d16.png)
</details>

### AzureRM.profileの更新

1. **[共有リソース]**の**[モジュール ギャラリー]**を開く。

2. **AzureRM.profile**を選択する。
<details>
<summary>【参考】スクリーンショット</summary>
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/517338/8f54b019-4b75-3bb0-9e38-007ab2961836.png)
</details>

3. バージョンを確認し**[インポート]**を押す。
   インポートの確認ダイアログが出るので、同意をチェックしてOKを押す。
<details>
<summary>【参考】スクリーンショット</summary>
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/517338/29b44816-1dad-aaaa-2f17-ca9d2468c627.png)
</details>

4. **[共有リソース]**の**[モジュール]**を開き、バージョンが変わって使用可能になるまで待つ。

### AzureRM.Networkのインポート

1. **[共有リソース]**の**[モジュール ギャラリー]**を開く。

2. **AzureRM.Network** を選択する。
<details>
<summary>【参考】スクリーンショット</summary>
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/517338/c53017ec-c46e-6b1f-0034-6ab8e04639cf.png)
</details>

3. **[インポート]**を押す。
   インポートの確認ダイアログが出るので、OKを押す。
<details>
<summary>【参考】スクリーンショット</summary>
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/517338/21e2cb94-3326-ddc0-542e-4f8147c42eee.png)
</details>

4. **[共有リソース]**の**[モジュール]**を開き、使用可能になるまで待つ。
<details>
<summary>【参考】スクリーンショット</summary>
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/517338/a7ba3bef-1913-f557-1e84-9cd35b383f98.png)
</details>

</div>
</details>

## Runbookの作成

[この記事][link-2]を参考に、新しいRunbookを作り、自動停止シェルを書いていきます。

**※ここも記事執筆時点[^1]の画面で手順を記載しました。**

1. 作成したAutomationアカウントを開く。

2. **[プロセス オートメーション]**の**[Runbook]**を開く。

3. **[+Runbook]**の作成を押す。

4. 適当な名前を付け、[Runbookの種類]は「PowerShell」を選択し、**[作成]**を押す。
<details>
<summary>【参考】スクリーンショット</summary>
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/517338/ba880732-7ed1-604d-bb3e-f4e626a8e419.png)
</details>

5. 作成したRunbookの画面から、**[+編集]**を押す。
<details>
<summary>【参考】スクリーンショット</summary>
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/517338/720e6090-e302-c9e3-8fc7-df3a2bb9a0a9.png)
</details>

6. 自動停止シェルを書いて、**[保存]**を押す。
<details>
<summary>【参考】スクリーンショット</summary>
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/517338/87f1cd55-7ea2-b3aa-70bd-580e726989d1.png)
</details>

7. **[公開]**を押す。
   なお、**[テストウィンドウ]**を押すとテスト実行することができます。

</div>
</details>


### 自動停止シェル

AutomationからAzureRMのコマンドを実行する場合、認証処理が必要です。
[Microsoftの記事][link-2]に認証処理のサンプルがあったので、そのままパクりました。

``` powershell
# 初期設定
$appGatewayName = "Application Gatewayの名前を入力する"
$resourceGroupName = "Application Gatewayのリソースグループを入力する"

# AzureRM認証処理
Disable-AzureRmContextAutosave -Scope Process
$connection = Get-AutomationConnection -Name AzureRunAsConnection

while (!($connectionResult) -And ($logonAttempt -le 10)) {
    Write-Output ("* Trying AzureRM authentication...")
    $logonAttempt++
    $connectionResult = Connect-AzureRmAccount `
                            -ServicePrincipal `
                            -Tenant $connection.TenantID `
                            -ApplicationID $connection.ApplicationID `
                            -CertificateThumbprint $connection.CertificateThumbprint
    Start-Sleep -Seconds 10
}

# ApplicationGatewayの情報を取得
$AppGw = Get-AzureRmApplicationGateway -Name $appGatewayName -ResourceGroupName $resourceGroupName
Write-Output ("* " + $appGatewayName + " is " + $AppGw.OperationalState + ".")

# 稼働中なら停止する
if ($AppGw.OperationalState -eq "Running") {
    Write-Output ("* Stopping " + $appGatewayName + "...")
    Stop-AzureRmApplicationGateway -ApplicationGateway $AppGw
}
Write-Output ("* Done.")
```

## スケジューリングの設定

1. 作成したRunbookを開く。

2. **[リソース]**の**[スケジュール]**を開く。

3. **[+スケジュールの追加]を押す。** 
<details>
<summary>【参考】スクリーンショット</summary>
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/517338/f72767dd-67c9-4587-a181-15c6a01b9fda.png)
</details>

4. スケジュールを作成します。
<details>
<summary>【参考】スクリーンショット</summary>
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/517338/19ec48ed-d645-ebe5-b0b0-d593087f933c.png)
</details>

5. **[スケジュール]**から、次の実行タイミングを確認します。
<details>
<summary>【参考】スクリーンショット</summary>
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/517338/be0ebaf2-5c1f-90e1-d930-dc5e0d63e214.png)
</details>

# おわりに

[前回記事][link-previous]の`Stop-AzureRmApplicationGateway`書くだけでいけるっしょ！と軽い気持ちで作り始めたら、意外とハマってしまいました。
何はともあれ、これで止め忘れは無くなったので良かったです。
Automationも使えたので、いろいろな運用を自動化させてみたいと思います。

# 参考記事

[link-1]:https://docs.microsoft.com/ja-jp/azure/automation/automation-quickstart-create-account#create-automation-account
[link-2]:https://docs.microsoft.com/ja-jp/azure/automation/automation-first-runbook-textual-powershell
[link-3]:https://www.syuheiuda.com/?p=3620
[link-previous]:https://qiita.com/yoshiyuki-iwata/items/edb9de0a2f93e1238f0e

+ Automation アカウントを作成する
  - [https://docs.microsoft.com/ja-jp/azure/automation/automation-quickstart-create-account)][link-1]
+ 初めての PowerShell Runbook
  - [https://docs.microsoft.com/ja-jp/azure/automation/automation-first-runbook-textual-powershell][link-2]
+ Azure Automation に AzureRM.Network モジュールがない件
  - [https://www.syuheiuda.com/?p=3620][link-3]

[^1]: 記事の執筆は2020/3/16です。