はじめに
本記事では、Power AutomateのWebhook経由で、Lambda関数の処理結果をTeamsのチャネルに投稿する方法を紹介します。具体例として、AWSのコスト情報を取得するケースを用いて説明します。
システム構成の概要
今回構築するシステムは、Teamsの特定のチャネルに対して定期的にAWSのコスト情報を投稿します。(ここでは自動投稿システムと呼ぶことにします)
自動投稿システムでは、以下のサービス・機能を使用します。
- Amazon EventBridge: 定期的にLambda関数を実行します。
- AWS Lambda: AWS Budget APIを使用してAWSのコスト情報を取得します。その後、コスト情報を含めたHTTP POSTリクエストをWebhook URLへ送信します。
- Power Automate (Workflow): Webhookへのリクエストを受信後、コスト情報を含めた投稿用メッセージを作成し、Teamsへ送信します。
- Microsoft Teams: メッセージを指定されたチャネルへ投稿します。
設定手順
本章で自動投稿システムの設定手順を説明します。
Lambda関数を作成する
AWS Lambda関数を作成し、適切な処理を記述します。今回は例としてPythonでコードを記述します。また、AWS Budget APIを利用してコスト情報を取得します。
以下の手順に沿ってLambda関数を作成してください。
- 関数の作成: AWS管理コンソールにログインし、Lambdaのコンソール画面に移動したら関数を作成します。ランタイムはPythonを選択してください。
- ソースコードの貼り付け: 関数の[コード]タブに移動し、本章に記載のソースコード(lambda_function.py)(*)を貼り付けてデプロイします。
- 環境変数の追加: AWSのコスト情報を取得し、POSTリクエストをWebhook URLへ送信するために、ソースコード内で以下の環境変数を参照しています。関数の[設定]タブに移動し、環境変数の編集画面で以下の情報を追加してください。
AWS_ACCOUNT_ID
: AWSアカウントIDBUDGET_NAME
: [Billing and Cost Management]コンソールで作成した予算の名前TEAMS_WEBHOOK_URL
: POSTリクエストの送信先となるWebhook URL(現時点ではWebhook URLが生成されていないため、後述のPower AutomateのWebhook URLを確認してLambda関数に設定するで設定します)
- IAMロールの追加: 関数を作成したときにデフォルトの実行ロールが関数に割り当てられますが、AWSのコスト情報を取得するための権限が不足しているため、IAMロールに必要な権限を追加します。ここでは、以下のマネージドロールを追加します。
- AWSBudgetsReadOnlyAccess
- タイムアウトの変更: デフォルトのタイムアウト値は3秒ですが、デフォルトのまま関数を実行するとタイムアウトエラーが発生するはずです。関数の[設定]タブに移動し、一般設定の編集画面でタイムアウト値を変更してください。(目安は5秒)
(*)ソースコード
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 |
import boto3 import json import logging import os from urllib import request from urllib.error import HTTPError, URLError logger = logging.getLogger() logger.setLevel(logging.INFO) def lambda_handler(event, context): budgets = boto3.client('budgets') ce = boto3.client('ce') # 環境変数から取得 ## AWSアカウントID account_id = os.environ['AWS_ACCOUNT_ID'] ## 予算の名前 budget_name = os.environ['BUDGET_NAME'] ## Power Automate Webhook URL webhook_url = os.environ['TEAMS_WEBHOOK_URL'] # Budget情報を取得 response_budgets = budgets.describe_budget( AccountId = account_id, BudgetName = budget_name ) budget_amount = response_budgets['Budget']['BudgetLimit']['Amount'] actual_spend = response_budgets['Budget']['CalculatedSpend']['ActualSpend']['Amount'] forecasted_spend = response_budgets['Budget']['CalculatedSpend']['ForecastedSpend']['Amount'] data = { "budget": budget_amount, "actual_spend": actual_spend, "forecasted_spend": forecasted_spend, "message": "※単位はドルです。" } post_message(data, webhook_url) return { 'statusCode': 200, 'headers': { 'Content-Type': 'application/json' }, 'body': json.dumps( { "message": "Succeeded!" } ) } def post_message(data, webhook_url): headers = {"Content-Type": "application/json"} req = request.Request(url = webhook_url, method = "POST", headers = headers, data = json.dumps(data).encode()) try: with request.urlopen(req) as res: logger.info(f"Webhookの送信成功: {res.status}") return True except (HTTPError, URLError) as e: logger.error(f"Webhookの送信失敗: {str(e)}") return False |
Power Automateのフローを作成する
Lambda関数から送信されたデータをTeamsに投稿するために、Power Automateでフローを作成します。
作成するフローの全体の流れは以下になります。

