TeamsでChatOps!? TeamsからAzuru FunctionsとAzure Automationで仮想マシンの管理を行なう
先日タイに出張していたのですが、連日30度を越えていて非常に暑かったです。
帰ってきたら20度以上の温度差で少し風邪をひいてしましました。体調管理には気を付けたいものです。
さて今回は思い付きのアイディアを形にしていく自由研究スタイルでいきたいと思います笑
私は検証用にAzureで仮想マシンを動かしておりますが、やっぱり節約しなきゃ!ということで小まめに停止をしております。
ただ毎回Azureのポータルで操作するのってやっぱり面倒くさいですよね。
ということで、TeamsのBot経由でやってしまおう!というのが今日の内容です。今回は仮想マシンの停止のみですが、スクリプトの書き方によってはもちろん仮想マシンの起動や作成、インスタンス変更なんかもできます。すべてはスクリプトの書き方次第でどうとでもなります。
そんなプチChatOps(そんな大それたものではないけれど)が今回のテーマでございます。
Azureを使うのでサブスクリプションが無い方は試用版を取得しておいてください。
やろうとしていること
今回はシンプルに以下のような流れを想定しています。
①Microsoft TeamsでBotユーザーに対して特定の文字列(stop-vm)を打つとAzure FunctionsにHTTPリクエストを投げる
②Azure Functionsが起動し、ユーザーに対してメッセージを返すともにAzure AutomationにHTTPリクエストを投げる
③Azure Automationが仮想マシンの停止スクリプトを実行
④仮想マシンのシャットダウンが完了したらIncoming Webhookでユーザーに通知
とっても雑な絵ですが、こんな感じ。
直接Azure Automationに投げてもできるかもしれませんが、Azure Functionsを経由した方がインタラクティブに対応できますし、これから開始や仮想マシンごとの停止、インスタンスの変更などを考えたときにFunctionsの方が自由度が効くと思ってこうしております。
これを実現するために、以下の準備を行います。
1.一連の処理が終わったら特定のチャネルにメッセージを送信できるようにIncomingWebhookを用意しておく
2.Azure Automationで仮想マシンの停止のRunbookを用意しておく
3.Azure Functionsで関数を用意しておく
4.Teamsにカスタムボットを登録し、Azure FunctionsにHTTPリクエストを投げれるようにしておく
それではそれぞれ見ていきましょう。
1. Teams側でIncoming Webhookを追加しておく
こちらは以前の記事を参照して用意しておいてください。
2. Azure AutomationのRunbookを用意する
以下のページを参考に、仮想マシンを操作するRunbookを作成しました。
Azure Automation で VM を自動停止する – Japan Azure Technical Support Engineers' Blog
今回は「Runbook の編集」章で記載がある、「サブスクリプション内の、すべての VM」を停止するようにします。
なお、仮想マシンが停止後、Incoming Webhook経由でメッセージを投げるために、後半のforeach文を以下のようにしております。
foreach ($VM in $VMs) { # VM を停止 $StopRtn = $VM | Stop-AzureRmVM -Force -ErrorAction SilentlyContinue $URI = <1. で作成したIncoming WebhookのURL> # 正常に VM が停止したかの確認&ステータスの出力 if ($StopRtn.Status -ne 'Succeeded') { Write-Output ($VM.Name + " failed to stop.") Write-Error ($VM.Name + " failed to stop. Error was:") -ErrorAction Continue Write-Error (ConvertTo-Json $StopRtn.Error) -ErrorAction Continue $body = ConvertTo-JSON @{ text = $VM.Name + " failed to stop." } Invoke-RestMethod -uri $URI -Method Post -body $body -ContentType 'application/json' } else { Write-Output ($VM.Name + " has been stopped.") $body = ConvertTo-JSON @{ text = $VM.Name + " has been stopped." } Invoke-RestMethod -uri $URI -Method Post -body $body -ContentType 'application/json' }
Runbookを保存したら、Webhookを追加します。
Webhookの追加をクリック。
任意の名前など必要な設定値を入力して作成。URLが表示されるので控えておいてください。
3. Azure Functionsを用意する
今回は全てPowerShellで書こうと思いますので、「PowerShell」-「HTTP - trigger」を選択します。
とても簡単ですが、以下のようなものを準備しておきました。
$requestBody = Get-Content $req -Raw | ConvertFrom-Json $text = $requestBody.text Out-File -Encoding Ascii -FilePath $res -inputObject $input $vms = Get-Content $inputTable | ConvertFrom-Json if($text -like "*stop-vm*"){ $hash = @{ type = "message"; text = "OK. Wait a moment."; } $URI = <2で取得したAzure AutomationのWebhookのURL> Invoke-RestMethod -uri $URI -Method Post -body $body -ContentType 'application/json' } else{ $hash = @{ type = "message"; text = "please use the folowing comend.<br>stop-vm -vm 'VM name'"; } } $input = $hash | ConvertTo-Json Out-File -Encoding Ascii -FilePath $res -inputObject $input
stop-vmコマンドが来たら2で作成したAzure Automationに投げる、それ以外はヘルプ的なものを出す、といった形にしています。
こちらもWebhookを追加します。
4. Teams側でカスタムボットを追加する
チームの管理から「カスタムボットの作成」をクリック
3で発行したURLや名前、説明を入力し、作成
これで準備が完了です。