![見出し画像](https://assets.st-note.com/production/uploads/images/134215485/rectangle_large_type_2_436a5f09c75daddfc585f887a0c83e52.jpeg?width=1200)
ロジックアプリでAzureのコストを毎日Slackに通知する
Sentinelの運用を始めてから、知らないうちにコストが跳ね上がったりしないかと心配なのでコストアラートを設定し、その上で毎日Azureのコストを目視で確認していました。
ある程度続けた後、自動化したいなあと思い色々調べたところ、「Cost Management API」なるものがある事を知ったので、それを利用してコストを自動通知できるように設定してみました。
実装内容について
どういった内容で実装したか、要件をざっくり書いておきます。
実装方法と通知方法
最初はGASでの実装を、と思ったのですが、AzureのことはAzureで完結したい気分だったのでロジックアプリで実装することにしました。
通知先はSlackに。通知内容としては、
当月の通知時点の累積コスト
当月の通知時点の種別コスト
の2つを毎日1回、指定の時間になったら取得して通知するようにします。
ロジックアプリを実装する
ということで、まずロジックアプリを作成します。名前は「cost_reminder」とし、プランは従量課金で作ります。
マネージドIDを作成する
リソースを作成したら、マネージドIDを作成します。マネージドIDについては下記に説明がありますが、マネージドIDを使うとAPI叩くのにトークンを取得してエンドポイントに引き渡して、という処理をせずに結果を得ることができます。
ロジックアプリの「ID」から「システム割り当て済み」タブの「状態」を「オン」にすると、システム割り当てのマネージドIDが作成されます。
![](https://assets.st-note.com/img/1710661454377-lf39FsnI94.png?width=1200)
次に「Azureロールの割り当て」からマネージドIDにコストの確認に必要な「コスト管理の閲覧者」ロールを割り当てます。
![](https://assets.st-note.com/img/1710661454165-pHKto77Eo3.png?width=1200)
トリガーを作る
マネージドIDの作成が済んだら、「ロジックアプリデザイナー」から構成を組んでいきます。
毎日コスト通知してほしいので、トリガーは「スケジュール」で検索して繰り返しのトリガーを選び、間隔を1日、設定時刻を9時にします。
![](https://assets.st-note.com/img/1710661813606-EGlq8g9HQw.png?width=1200)
ちなみに日本はUTC+9なので実際に動くのは18時です。
APIからコストの情報を取得する
次にHTTP処理を追加します。利用しているAPIについては下記を参照。
![](https://assets.st-note.com/img/1710661454066-m1KZrAZHuD.png?width=1200)
URIの途中は自分のサブスクリプションIDです。本文にはAPIからどんな形でデータを返してもらうかを指定するのですが、これを自力で書くのはなかなか骨が折れます。
ただ、「Cost Management APIで種別で当月のコストを取得したいんだ!」とChatGPTさんにダメ元で聞いてみたら、意外と物知りでちゃんと使えるものを吐き出してくれたので簡単に実装できました。
次にAPIから帰ってきたレスポンスを解析します。「コンテンツ」にはHTTP処理の「本文」を指定し、スキーマを指定します。
![](https://assets.st-note.com/img/1710662544246-pc1WlXbpAP.png?width=1200)
「サンプルのペイロードを使用してスキーマを作成する」から実際の応答結果を食わせると、そこから勝手にスキーマを組んでくれるので、一度応答をそのまま出力して控えておくとスムーズです。
データを表示用に加工する
次に種別コスト用の配列と合計コスト用の変数を作成します。コストがFloatで返ってくるので、合計コスト用の変数は種類をFloatにしています。
![](https://assets.st-note.com/img/1710662544196-m2djYNx8sv.png?width=1200)
入れ物を作ったら次は反復処理でデータを整形します。JSONの解析結果の「rows」配列から種別名とそのコストを一つずつ取りだして先に作成した配列と変数に格納します。
![](https://assets.st-note.com/img/1710662921563-ihwPdm3LSZ.png?width=1200)
種別名とコストはそれぞれ下記関数で取得しています。「配列から各データを取り出す」は反復処理名です。
コスト:items('配列から各データを取り出す')?[0]
種別名:items('配列から各データを取り出す')?[2]
また、ロジックアプリでFloatをintにする処理がよくわからなかったので、splitで小数点より前だけ取得する形にしています。
split(string(variables('total_cost')), '.')[0]
処理が済んだら結合を用いて配列を円+改行コード( 円\n )の形で結合し、出力用変数に結合した結果と合計費用をそれぞれ入れます。
最後に変数をSlackにメッセージとして投げ込む形に整えます。
![](https://assets.st-note.com/img/1710662921708-JDRlLVinWG.png?width=1200)
ちなみに結合の条件がデザインビューだとうまく設定できなかったので、コードビューで設定しています。コードビューで見ると下記の形になっています。
"結合": {
"inputs": {
"from": "@variables('cost_list')",
"joinWith": "円\\n"
},
"runAfter": {
"配列から各データを取り出す": [
"Succeeded"
]
},
"type": "Join"
},
何度かメッセージを投げながら調整して、最終的にこんな感じでSlackに出力するようにしました。
![](https://assets.st-note.com/img/1710663417179-U2hJI8GHrl.png?width=1200)
一番上に合計コストを記載し、下に種別の内訳を表示するようにしています。
処理全体の流れはこんな感じです。
![](https://assets.st-note.com/img/1710663417271-2qm3V7f2Vj.png?width=1200)
けっこう学びがあった
実装後1週間ほど眺めてみましたが、通知も内容も問題なさそうです。コスト確認がちょっと楽になりました。
また、副産物としてマネージドIDやロジックアプリに関しての知見もある程度深まりました。Microsoft周辺だとIntuneやMDE、Azure Open AIも利用しているので、それらとの連携の際にも利用できそうです。
ロジックアプリをちゃんと作るのは初めてだったので、結構楽しい作業でした。これからも活用してみたいと思います。