Azure AutomationでAzure Analysis Servicesのモデルを更新する

## はじめに
[Azure Analysis Services](https://azure.microsoft.com/ja-jp/services/analysis-services/) は、企業のデータに対して一般的な用語を使用して意味を与えるセマンティックモデルの役割となり、エンドユーザー向けのBIのアクセスレイヤーとして使われている。インメモリで動作するため非常に高速である。セルフBIのようなシステムを作ろうとするときは、このような技術があるのと無いのとでUXが全然違う。もともとはSQL ServerのコンポーネントでSQL Server Analysis Services (SSAS)と呼ばれる昔からある技術をAzure上のPaaSとして提供しているのがAzure Analysis Services (AAS)である。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/144789/a247eba1-ac93-0495-dbce-3ce26a8101ea.png)
https://docs.microsoft.com/ja-jp/azure/analysis-services/analysis-services-overview より

このAzure Analysis ServicesはPaaSだけあって簡単に可用性・拡張性等が備わったものをデプロイできて、すぐに利用できるので非常に便利である。SSASの頃からの技術で、ネット上には多くの記事が出ているので、比較的情報を得やすい。
データ基盤のパイプラインにおける1つのアクティビティとしてAASのモデルの自動更新を検討していたところ、[Azure Automation](https://azure.microsoft.com/ja-jp/services/automation/) が比較的実装しやすいことが分かったので、ここにメモしておく。Azure Automationを選択したのは、PowerShellが実行しやすくWebhookでコールしやすいためである。もちろんほかにもいろいろと良い方法はあると思う。

## 構成

以下の図のような構成を想定する。これらのサービスをデプロイしておく。[SQL Data Warehouse](https://azure.microsoft.com/ja-jp/services/sql-data-warehouse/) はMPP型のDWHであり大量データを構造化してまとめ上げるのに適したサービスである。テストする際はSQL Data Warehouseのデプロイ時にサンプルデータを指定しておくと、最初からAdventureWorksのデータが入っているので便利。
<div align="center">
<img src="https://qiita-image-store.s3.amazonaws.com/0/144789/1498a401-e10a-c435-7536-81a29fa2494b.png">
</div>

## 事前準備

AAS上のWebデザイナー等でテスト用のモデルを1つ作っておく。WebデザイナーはAzureポータル上でモデルの作成と編集ができるツールで、現在はプレビューの状態だ。
https://docs.microsoft.com/ja-jp/azure/analysis-services/analysis-services-create-model-portal
このドキュメント上には、
>このフィーチャーは非推奨です。今後の更新プログラムで削除されるか、大幅に変更される可能性があります。

と書いてあるが、テスト用にモデルを作るだけなので今回はこのドキュメントの要領に従ってモデルを作成する。本格的に作成する場合はVisual StudioとSQL Server Management Studioを使うことが推奨されている。

## 設定方法

### サービスプリンシパルを作成
AzureポータルからAzure ADの管理画面を開き "App Registration" > "New application registration" と進み、必要事項を入力する。ここで入力したSign-on URLは特に意味はない。
<img src="https://qiita-image-store.s3.amazonaws.com/0/144789/f817a030-30c8-97bd-3d86-24a7efdd0ee3.png" width=40%>

出来上がったら、そのApp Registrationの画面に表示されるApplication IDをコピーしてメモ帳かなんかに張り付けておく。
<img src="https://qiita-image-store.s3.amazonaws.com/0/144789/eba79b0a-fccf-5579-dbf1-99694ebf4a02.png" width=60%>

#### パーミッションの設定
で"Settings"メニューに入り、"Required permissions" > "+Add" > "1. Select an API"と進み、検索ボックスに「Azure Analysis Service」と入れて表示される Azure Analysis Services を選択して"Select"をクリック。
<img src="https://qiita-image-store.s3.amazonaws.com/0/144789/75bf33ba-ac94-76f4-6794-0fe6611925d4.png" width=60%>

次の画面で"DELEGATED PERMISSIONS"にチェックを入れて"Select"をクリック。
<img src="https://qiita-image-store.s3.amazonaws.com/0/144789/bafae406-fb20-eeab-a76c-74f47ebc2785.png" width=60%>

Required permissionsの設定完了なので、"Done"をクリック。

Azure Analysis Servicesが追加され、DELEGATED PERMISSIONSが1になっていることが確認できる。
<img src="https://qiita-image-store.s3.amazonaws.com/0/144789/b171ac0b-0fc3-3a77-fecc-37c10c962a4b.png" width=60%>

#### キーの取得
次に"Settings"に戻り、"Keys"をクリック。
DESCRIPTIONにキーの名前を入れ、EXPIRESのところにキーの期限を設定する。ここではNever expiresにしている。設定が終わったら画面上部の"Save"をクリックするとVALUE欄にキーの値が1回だけ表示されるので、これを忘れずにコピーして、メモ帳かなんかに張り付けておく。
<img src="https://qiita-image-store.s3.amazonaws.com/0/144789/9de7537d-35d4-8160-7294-ab1e3baf7412.png" width=60%>

#### Directory IDの取得
Directory ID (Tenant ID)も必要なので、Azure ADの"Properties"メニューからDirectory IDを探してコピーし、これもメモ帳かなんかに張り付けておく。
<img src="https://qiita-image-store.s3.amazonaws.com/0/144789/c1d546eb-b8cb-1fa7-ad6d-7b1a0a24aeda.png" width=60%>

#### Analysis Services Adminsにサービスプリンシパルを追加

作ったサービスプリンシパルをAnalysis Services Adminsに追加する。PowerShellを使うので、こういう時に便利な [Azure Cloud Shell](https://docs.microsoft.com/ja-jp/azure/cloud-shell/overview) で実行する。

Azure Cloud ShellはAzureポータル画面の右上あたりにある顔文字みたいなアイコンをクリックする。BashかPowerShellか聞いてくるのでPowerShellを選択する。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/144789/d2472998-a2a1-beb0-2efa-266a5f19c78b.png)

PowerShellがブラウザの画面下部で起動するので、起動が終わったら下記のようにコマンドを実行して登録する。

```PowerShell
$SPAdmin = "app:{Application ID}@{Directory ID}"
Set-AzureRmAnalysisServicesServer -Name "{Server Name}" -ResourceGroupName "{Resource Group Name}" -Administrator $SPAdmin
```

こうすると、もともと入っていた自分のアカウントが消えて、サービスプリンシパルだけになってしまうので、避けたい場合は以下のように自分のアカウントも入れて登録する。

```PowerShell
$SPAdmin = "app:{Application ID}@{Directory ID}"
Set-AzureRmAnalysisServicesServer -Name "{Server Name}" -ResourceGroupName "{Resource Group Name}" -Administrator "$SPAdmin , youraccount@yourdomain"
```

これで下準備は完了なので、後はAzure Automationで更新処理をこしらえていく。

### Azure Automation

[Azure Automation](https://azure.microsoft.com/ja-jp/services/automation/) はPowerShellやPythonの自動実行とか、OSパッチの更新管理とか、構成管理とか、いろいろできるサービスである。今回の目的はPowerShellを実行してAASのモデル更新を自動化することである。Azure Automationのデプロイは簡単で、[このドキュメント](https://docs.microsoft.com/ja-jp/azure/automation/automation-quickstart-create-account) の1~3項を実行するだけである。

#### モジュールのインポート

Azure Automationが作成されたら、まずは今回必要なモジュールをセットアップする。
"Modules gallery"から「SQLServer」で検索して表示された「SqlServer」モジュールを選択。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/144789/159b9abe-1457-2621-a847-672cb212d9c1.png)

"Import"をクリックし、確認画面で"OK"をクリックしてインポートを実行する。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/144789/418ffbea-b4fe-6d28-c704-a04becd5f990.png)

同様にして"AzureRM.Profile", "Azure.AnalysisServices"も順にインポートする。

#### クレデンシャルの作成
Azure Automationアカウントの管理画面に戻り"Credentials"メニューから"Add a credential"を選択して以下のように必要事項を入力する。
User name欄にはサービスプリンシパルのApplication IDを入れ、Passwordにはキーを入れる。
<img src="https://qiita-image-store.s3.amazonaws.com/0/144789/0dfb332f-f9f8-3db8-d81c-204d0fb6c3b8.png" width=40%>

#### Runbookの作成
Azure Automationアカウントの管理画面から"Runbooks"メニューに入り、"+Add a runbook"と進み、以下のようにRunbookの設定を行う。
<img src="https://qiita-image-store.s3.amazonaws.com/0/144789/3bb418be-7acf-5853-34ce-c8840ae045ea.png" width=60%>

設定が完了すると、Runbookの編集画面に遷移する。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/144789/8700468e-e69e-1026-7450-b44cbdbfcfd6.png)

以下のようにPowerShellのスクリプトをRunbookエディタに記述する。

```PowerShell
$AzureCred = Get-AutomationPSCredential -Name "{Your Credential Name}"
Add-AzureAnalysisServicesAccount -RolloutEnvironment '{Your AAS Region Name}.asazure.windows.net' -ServicePrincipal -Credential $AzureCred -TenantId "{Your Directory ID}"
Invoke-ProcessASDatabase -server "{Your AAS URL}" -DatabaseName "{AS Database Name}" -RefreshType Full
```

PowerShellを記述したら、"Save"をクリックして保存し、"Publish"を押して発行する。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/144789/ce5a11ce-6b3d-5fc2-08c3-61f840f26ca3.png)

#### Runbookの実行
Publishが完了したら、Runbookの画面から"Start"をクリックすると即時に処理が実行される。"Schedule"メニューから起動するスケジュールを設定することもできる。エラー無く完了すれば成功となる。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/144789/af5f88ef-03db-49f3-659d-c974f3558024.png)