概要
MattermostとAzureのサービスを連携してChatOpsをしたいと思い、サクッとできるんじゃないかと思っていたら意外と苦労したためその方法をメモします
目標
- Mattermostからチャット(カスタムスラッシュコマンド)で何か操作を行えるようにする
前提
- WSL 2(ubuntu 18.04)
- Mattermost v5.18.0
- Azure Function v3(Powershell)
MattermostとAzureの組み合わせ
AzureのサービスではLogicAppsがローコードでいけて良さそうと思ったんですが・・
LogicAppsと組み合わせてみる
愚直にMattermostと組み合わせるとダメでした。カスタムスラッシュコマンド実行時に付与される認証とLogicAppsの認証が混在しLogicAppsの実行に401 UnAuthorizedで失敗します。こちらが詳しく解説してくれています。わたしはあきらめた。。
Functionと組み合わせてみる
Functionも認証機能を持ちますが設定によってanonymousアクセスを有効(関数内で認証機能を独自に実装する必要あり)にできるのでこれでやります。
Mattermostカスタムスラッシュコマンドとは
Mattermostのチャット上で /<slash_command名>
と発言すれば、任意の場所にデプロイしたプログラムをHttp経由で起動できるものです。これを利用すればチャット上から楽に運用操作ができます。
詳しくは公式ドキュメントを参照してください。
ローカル環境を構成する
Functionを開発する環境を構成します。Mattermostは適宜準備ください。
開発はCLIベースで行います。
- Azure Functions Core Toolsをインストールする
- Azure CLIをインストールする
- .NET Core SDKをインストールする
Azure Functionを開発する
公式ドキュメントを参考にAzure Functions Core Toolsを使ってHttpTrigger templateをベースに開発をします。
プロジェクトを作成する
HttpTrigger templateを使ってコードを生成します。
公式ドキュメントに従って開発してください。
Functionの認証機能をanonymousにする
カスタムスラッシュコマンドに認証機能があるため、Functionの認証機能は無効にします。
前述したMattermostの公式ドキュメントよりカスタムスラッシュコマンドを発行したとき、Functionを呼び出すリクエストに認証Tokenを含めることができます。
生成したコードに修正を加えます。function.json
を以下のようにします。
{
"bindings": [
{
- "authLevel": "function",
+ "authLevel": "anonymous",
"type": "httpTrigger",
"direction": "in",
"name": "Request",
"methods": [
"get",
"post"
]
},
{
"type": "http",
"direction": "out",
"name": "Response"
}
]
}
カスタムスラッシュコマンドの実行処理を記載する
自動生成したrun.ps1
を以下のようにします。レスポンスボディの仕様はSlash Commands parameterを参照してください。
以下の例では実処理は何もしておらず、Mattermostに多少リッチにレスポンスするコードを加えています。これはAttachment機能を利用します。
また認証機能としてFunctionAppの環境変数(アプリケーション構成)に設定されたTokenとHttpリクエストのTokenヘッダが一致するかをチェックします。
TokenはMattermostにカスタムスラッシュコマンドを登録したときに自動的に発行されます(後述)。
using namespace System.Net
param($Request, $TriggerMetadata)
$green = "#44ff1f"
$red = "#FF0000"
$retStatus = [HttpStatusCode]::OK
$retBody = @{
"response_type"="in_channel"
"attachments"=@(
@{
"title"= "Result"
"color"=$green
"text"="message"
}
)
}
$authorizationHeader = $Request.Headers.Authorization
$token = $authorizationHeader.split(' ')[1]
if ($token -eq $env:MattermostCustomSlashToken) {
$retBody["attachments"][0]["text"] = "Success!"
} else {
$retBody["attachments"][0]["text"] = "Invalid token is set"
$retBody["attachments"][0]["color"] = $red
$retStatus = [HttpStatusCode]::UnAuthorized
}
Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{
StatusCode = $retStatus
Body = $retBody | ConvertTo-Json | Out-String
})
Functionをデプロイする準備を行う
AZ CLIを使って構築します。事前にaz login
コマンドで認証する必要があります。
リソースグループ名など名前はお好みで変えてください。
ストレージアカウントを構築する
az storage account create \
--name sttestslash \
--location japaneast \
--resource-group rg-test-slash-jpeast \
--sku Standard_LRS
FunctionApp(v3)を構築する
az functionapp create \
--resource-group rg-test-slash-jpeast \
--consumption-plan-location japaneast \
--runtime powershell \
--functions-version 3 \
--name func-pwshfunc-jpeast \
--storage-account sttestslash
開発した関数をFunctionAppにデプロイする
func azure functionapp publish func-pwshfunc-jpeast
うまくいくと以下のようになります。Invoke urlは後述の手順で利用します。
# func azure functionapp publish func-pwshfunc-jpeast
Getting site publishing info...
Creating archive for current directory...
Uploading 5.18 KB [###########################################]
Upload completed successfully.
Deployment completed successfully.
Syncing triggers...
Functions in func-pwshfunc-jpeast:
HttpExample - [httpTrigger]
Invoke url: https://func-pwshfunc-jpeast.azurewebsites.net/api/httpexample
MattermostのカスタムスラッシュコマンドをAzure Functionと統合する
デプロイしたFunctionとMattermostを統合します。
カスタムスラッシュコマンドを作成する
Mattermost公式ドキュメントを参照して作成する
- ホーム > 統合機能> スラッシュコマンド を選択
- 最低限の入力は以下に示したパラメータとなります
- タイトル: 任意のタイトル
- コマンドトリガーワード: コマンド名(頭にスラッシュは不要)
- リクエストURL: カスタムスラッシュコマンド用に開発したFunctionの
Invoke url
- 保存し設定完了したらトークンを控えます。この文字列で認証を行います。
TokenをFunctionAppに設定する
- Azureポータルより作成したFunctionAppにアクセスし、新しいアプリケーション設定を追加します
-
MattermostCustomSlashToken
とう名前で追加し値はTokenを設定します
Mattermostからカスタムスラッシュコマンドを呼び出す
チャットに /
付きでコマンドを打ち込み、Enterで実行します
以下のように処理結果が返却されれば成功です!
あとはFunctionを実装すれば、VM起動・停止とかMattermostから操作ができますね!
以上