普段、Azure Portalから実行しているパラメータ付きのRunbookを、Webhookからの実行に切り替えるときに手間取った内容をまとめます。
結論
- Runbookで「WebhookData」という名前でパラメータを定義する。
- 「WebhookData」の「RequestBody」プロパティからリクエスト送信時に指定したデータを読み取る。
前提
Azure Automationで簡単なスクリプト(Runbook)を作成したことがあることを前提としていますので、Runbookの作成方法などは割愛します。
また、コードはすべてPowerShell(7.2)になります。
背景
Azure Automationでちょっとしたスクリプトを作成して、普段はAzure Portalから実行しています。Azure Portalから実行する際は、実行時にパラメータを入力する画面が表示されます。以下の簡単なRunbook(Powershellスクリプト)を見てみましょう。
Param (
[Parameter()]
[string] $name,
)
Write-Output "$name"
これをPortalから実行すると、以下のようにパラメータの入力を求められます。
このRunbookにWebhookを設定して外部から実行しようと思った時に、どのようにnameパラメータを送ればよいのか悩みました。
結果と設定方法
Webhookでリクエストを送る際のパラメータの仕様
WebhookでRunbookを実行する際は、リクエスト情報が「WebhookData」という名前のパラメータに集約されます。この「WebhookData」の中の「RequestBody」にリクエストボディの内容が格納されます。どういうことなのか試しにWebhook経由でリクエストを送ってみましょう。
$url = "webhookurl"
$param = @{ name="test" }
$body = ConvertTo-Json -InputObject $param
Invoke-RestMethod -Method Post -Uri $url -Body $body -UseBasicParsing
上記のコードを実行して、Runbookで受け取ったリクエスト情報を見てみましょう。Runbookの「ジョブの状態」から確認できます。
webhookDataの中身を整形すると以下のようになります。
{
"WebhookName": "test",
"RequestBody": "{\r\n \"name\": \"test\"\r\n}",
"RequestHeader": {
(略)
}
}
つまり、Runbookでは「WebhookData」という名前のパラメータを設定して、その中の「RequestBody」から情報を取得すればよいということです。
Runbookの修正
先ほど説明した内容を踏まえて修正したRunbookが以下になります。「$name」を「$WebhookData」に変更しています。
Param (
[Parameter()]
[object] $WebhookData
)
$jsonBody = (ConvertFrom-Json -InputObject $WebhookData.RequestBody)
Write-Output "$($jsonBody.name)"
このRunbookをリクエストボディに「name = test」を付与してWebhookで実行すると、以下のように想定通り、「test」がログに出力されます。無事にWebhook経由でリクエストボディの内容を受け取ることができました。
Webhookでのパラメータ指定について
Webhookには予めパラメータを指定できます。
ただし、ここで指定したパラメータはリクエスト送信時に指定した値で上書きされます。さらに、リクエストボディを指定しなかったとしても上書きされます。
おまけ
Powershell 7.1(プレビュー)には、Webhookパラメータが無効なJSONに自動変換される既知の問題があるそうです。以下のようなエラーが発生して30分くらい悩みました。Powershell 7.2では問題なさそうです。
Cannot bind argument to parameter 'InputObject' because it is null
コメント