Azure Functions for PowerShell をつかって Azure の操作をやってみた

Windows Virtual Desktop の制御を Power Apps からやろうとしているので、Azure の操作を PowerShell で操作可能な Azure Automation を使ったのですが、実運用には全く耐えられないことがわかりました。
そもそも、Azure Automation はバッチ処理みたいな自動運用のためのサービスなんですよね。
なので、Azure Automation に実行要求を投げても、すぐには実行されずキュー待ちとなり、その後キューが実行されて初めて処理が実行されるのです。
早いときはそこそこ早いのですが（それでも2分ぐらい待つ）、遅いときは4~5分待つこともザラ。
ユーザー操作に対してのレスポンスがこれだと、正直使い物にならないですよね。

ですので、要求後即時実行可能で、PowerShell ができる Azure Functions for PowerShell を使ってみることにしました。

# Azure Function for PowerShellを作る

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/269159/94bb7f1d-1393-5d7a-2c73-fd446e09cf5b.png)

ここで、ランタイムスタックを PowerShell Core に指定します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/269159/f72332e4-f212-60f3-5343-1e3c23203b9b.png)

あとは、Azure Functions を普通に作るのと一緒です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/269159/a2e043a1-71d1-6395-c83c-39f6ec268446.png)

# 関数の作成

関数の作成も Python などと同じです。
VS Code を環境にすることもできますし
ポータル上で直接開発することもできます

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/269159/435a3f40-32d3-801e-b3ea-a9d677118653.png)

テンプレートも豊富に存在します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/269159/c8181df8-883b-35a3-a00c-21c77d9e17fc.png)

仮に HTTP trigger を指定すると、以下のように自動生成されます。

``` Powershell:run.ps1
using namespace System.Net

# Input bindings are passed in via param block.
param($Request, $TriggerMetadata)

# Write to the Azure Functions log stream.
Write-Host "PowerShell HTTP trigger function processed a request."

# Interact with query parameters or the body of the request.
$name = $Request.Query.Name
if (-not $name) {
    $name = $Request.Body.Name
}

$body = "This HTTP triggered function executed successfully. Pass a name in the query string or in the request body for a personalized response."

if ($name) {
    $body = "Hello, $name. This HTTP triggered function executed successfully."
}

# Associate values to output bindings by calling 'Push-OutputBinding'.
Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{
    StatusCode = [HttpStatusCode]::OK
    Body = $body
})

```

# Azure の認証

PowerShell で各種処理を行いたいときには、まずは Azure にて認証をしてあげる必要があります。

Azure Funtions には、マネージドIDを使って Azure RBAC を使用した認証を行うことができます。

デフォルトはオフになっていますので、こちらを有効化します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/269159/d6901476-305d-c080-7f78-66772c1b1f2f.png)

あとは、操作したいリソースに対して、Azure ロールを割り当てることで、実行時に自動認証され、アクセス権が付与されます。

# あとは・・・

自分の好きなように PowerShell を書いていただくことで、Azure の操作を自由に行うことができるようになります。

# CI/CDももちろんできる！

デプロイセンターから様々なリポジトリを選択して、CI/CDを作ることもできます！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/269159/1aa2cfdb-1b5d-4494-c094-3c4ab15f013c.png)

もちろん Azure Devops の Pipeline から、リポジトリの更新をトリガーとして、自動的にビルドされ、デプロイが完了します！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/269159/08ab0c91-12c4-2ead-1aff-fe279a1300a5.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/269159/868900b4-3a0e-1b0a-cd86-e1e5cb7736dc.png)


# おまけ

Windows Virtual Desktop を Power Apps を使って操作することができます！
これも Azure Functions for PowerShell のおかげです。

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr"><a href="https://twitter.com/hashtag/WVD?src=hash&amp;ref_src=twsrc%5Etfw">#WVD</a> の起動停止制御、及びセッション状態の取得を <a href="https://twitter.com/hashtag/PowerApps?src=hash&amp;ref_src=twsrc%5Etfw">#PowerApps</a> を使ってできるようにしたのを動画にしました！<br>実際の操作処理を <a href="https://twitter.com/hashtag/AzureFunctions?src=hash&amp;ref_src=twsrc%5Etfw">#AzureFunctions</a> に変更したことで、かなり実用的な速度にすることができました！！<br>なお、Azure Functions のコードは PowerShell で作成しています！<br>※2.5倍速です <a href="https://t.co/49NP7AMeuC">pic.twitter.com/49NP7AMeuC</a></p>&mdash; りなたむ MVP 🇯🇵 | Ryota Nakamura (@R_t_A_n_M) <a href="https://twitter.com/R_t_A_n_M/status/1342004456393637889?ref_src=twsrc%5Etfw">December 24, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>