フォーム読み込み中
クラウドエンジニアリング本部の宮田銀河です。本記事では、”Azure利用料金をSlackに通知する”システムの実装方法を説明します
Azure利用料金は、Azure Portalのコスト分析で確認することができます。しかし、利用料金を確認するためだけに、Azure Portalを操作するのは面倒です。さらに、リソース所有者ごとの利用料金の確認は、それ以上に面倒です (フィルタ操作が必要なため)。
そのため、情報の確認がしやすいSlackに、料金情報を通知したい要望がありました。その要望を満たすべく、新卒1年目のAzure初心者が、Azure FunctionとSlackのワークフロービルダーを使用して実装しました。
システム構成図とSlack通知例 (右上) を下図に示します。
Azure FunctionからCost Mangement APIを使用して、1週間の料金情報を取得
その情報を加工してSlackに通知
このシステムを実装するにあたり、以下を実施しました。
Azureリソースに所有者タグを設定
SlackにIncoming Webhookの追加
Azure Functionのデプロイ
利用料金をSlackに通知するために、Incoming Webhookを使用する必要があります。
このIncoming Webhookを使用するためには、大きく2つの方法があります(2022年8月現在)。
後者の方が、UIのカスタマイズ性は高いです(Block Kitを使えるため)。ただし会社や組織ポリシーによっては、カスタムアプリの作成ができない場合があります。したがって本記事では前者の”ワークフロービルダーを利用する”方法を説明します。
チャンネル名をクリックするとインテグレーションタブが表示されるので、ワークフローを追加するをクリックします。
2.ワークフロービルダーの画面右上にある作成をクリックすると、下記のポップアップ画面が表示されます。適当な名前を設定した後、次へをクリックし、Webhookを選択します。
3.Webhookの設定において、変数を追加するをクリックして、キー:text、データタイプ:テキストを指定して、次へをクリックする。
4.ステップを追加をクリックします。メッセージのテキストに変数を挿入するをクリックしてtextを挿入して、保存します。
5. 面右上の公開するボタンをクリック すると、ワークフローを準備する準備ができましたとポップアップが表示され、WebhookのURLが生成されます。このURLは後ほど使用します(後述するSLACK_WORKFLOW_WEBHOOK_URLに該当)。
画像に示すAzure Functionを作成している前提で説明をします。
利用料金情報を取得するためには、コスト管理の閲覧者のAzureロールが必要です。
Azure Function=>設定=>IDをクリックして、Azureロールの割り当てをクリックします。
画像に示すように、コスト管理の閲覧者でリソース名:サブスクリプションを割り当てます。この割り当て完了後に、Azure Functionが利用料金情報を取得可能になります。
Slack通知部分のコードを以下に示します。
# textには、送信したい情報を入れます。
test_data={“text”:text}
data = json.dumps(test_data)
# 日本語対応するための処理
data = f"{data.encode('unicode-escape').decode('utf-8')}".replace("\\\\", "\\")
headers = { "Content-type": "application/json"}
requests.post(
"WORKFLOW_WEBHOOK_URL", headers=headers, data=data
)
Slackに日本語を送信するためには、1つ工夫が必要です。送信したいテキストをunicode-escapeにエンコードした後に、utf-8にデコードする必要があります。
(例. “あいうえお”は、”\\u3042\\u3044\\u3046\\u3048\\u304a”になります)
WORKFLOW_WEBHOOK_URLには、前述のWebhookのURLを指定します。試しに以下のtest_dataで実行すると、下記画像のようなSlack通知が可能です。
{“text”:”bust_in_silhouette:ownerごとのコスト一覧 (2022-06-18 ~ 2022-06-25 )\r\nAさん-----100円\r\nBさん-----10円”}
Azureの利用料金情報を取得するためには、Cost Management APIを使用する必要があります。このAPIリクエストに必要なパラメータの指定が (issue作成されるほど) 難しいです。なので、Web UIで意図したレスポンスが取得可能になった後で、コード実装することをお勧めします。1週間のコスト情報を取得可能なパラメータ定義とAPIコールするコードを以下に記します。
# 期間の指定
dt_now = datetime.datetime.now().replace(hour=0, minute=0, second=0, microsecond=0)
from_date = dt_now - datetime.timedelta(days=7)
# queryパラメータの設定
cost_parms = {
"timeframe": "Custom",
"type": "ActualCost",
"dataset": {
"granularity": "None",
"grouping": [{"type": "TagKey", "name": "Owner"}],
"aggregation": {"totalCost": {"name": "Cost", "function": "Sum"}},
},
"include": ["Tags"],
"timePeriod": {
"from": from_date.isoformat(),
"to": dt_now.isoformat(),
},
}
cost_management_client = CostManagementClient(DefaultAzureCredential())
# Cost Management API叩く
resource_cost_result_dict = cost_management_client.query.usage(
scope=f"/subscriptions/”SUBSCRIPTION_ID"}/",
parameters=cost_parms,
)
“SUBSCRIPTION_ID”は所有しているAzureサブスクリプションのIDを入力します。
パラメータの"grouping": [{"type": "TagKey", "name": "Owner"}]により、onwerタグごとのリソース料金情報を取得可能です。resource_cost_result_dictには、onwerタグごとのリソース料金情報が格納されています。後は好きなように整形した後、前述したSlack通知コードにデータを渡せば通知できます。
実装を進める過程で勉強になったことは、以下でした。
ワークフロービルダーのIncoming Webhookを使うと、一部の文字を太字にしたり動的にメンションしたりすることができない
Cost Management APIパラメータの適切な指定
Slackで日本語文字を表示させる方法
SlackのワークフロービルダーとAzure Functionを使用して、Azure利用料金をSlackに通知する機能を実装しました。これにより、Slack上で以下の情報が確認可能になりました。
1週間のAzure利用料金
リソース所有者ごとのAzure利用料金
この通知システム実装後に、検証環境の利用者にアンケートをしたところ、以下の意見をいただきました。
「所有者ごとの利用料金の高い順でSlackに投稿されるので、できるだけコストを減らそうと思うようになった」
「Slackの方がメールよりも確認しやすくて便利。行動に移しやすい」
また、Azureの利用料金が約50%減少し、コスト意識の向上にもつながったと感じています。
今後Azureの利用料金をSlackに通知したい場合は、ご参考にしていただけると幸いです。
条件に該当するページがございません