【Azure Function】Azure利用料金をSlackに通知する

2022年8月10日掲載

キービジュアル

クラウドエンジニアリング本部の宮田銀河です。本記事では、”Azure利用料金をSlackに通知する”システムの実装方法を説明します

Azure利用料金は、Azure Portalのコスト分析で確認することができます。しかし、利用料金を確認するためだけに、Azure Portalを操作するのは面倒です。さらに、リソース所有者ごとの利用料金の確認は、それ以上に面倒です (フィルタ操作が必要なため)。

そのため、情報の確認がしやすいSlackに、料金情報を通知したい要望がありました。その要望を満たすべく、新卒1年目のAzure初心者が、Azure FunctionとSlackのワークフロービルダーを使用して実装しました。

目次

  • 本記事では、Azure利用料金をSlackに通知する方法を説明します。
  • Azure FunctionとSlackのワークフロービルダーを使用します。
  • リソース所有者ごとの利用料金も通知可能です。

システム構成図

システム構成図とSlack通知例 (右上) を下図に示します。

Azure利用料金をSlackに通知するシステム構成
  1. Azure FunctionからCost Mangement APIを使用して、1週間の料金情報を取得

  2. その情報を加工してSlackに通知

このシステムを実装するにあたり、以下を実施しました。

  • Azureリソースに所有者タグを設定

  • SlackにIncoming Webhookの追加

  • Azure Functionのデプロイ

Azureリソースに所有者タグを設定

前述の通り、私たちの部署では、Azureの利用料金だけではなくリソース所有者ごとの利用料金も確認したい要望がありました。この要望を満たすためには、事前に所有者情報をリソースに設定する必要があります。そこで、ベストプラクティスに則り、所有者を意味する”owner”タグを各リソースに設定しました。マルチクラウド対応を見据えたリソースタグ制約を考慮して、下記画像に示すタグを設定しました (Azure Policyを使用すれば、ほぼ全てのリソースに簡単にタグを付与することができます。その話はまた次の記事にします)

リソースに設定するタグ

SlackにIncoming Webhookの追加

利用料金をSlackに通知するために、Incoming Webhookを使用する必要があります。

このIncoming Webhookを使用するためには、大きく2つの方法があります(2022年8月現在)。

  1. ワークフロービルダーを利用する

  2. カスタムアプリを使用する

後者の方が、UIのカスタマイズ性は高いです(Block Kitを使えるため)。ただし会社や組織ポリシーによっては、カスタムアプリの作成ができない場合があります。したがって本記事では前者の”ワークフロービルダーを利用する”方法を説明します。

ワークフローの追加

  1. チャンネル名をクリックするとインテグレーションタブが表示されるので、ワークフローを追加するをクリックします。

ワークフローの追加

2.ワークフロービルダーの画面右上にある作成をクリックすると、下記のポップアップ画面が表示されます。適当な名前を設定した後、次へをクリックし、Webhookを選択します

Webhookワークフローの追加

3.Webhookの設定において、変数を追加するをクリックして、キー:textデータタイプ:テキストを指定して、次へをクリックする。

4.ステップを追加をクリックします。メッセージのテキストに変数を挿入するをクリックしてtextを挿入して、保存します

webhookの変数設定

5. 面右上の公開するボタンをクリック すると、ワークフローを準備する準備ができましたとポップアップが表示され、WebhookのURLが生成されます。このURLは後ほど使用します(後述するSLACK_WORKFLOW_WEBHOOK_URLに該当)。

webhookの公開

Azure Functionのデプロイ

画像に示すAzure Functionを作成している前提で説明をします。

  • 公開: コード
  • ランタイムスタック(バージョン): Python (3.8)
  • プラン: 消費量(サーバレス)
Azure Funcitonの設定

Azure Functionのロール設定

利用料金情報を取得するためには、コスト管理の閲覧者のAzureロールが必要です。

Azure Function=>設定=>IDをクリックして、Azureロールの割り当てをクリックします。

Azure Functionのロール設定

画像に示すように、コスト管理の閲覧者でリソース名:サブスクリプションを割り当てます。この割り当て完了後に、Azure Functionが利用料金情報を取得可能になります。

コスト管理の閲覧者ロールの設定

Azureのコード

Slack通知コード

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円”}

Slackへの通知例

料金取得コード

 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に通知したい場合は、ご参考にしていただけると幸いです。

関連サービス

Microsoft Azure

Microsoft Azureは、Microsoftが提供するパブリッククラウドプラットフォームです。コンピューティングからデータ保存、アプリケーションなどのリソースを、必要な時に必要な量だけ従量課金で利用することができます。

MSPサービス

MSP(Managed Service Provider)サービスは、お客さまのパブリッククラウドの導入から運用までをトータルでご提供するマネージドサービスです。

おすすめの記事

条件に該当するページがございません