Azure SDK for Pythonの利用メモ

# Azure SDK for Pythonの利用メモ
## 本記事について
普段のAzure構築ではポータルやPowerShellを使うことが多いのですが、データの集計とエクセル出力までおこなうにあたり使い慣れているPythonを使用したく、SDK for Pythonを使ってみました。
覚書も兼ねて使い方をまとめておきます。基本的にはMicrosoftのドキュメント通りです。
- [Microsoftドキュメント](https://docs.microsoft.com/ja-jp/azure/developer/python/sdk/azure-sdk-overview)
- [SDK for Pythonのリファレンス](https://docs.microsoft.com/ja-JP/python/api/?view=azure-python)

また、所々つまずいたり、面倒だったりした点や対応を"メモ"に記載します。

## SDK for Pythonの概要
- Pythonのサポートバージョンは2.7および3.5.3以上とのこと。　※本記事では3.10.4で動作確認しています。
- 管理ライブラリ(azure-mgmt-XXX)とクライアントライブラリの２つのライブラリが提供されています。
- pipで各ライブラリをインストール、管理。
- Azure REST API上に構築されています。
- **Microsoftドキュメントにも記載がある通り、Azure CLIやPowershellの方が短い文で同じ処理を実装できます。**

## 使ってみた
### ライブラリインストール
`pip install "library name"`でインストール。ライブラリ単位でのインストールが必要になります。
また、プレビューバージョンのライブラリも利用できるようです。

今回はRecovery Serviceコンテナを取得するためのライブラリと、認証のためのライブラリをインストールしてみます。
```
pip install azure-mgmt-recoveryservices
pip install azure-identity
```
※上記に伴って"azure-common", "azure-core"のライブラリもインストールされました。

### ライブラリインポート
必要なメソッドをライブラリからインポートします。
```
from azure.identity import DefaultAzureCredential, InteractiveBrowserCredential
from azure.mgmt.recoveryservices import RecoveryServicesClient
```

### クライアントオブジェクト作成
クライアントを作成します。
```
# 認証用（対話型のブラウザ認証、テナントIDを指定）
credential = InteractiveBrowserCredential(authority="login.microsoftonline.com", tenant_id=TENANT_ID)

# Recovery Serviceコンテナ取得用
# ここでは後述のメソッド単位でのログ出力設定を有効化
rs_client = RecoveryServiceClient(credential, SUBSCRIPTION_ID, logging_enable=True)
```

### クライアントオブジェクトを利用してメソッドを実行（APIリクエスト）
Recovery Serviceコンテナの一覧を取得してみます。
クライアント作成時に指定したサブスクリプション内のRecovery Serviceコンテナの名称が取得できていることが確認できます。
```
for rsv in list(rs_client.vaults.list_by_subscription_id()):
    print(rsv.name)
```

---
認証とログ出力に関してのメモ。
## 認証
### 特徴
- サービスプリンシパル、マネージドID、Azure CLI/PowerShellの認証情報の利用、実行時の対話型での認証などが利用可能
- "DefaultAzureCredential"クラスを利用することで、実行環境に依存した上記の異なる認証方法を1つの処理で実装可能
### メモ
- 認証のためのクライアントもSDK for Pythonのパケージに含まれているため、詳細な仕様はリファレンスかソースコードを確認するとよいです。
  例えば、対話型のブラウザ認証のClassは以下に記載されており、引数が列挙されています。
  [InteractiveBrowserCredentialのClass](https://docs.microsoft.com/ja-jp/python/api/azure-identity/azure.identity.interactivebrowsercredential?view=azure-python)
- "DefaultAzureCredential"を利用した認証の優先順位は、Microsoftのドキュメントに記載されている通りですが、実際にはマネージドIDの次の優先順位で"SharedTokenCacheCredential"というWindows限定のキャッシュによる認証も実施されます。
  [DefaultAzureCredentialの優先順位](https://docs.microsoft.com/ja-jp/azure/developer/python/sdk/authentication-overview#sequence-of-authentication-methods-when-you-use-defaultazurecredential)

  ※自分の環境ではこの認証に引っかかって、これ以降の優先順位の認証が"DefaultAzureCredential"では実行できませんでした。元々今回は対話型の認証を利用するつもりでしたので、直接"InteractiveBrowserCredential"を利用することで回避したため、原因と対応までは追っていません。

## ログ 出力
### 特徴
- ライブラリ単位でログ出力設定が可能
  ただし、"azure"を指定してすべてのライブラリでの出力を設定することも可能
  ```
  import logging
  logger = logging.getLogger("azure") # すべてのライブラリを対象
  logger.setLvel(logging.DEBUG)

  logger.addHandler(HANDLER) # 標準出力やファイル出力を設定
  ```
- HTTPログを含めるにはクライアント単位、認証情報単位、メソッド単位で有効化が必要
### メモ
- **最低限Request URLを確認したいのであればライブラリでINFOレベルのログ出力を設定**することで十分です。思い通りのパラメータが渡せているかのチェックにはこちらです.
- Responseの内容も確認したい場合はHTTPログの出力が必要になります。
- 標準のデバッグログでトラブルシューティングができない場合は、最終手段としてPythonのライブラリそのものにPrintデバッグを仕込むのもアリかと思います。

## 所感
- 目的の処理をおこなうクライアント、メソッドを探すのにそこそこ苦労します。Azure慣れしているとある程度あたりがつくものと思います。
 例えば、Recovery Serviceコンテナではなく、Azureディスクバックアップ等で使われるバックアップコンテナを取得する場合は"azure-mgmt-dataprotection"というライブラリを使用しますが、バックアップコンテナからdataprotectionにたどり着くのに苦労するかもしれません。
 ※dataprotectionはリソースプロバイダー名です。REST APIの説明等も検索してみると良いと思います。
- 取得してきたオブジェクトの取り得る値の定義を知りたい場合は、ライブラリのmodelを確認する必要があります。リファレンスページで探すのが面倒なときはソースコードから見る方が早いかもしれません。
---
## まとめ
Azure CLIやPowerShellの方がお手軽ですが、Pythonの豊富なライブラリを利用して他の処理と統合する場合には便利と思います。
また、個人的にはAzureエンジニアにはPowerShellが好まれがちなイメージがあるのですが、保守性を考慮すると汎用的なPythonの方が属人化せずに保守を続けられるのではと考えています。
用途に応じてうまく使い分けていきたいところです。