それぞれのトリガーおよびアクションの設定内容を説明します。
フローのトリガー/アクションを設定する
Teams Webhook要求を受信したとき

- フローをトリガーできるユーザー:
誰でも
を選択します。 - HTTP URL: フローを保存完了後に自動的にURLが生成されます。本URLをLambda関数の環境変数(TEAMS_WEBHOOK_URL)として使用します。
JSONの解析

- Content: 本アクションの前ステップである
Teams Webhook要求を受信したとき
の本文
データを追加します。 - Schema: 以下のJSON形式のスキーマを貼り付けます。
properties
に記述されているbudget
などは、Lambda関数が送信するPOSTリクエストに含まれるデータ群です。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
{ "type": "object", "properties": { "budget": { "type": "string" }, "actual_spend": { "type": "string" }, "forecasted_spend": { "type": "string" }, "message": { "type": "string" } } } |
チャットやチャネルにカードを投稿する

- 投稿者:
フローボット
を選択します。 - 投稿先:
チャネル
を選択します。 - チーム: 投稿先のTeamsを選択します。
- チャネル: 投稿先のチャネルを選択します。
- アダプティブカード: 以下のJSON形式のアダプティブカードを貼り付けます。アダプティブカードを編集することで、Teamsチャネルの投稿フォーマットを設定できます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
{ "type": "AdaptiveCard", "body": [ { "type": "TextBlock", "size": "Large", "weight": "Bolder", "text": "AWS利用料" }, { "type": "FactSet", "facts": [ { "title": "今月の予算:", "value": "@{body('JSON_の解析')?['budget']}" }, { "title": "本日時点の利用料:", "value": "@{body('JSON_の解析')?['actual_spend']}" }, { "title": "月末の予測値:", "value": "@{body('JSON_の解析')?['forecasted_spend']}" } ] }, { "type": "TextBlock", "text": "@{body('JSON_の解析')?['message']}", "wrap": true } ], "$schema": "http://adaptivecards.io/schemas/adaptive-card.json", "version": "1.4" } |
Power AutomateのWebhook URLを確認してLambda関数に設定する
フローを保存すると、Webhook用のHTTP URLが生成されます。
トリガーTeams Webhook要求を受信したとき
のHTTP URL欄の値をコピーしてLambda関数の環境変数TEAMS_WEBHOOK_URL
として設定します。

Lambda関数のテスト機能を使用して動作確認する
関数の[コード]タブに移動してテストを実行し、一連の動作に問題がないことを確認します。以下のようにTeamsチャネルにメッセージが投稿されていれば処理は成功です。

Lambda関数にトリガーを追加する
Lambda関数を自動的に実行し、AWS利用料をTeamsチャットに投稿したい場合は、Lambda関数が実行されるトリガーを追加します。ここでは、Amazon EventBridgeを使用して、定期的にLambda関数が実行されるよう設定します。
関数の概要画面の[トリガーを追加]をクリックします。

以下のようにEventBridgeを選択してルールを設定します。例えば、スケジュール式にcron(0 0 ? * MON-FRI *)
と入力すると、月曜日から金曜日の00:00(UTC時刻)にLambda関数が実行されるようになります。
