[Azure] Azure サービスを定期的にスケールダウンしてコスト削減する ～Cosmos DB RU値の定期変更を例に～

## はじめに
クラウドの利用料を削減するために、夜間や休日などクラウドサービスの使用率が小さい時間はあらかじめスケールダウンやスケールインするよう設定したいですよね。
Azureには[自動スケール](https://docs.microsoft.com/ja-jp/azure/azure-monitor/platform/autoscale-overview)という仕組みが用意されていますが、対応サービス数が限られていたり、スケールアウト/インのみの対応だったりします。

そんな中、スケール変更の別アプローチとして、[Azure Automation](https://azure.microsoft.com/ja-jp/services/automation/)というサービスを使う方法を紹介します。
Azure AutomationではPowerShellのコマンドを定期的に実行させることが可能です。

そして、Azureサービスの中には、PowerShellコマンドでスケール設定を変更できるものがあります。
例えば、App Service プランは[こちら](https://docs.microsoft.com/ja-jp/powershell/module/az.websites/set-azappserviceplan?view=azps-3.0.0)に提示されているPowerShellコマンドで`-Tier`オプションを使用するとスケール変更ができます。
また、本記事で具体例として紹介するCosmos DBのスケール変更(ここではRU値の変更を指しています)については[こちら](https://docs.microsoft.com/ja-jp/azure/cosmos-db/scripts/powershell/sql/ps-sql-ru-update?toc=%2fpowershell%2fmodule%2ftoc.json)のドキュメントに記載されています。

よって、Azure Automationでスケール設定を変更するPowerShellコマンドを定期実行させることで、サービス使用率が低い時間帯はスケールを下げることを実現できます。

※Cosmos DBのRU値については[こちら](https://docs.microsoft.com/ja-jp/azure/cosmos-db/request-units)

## 1. Automation アカウントの作成
Azure Automationを初めて使う場合は、Automationアカウントを作成する必要があります。
Azureポータルの[すべてのサービス]で"Automation"などと検索し、[Automation アカウント]を選択します。
<img width="457" alt="2019-11-08_18h33_21.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/423135/97a2f4c1-89d6-e7d9-d0c1-b7ee06fbd25e.png">
[+追加]でAutomation アカウント作成画面に移動したら、任意の名前、サブスクリプション、リソースグループ、場所を設定し、[Azure 実行アカウントの作成]は"はい"のまま[作成]を押下します。
<img width="156" alt="2019-11-08_18h52_43.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/423135/9a57455f-6178-a10c-d04f-5dc3826a2497.png">

これでAzure Automationを使用する準備ができました。
※Azure実行アカウントが作成できない場合は[こちら](https://docs.microsoft.com/ja-jp/azure/automation/automation-create-standalone-account#permissions-required-to-create-an-automation-account)のドキュメントを参考に権限をご確認ください。

## 2. Runbookの作成
続いて、Runbookなるものを作成します。
作成したAutomation アカウントに入ったら、[Runbook]を選択して、[+Runbookの作成]を押下します。
<img width="393" alt="2019-11-08_19h06_15.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/423135/b80c2c56-f53f-3320-e074-d32a1faffec3.png">
作成画面に移動したら、任意の名前を入力し、[Runbookの種類]は[PowerShell]を選択します。説明は自由に記述してください。
<img width="155" alt="2019-11-08_19h10_35.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/423135/0157f638-b10b-bc2a-2504-25421de939ff.png">
[作成]を押下するとコマンド編集画面に移動します。
ここでスケールを変更するためのPowerShellコマンドを入力して[保存]を押下します。

今回は例としてCosmos DBのRU値を変更するコマンドを示します。
設定変更したいAzureサービスに合わせて、以下のパラメータや変数、設定コマンド部分は変更してください。
また、設定コマンドによっては変更確認をスルーするために`-Force`オプションなどが必要な場合もあるのでエラーが出た場合は気にしてみてください。

~~~powershell
# Set input parameter
# Please change the following depending on the Azure Service
Param(
 [Parameter (Mandatory= $true)]
 [string]$resourceGroupName,
 [Parameter (Mandatory= $true)]
 [string]$accountName,
 [Parameter (Mandatory= $true)]
 [string]$databaseName,
 [Parameter (Mandatory= $true)]
 [string]$containerName,
 [Parameter (Mandatory= $true)]
 [Int32]$throughput
)

# Set variable
# Please change the following depending on the Azure Service
$resourceType = "Microsoft.DocumentDb/databaseAccounts/apis/databases/containers/settings"
$apiVersion = "2015-04-08"
$containerResourceName = $accountName + "/sql/" + $databaseName + "/" + $containerName + "/throughput"
$properties = @{
    "resource"=@{"throughput"=$throughput}
}

# Stop runbook when an error occurs
$ErrorActionPreference = "Stop"

# Turn off autosaving Azure credentials
Disable-AzContextAutosave -Scope Process

# Connect to Azure
$connection = Get-AutomationConnection -Name AzureRunAsConnection
Connect-AzAccount -ServicePrincipal -Tenant $connection.TenantID `
    -ApplicationId $connection.ApplicationID -CertificateThumbprint $connection.CertificateThumbprint

# Set Cosmos DB throughput
# Please change the following depending on the Azure Service
Set-AzResource -Force -ResourceType $resourceType `
    -ApiVersion $apiVersion -ResourceGroupName $resourceGroupName `
    -Name $containerResourceName -PropertyObject $properties 
~~~
## 3. モジュールのインポート、テスト、Runbookの発行
コマンドが完成したら、[テストウィンドウ]からコマンドの動作テストができます。
※テストといっても、実際にサービスのスケールは変更されるので注意しましょう。
ただし、上記をそのまま実行しても以下のようなエラーメッセージが表示されてしまうと思います。

```
失敗
The term 'Disable-AzContextAutosave' 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. (The term 'Disable-AzContextAutosave' 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.)
```

PowerShellからAzureのリソースを触るコマンド(上記でいうと`Disable-AzContextAutosave`や`Set-AzResource`)を使用するには、適切なAzモジュールのインポートが必要です。
必要なAzモジュールは、使用したいPowershellコマンドの公式ドキュメントに書いてあります。
<img width="408" alt="2019-11-22_12h45_15.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/423135/62e09966-b438-4934-a51e-66520a4c7abe.png">

必要なAzモジュールが分かったら、[モジュールギャラリー]からインポートします。
今回の場合は`Az.Accounts`と`Az.Resources`という2つのモジュールが必要になるので、検索窓から検索してインポートします。
<img width="486" alt="2019-11-08_20h09_21.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/423135/abe000ad-24cb-0647-1571-a50fe6ae5f67.png">

モジュールのインポートもできたら、改めてRunbookが動くかテストします。
[モジュールギャラリー]にいる場合は、[Runbook] - [ (作成中のRunbook) ]と選択して概要画面の[編集]を押下すれば、先ほどの編集画面に戻ります。
[テストウィンドウ]を押下し、テスト画面に移動します。
上記コマンド内の`# Set input parameter`で設定したパラメータを入力できるので、対象のCosmos DBとスケール設定の情報を入力して、[開始]を押下します。
<img width="608" alt="2019-11-22_13h00_28.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/423135/59043c35-dc9c-9c5f-c7a0-c5699bf5cf36.png">
完了の文字が出たら、実際にCosmos DBを見に行きましょう。RU値が変更されているはずです。
RU値の変更が確認できたら、再度編集画面に戻り[公開]ボタンを押して作成したRunbookを発行します。
<img width="252" alt="2019-11-08_20h48_13.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/423135/83b1c7a6-56c8-8d46-5c3c-0a33b26889cb.png">

## 4. スケジュールの設定
ここまで来たら、後はスケジュールの設定だけです。
スケジュールを設定するには該当のRunbook画面から[スケジュール] - [+ スケジュールの追加]と進みます。
スケジュールで、[+新しいスケジュールを作成します]でスケジュール設定を入力します。
[繰り返し]で"定期的"を選択すると、1日おきや1週おきなどRunbookの実行間隔を設定できます。
Runbookの有効期限も設定可能です。
<img width="471" alt="2019-11-08_20h54_24.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/423135/4a5ba432-de16-43b9-a02e-e94e08c01999.png">

スケールダウンの設定だけでなく、もとに戻すスケジュール設定もお忘れなく。
<img width="718" alt="2019-11-08_20h57_16.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/423135/fe3f8958-5d79-7326-da55-d9649cdc2898.png">

あとは時が来るのを待つのみです。
実行されると、"最近のジョブ"に実行履歴が表示されます。
<img width="699" alt="2019-11-22_17h33_36.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/423135/ae5a929a-3997-1780-06a0-491d2329b301.png">