-Contextを使って認証情報を入力せずにAzureコマンドを実行する

#はじめに
Azureスクリプト初心者の私がAzure上でPowershellスクリプトを作成する時に序盤なにが一番面倒だったかというとリソースを操作する度にコマンドオプションに認証情報を付けないといけない事だったので、Automationなどでスクリプトを作るときの小技として紹介しておきます。
なんと最初に認証情報をContextにして作っておけば一々書かなくてもいいんですよ！

「セッション情報をオブジェクト化して再利用可能にするのは常識でしょ？」ということなのか、意外と情報見つからなかったので初心者の皆様の参考になればと思います。。。

2020/10/30現在でこのContextを作成できるコマンド群はAz.Account(サブスクリプションのアカウント情報)、Az.Storage(ストレージアカウント情報)、Az.Automation(ジョブ実行アカウント)のようです。　今後もアカウント認証が必要なサービスが実装されたらきっと使える幅が広がる、はず

参考情報
[AzurePowershell context objects(MSドキュメント)](https://docs.microsoft.com/en-us/powershell/azure/context-persistence?view=azps-5.0.0)
[Az.Accountsのリファレンス](https://docs.microsoft.com/en-us/powershell/module/az.accounts/?view=azps-5.0.0#accounts)
[New-AzStorageContextのリファレンス](https://docs.microsoft.com/en-us/powershell/module/az.storage/new-azstoragecontext?view=azps-5.0.0)


#Az.AccountのContextの使い方
Az.Account上のコンテキストは「～-AzContext」というコマンド群で扱います。普段Portalログインや「Connect-AzAccount」でログインしたユーザでそのまま操作、構築する場合は意識しませんが、コマンド操作内で意図してユーザ変更をする場合にコンテキスト情報をリストして管理しておけるのでとても便利です。(リソースグループ毎に使えるユーザが違う場合など)

``` AzAccountContext.ps
#最初に必要な分だけログインしちゃう
Connect-AzAccount

#ログインした情報はすべて保管されているのでリストでみてみる
PS C:\Users\hoge> Get-AzContext -ListAvailable

Name                                     Account                                     SubscriptionName                            Environment                                 TenantId                                  
----                                     -------                                     ----------------                            -----------                                 --------                                  
Name1                                    Name1@hoge.onmicrosoft.com                  hogehoge                                     AzureCloud                                  xxxxxxxx-xxxxxxxxx-xxxxx- 
Name2                                    Name2@hoge.onmicrosoft.com                  hogehoge                                     AzureCloud                                  xxxxxxxx-xxxxxxxxx-xxxxx- 

```
通常は最後に接続したユーザが有効になるので毎度ログインし直しかのように見えますが実際はコンテキスト上に認証情報がリスト化されて保存されています。よってこれらを切り替えることによりログイン済みの情報を再利用できます。
また、通常「Name」はAzureから自動でIDが振られていて扱い難いので、わかりやすい名前にして管理することも可能です。
このリストから１つ取り出して-Contextオプションで使えるオブジェクトにしまってみます。

``` AzAccountContext2.ps
#一意のコンテキスト情報を指定してNameを分かりやすいものに変える
PS C:\Users\hoge> Set-AzContext -Name "User1" -Tenant "xxxxxxxx-xxxxxxxxx-xxxxx-"

Name                                     Account                                     SubscriptionName                            Environment                                 TenantId                                  
----                                     -------                                     ----------------                            -----------                                 --------                                  
User1                                    Name1@hoge.onmicrosoft.com                  hogehoge                                     AzureCloud                                  xxxxxxxx-xxxxxxxxx-xxxxx-

#作ったコンテキスト情報をオブジェクトに格納する
PS C:\Users\hoge> $AzContext = Get-AzContext -Name User1

#こんな感じで実行できる
PS C:\Users\hoge> New-AzVM -Name hogeMachine -Context $AzContext

#不要なContextはこれで削除
PS C:\Users\hoge> Remove-AzContext -Name "Name1"

#全部削除はこっち(ポップアップ嫌なら-Force)
PS C:\Users\hoge> Clear-AzContext

```
このようにオブジェクトしておくと作業の間はコンテキストを切り替えることで実行ユーザを簡単に変更することができます。
また、一度コンテキスト情報のリストをきちんと作っておくと、これをファイル形式で保存できるので次回の作業時はファイルをインポートすることでログインする手間を省いてすぐ使うこともできます。
※ただ、これを外部からのバッチ実行ファイル形式にして恒久的に使えるのかまでは検証できていないので自己責任で！

``` AzAccountContext3.ps
#コンテキストのリスト情報を保存する
PS C:\Users\hoge> Save-AzContext -Path ContextJoho.jason

#ファイルからインポートする
PS C:\Users\hoge> Import-AzContext -Path ContextJoho.jason
```

#Az.StorageのContextの使い方
Accountと比較するとBlobStorageは操作毎認証が必要なのでメリットが分かりやすいと思います。StorageKeyでもSASトークンでもやり方は同じで接続情報を設定したコンテキストを作成し、オブジェクトに格納します。

``` AzStorageContext1.ps
#New-AzStoragecontextコマンドでコンテキストを生成する(SASならKeyの代わりに-SasTokenでSASオブジェクトを指定する)
PS C:\Users\hoge> $stKeyContext = New-AzStorageContext -StorageAccountName $storageAccountName -StorageAccountKey $storageKey

#こんな感じで使う
PS C:\Users\hoge> Get-AzStorageblob -Container "hoge" -Context $stKeyContext
```

ちなみに権限さえもっているならKeyの代わりに「-UseConnectedAccount」を使うことで操作ユーザをコンテキストに指定することもできます。

#Az.AutomationのContextの使い方
AutomationスクリプトはAutomationの実行アカウントを使って各リソースを操作するためにAz.Accountのコンテキスト情報をAutomationアカウントの情報を使って作ります。(要はAutomationアカウントでPortalに自動ログインするイメージです)

``` Az.AutomationContext.ps
#デフォルトで作ると名前は固定
$connectionName = "AzureRunAsConnection"

#Automationアカウントの認証情報を格納
$conn = Get-AzAutomationConnection -Name $connectionName

#Portalに接続
Connect-AzAccount -ServicePrincipal -Tenant $conn.TenantID -ApplicationId $conn.ApplicationID -CertificateThumbprint $conn.CertificateThumbprint

#コンテキスト情報を作成
$AzureContext = Select-AzSubscription -SubscriptionId $conn.SubscriptionID

#こんな感じで実行できる
New-AzVM -Name hogeMachine -Context $AzContext

```
Automationのコンテキスト情報はSubscriptionで指定しており、Accountで作成したコンテキストと格納内容が違うように見えますが、Automationアカウントは実行アカウントをサービスプリンシパルという形態で持っている為ユーザと異なり独自にサブスクリプションIDを保持しているのでこれで一意に実行者を絞れるのです。
Automationに興味があったらこちらに過去記事([AzureAutomationの仕組みと設定内容](https://qiita.com/sakamichihassin/items/3bd4c175a7c7c3fb6f3c))あるので参考にしてみてください。


#まとめ
QiitaAzureタグのイベントを見て自分が一番使う小技について記事をまとめてみました。
Azureに関する記事は開発の方が活発でインフラ系統の記事を見つけるのは中々大変なのですが、今までずっと先行の方たちが試行錯誤した結果を頂いてばかりだったので少しでも貢献できれば良いと思います。