Webhook経由でAzure Automationを実行するときのパラメータの指定方法

Azure

普段、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

Powershell 7.1はすでにサポートされなくなったため、使用することはないと思います。私は昔作ったものを移行せずに使い続けていたため発生しました。

コメント