0. はじめに
AzureのコストはAzure portalのコスト管理で詳しく分析できますが、毎日ログインして確認するのはなかなか大変です。
そこで、Azureでどのサービスをいくら使っているか、今月と今年度のコストをTeamsに毎日通知するようにしてみました。
1. 手順の流れ
Automation アカウント
のRunbook
でコストを取得し、ロジック アプリ
のワークフロー
でTeams
に投稿します。(図中の番号は以下の章番号に対応しています。)
2. Automationアカウントの作成
2.1. Automationアカウントを作成する
Azure portalにサインインし、ナビゲーションバーでAutomation アカウント
に移動します。
作成
を選択し、サブスクリプション
、リソースグループ
、Automation アカウント名
、リージョン
を入力してアカウントを作成
します。
2.2. Automationアカウントにコストを閲覧する権限を付与する
コストを参照できるよう、AutomationアカウントのシステムマネジメントIDにコスト管理の閲覧者
ロールを割り当てます。
作成したAutomationアカウント
を選択し、アカウント設定
>ID
>システム割り当て済み
>Azure ロールの割り当て
をクリックします。
ロールの割り当ての追加
を選択し、スコープ
をサブスクリプション
にし、サブスクリプション
を入力し、役割
でコスト管理の閲覧者
を選んで保存
します。
3. Runbookの作成
3.1. AutomationアカウントにRunbookを作成する
Azureコストを取得し、月次コストおよび年次コストとそのサービス内訳を抽出して、ロジックアプリへHTTPリクエストを送信するRunbookを作成します。
作成したAutomationアカウント
を選択し、プロセス オートメーション
>Runbook
>Runbook の作成
をクリックし、Runbookの名前
、Runbook の種類
、ランタイム バージョン
を入力して作成
します。今回は以下を選択しました。
項目 | 設定値 |
---|---|
名前 | (任意) |
Runbook の種類 | PowerShell |
ランタイム バージョン | 7.2 |
PowerShell Runbook の編集
で以下のコードを入力し保存
し公開
します。
Runbookを作成(修正)したら、必ず公開
して状態
が発行済み
になっていることを確認してください。保存だけしても公開しないと有効になりません。
リソースグループの利用実績が無い場合コストがnullとなり正しく動かない場合があります。必要ならエラー処理などを追加してください。
$SubscriptionID = Get-AutomationVariable -Name "SubscriptionID"
$RGName = Get-AutomationVariable -Name "ResourceGroupName"
$LogicAppsUri = Get-AutomationVariable -Name "LogicAppsUri"
if ((Get-Date).Month -ge 4) {
$FiscalYear = (Get-Date).Year
} else {
$FiscalYear = (Get-Date).Year - 1
}
$FYStartDay = (Get-Date -Year $FiscalYear -Month 4 -Day 1)
$Today = (Get-Date).Date
Connect-AzAccount -Identity
Set-AzContext -SubscriptionId $SubscriptionID
$MonthlyUsageDetail = Get-AzConsumptionUsageDetail -ResourceGroup $RGName
$MonthlyCost = [Math]::Round($($MonthlyUsageDetail.PretaxCost | Measure -Sum).Sum, [MidpointRounding]::AwayFromZero).ToString("#,#")
$MonthlyServicesCost = $MonthlyUsageDetail | Group-Object -Property ConsumedService | Sort-Object -Property {@($_.Group.PretaxCost | Measure -Sum).Sum} -Descending | ForEach-Object {
[PSCustomObject]@{
Service = $_.Name -replace '^Microsoft\.', ''
Cost = [Math]::Round(($_.Group.PretaxCost | Measure -Sum).Sum, [MidpointRounding]::AwayFromZero).ToString("#,#")
}
}
$AnnualUsageDetail = Get-AzConsumptionUsageDetail -ResourceGroup $RGName -StartDate $FYStartDay -EndDate $Today
$AnnualCost = [Math]::Round($($AnnualUsageDetail.PretaxCost | Measure -Sum).Sum, [MidpointRounding]::AwayFromZero).ToString("#,#")
$AnnualServicesCost = $AnnualUsageDetail | Group-Object -Property ConsumedService | Sort-Object -Property {@($_.Group.PretaxCost | Measure -Sum).Sum} -Descending | ForEach-Object {
[PSCustomObject]@{
Service = $_.Name -replace '^Microsoft\.', ''
Cost = [Math]::Round(($_.Group.PretaxCost | Measure -Sum).Sum, [MidpointRounding]::AwayFromZero).ToString("#,#")
}
}
$Body = @{
resourcegroup = $RGName
monthlycost = $MonthlyCost
monthlyservicescost = $MonthlyServicesCost
annualcost = $AnnualCost
annualservicescost = $AnnualServicesCost
}
Invoke-RestMethod -Uri $LogicAppsUri -Method Post -Body ($Body | ConvertTo-Json -Depth 3) -ContentType "application/json"
3.2. Runbookにスケジュールを設定する
作成したAutomationアカウント
を選択し、共有リソース
>スケジュール
>スケジュールの追加
をクリックし、名前
、開始時
、繰り返し
、間隔
、有効期限
を入力して作成
します。
今回は月曜日から金曜日の午前9時に実行するスケジュールを作成しました。
作成したAutomationアカウント
を選択し、プロセス オートメーション
>Runbook
>作成したRunbook名
を選択し、スケジュールをリンク
をクリックします。
スケジュールを Runbook にリンクします
>作成したスケジュール
を選択し、OK
をクリックします。
3.3. Runbookの変数を設定する
Runbookから呼び出す変数を設定します。
作成したAutomationアカウント
を選択し、共有リソース
>変数
>変数の追加
をクリックし、以下の変数を作成
します。
名前 | タイプ | 値 |
---|---|---|
LogicAppsUri | 文字列 | コスト情報をRunbookからロジックアプリへ送信するためのロジックアプリのアドレス ( 5.9. ロジックアプリのアドレスをRunbook変数に設定 参照) |
ResourceGroupName | 文字列 | コストを取得するリソースグループ名 |
SubscriptionID | 文字列 | サブスクリプションID |
4. ロジックアプリの作成
Azure portalのナビゲーションバーでロジック アプリ
に移動します。
追加
を選択し、ホスティング オプションの選択
でマルチテナント
を選択して選択
をクリックします。
ロジック アプリの作成(マルチテナント)
でサブスクリプション
、リソース グループ
、ロジック アプリ名
、リージョン
を入力して作成
します。
5. ワークフローの作成
Runbookからコスト情報を受信し、月次コストおよび年次コストを取得して、Teamsチャネルに投稿するロジックアプリワークフローを作成していきます。
作成したロジックアプリ名
を選択し、開発ツール
>ロジック アプリ デザイナー
を選択します。
5.1. HTTPリクエストの受信
Runbookからコスト情報を含むHTTPリクエストを受信します。
ロジック アプリ デザイナー
でトリガーの追加
を選択し、Request
>When a HTTP request is received
をクリックします。
トリガー名を変更します。
トリガー名 |
---|
HTTPリクエストの受信 |
パラメーター
に以下の項目を入力し、>>
でトリガーを折りたたみます。
パラメーター | 入力内容 |
---|---|
Method | POST |
Request Body JSON Schema | 以下参照 |
{
"properties": {
"resourcegroup": "string",
"monthlycost": "string",
"monthlyservicescost": {
"type": "array",
"items": {
"properties": {
"Service": "string",
"Cost": "string"
},
"type": "object"
}
},
"annualcost": "string",
"annualservicescost": {
"type": "array",
"items": {
"properties": {
"Service": "string",
"Cost": "string"
},
"type": "object"
}
}
},
"type": "object"
}
5.2. 月次コストの初期化
月次コストを出力するに当たって、変数を初期化します。
HTTPリクエストの受信
トリガーの下の+
>アクションの追加
を選択し、Variables
>Initialize variable
をクリックします。
アクション名を変更します。
アクション名 |
---|
月次コスト変数の初期化 |
パラメーター
に以下の項目を入力し、>>
でアクションを折りたたみます。
パラメーター | 入力内容 |
---|---|
Name | monthlyServicesCostFormatted |
Type | String |
Value | (空白) |
5.3. 月次コストの出力
サービス毎の月次コストを取得するため、繰り返し制御を行います。
月次コスト変数の初期化
アクションの下の+
>アクションの追加
を選択し、Control
>For each
をクリックします。
アクション名を変更します。
アクション名 |
---|
月次コストの出力 |
パラメーター
に以下の項目を入力します。
パラメーター | 入力内容 |
---|---|
Select An Output From Previous Steps | monthlyservicescost |
設定
に以下の項目を入力し、>>
でアクションを折りたたみます。
設定 | 設定内容 |
---|---|
Concurrency control | オン |
Degree of parallelism | 1 |
5.4. 月次コスト変数にサービスコストを追加
繰り返し処理の中で、サービス毎の月次コストを取得します。
月次コストの出力
アクションの中の+
>アクションの追加
を選択し、Variables
>AppendToStringVariable
をクリックします。
アクション名を変更します。
アクション名 |
---|
月次コスト変数にサービスコストを追加 |
パラメーター
に以下の項目を入力します。
パラメーター | 入力内容 |
---|---|
Name | monthlyServicesCostFormatted |
Value | 以下参照 |
concat('- ', items('月次コストの出力')?['Service'], ':', if(empty(items('月次コストの出力')?['Cost']), '0', items('月次コストの出力')?['Cost']), '円<br>')
5.5. 年次コストの初期化
年次コストを出力するに当たって、変数を初期化します。
HTTPリクエストの受信
トリガーの下の+
>並列分岐の追加
を選択し、Variables
>Initialize variable
をクリックします。
アクション名を変更します。
アクション名 |
---|
年次コスト変数の初期化 |
パラメーター
に以下の項目を入力し、>>
でアクションを折りたたみます。
パラメーター | 入力内容 |
---|---|
Name | annualServicesCostFormatted |
Type | String |
Value | (空白) |
5.6. 年次コストの出力
サービス毎の年次コストを取得するため、繰り返し制御を行います。
年次コスト変数の初期化
アクションの下の+
>アクションの追加
を選択し、Control
>For each
をクリックします。
アクション名を変更します。
アクション名 |
---|
年次コストの出力 |
パラメーター
に以下の項目を入力します。
パラメーター | 入力内容 |
---|---|
Select An Output From Previous Steps | annualservicescost |
設定
に以下の項目を入力し、>>
でアクションを折りたたみます。
設定 | 設定内容 |
---|---|
Concurrency control | オン |
Degree of parallelism | 1 |
5.7. 年次コスト変数にサービスコストを追加
繰り返し処理の中で、サービス毎の年次コストを取得します。
年次コストの出力
アクションの中の+
>アクションの追加
を選択し、Variables
>AppendToStringVariable
をクリックします。
アクション名を変更します。
アクション名 |
---|
年次コスト変数にサービスコストを追加 |
パラメーター
に以下の項目を入力します。
パラメーター | 入力内容 |
---|---|
Name | annualServicesCostFormatted |
Value | 以下参照 |
concat('- ', items('年次コストの出力')?['Service'], ':', if(empty(items('年次コストの出力')?['Cost']), '0', items('年次コストの出力')?['Cost']), '円<br>')
5.8. チャネルにコストを投稿
月次コストおよび年次コストをTeamsチャネルに投稿します。
月次コストの出力
アクションの下の+
>アクションの追加
を選択し、Microsoft Teams
>チャットまたはチャネルでメッセージを投稿する
をクリックします。
サインイン
を選択し、Teams投稿に使用するアカウント
を選択して認証します。
アクション名を変更します。
アクション名 |
---|
チャネルにコストを投稿 |
設定
に以下の項目を入力します。
設定 | 設定内容 |
---|---|
Run after | 月次コストの出力 年次コストの出力 |
パラメーター
に以下の項目を入力し、>>
でアクションを折りたたみます。
パラメーター | 入力内容 |
---|---|
投稿者 | フロー ボット |
投稿先 | Channel |
Team | 任意のTeamsチーム |
Channel | 任意のTeamsチャネル |
Message | 以下参照 |
<p class="editor-paragraph"><u><b><strong class="editor-text-bold editor-text-underline">今月の利用料金</strong></b></u><br>■合計<br>@{triggerBody()?['resourcegroup']}:@{triggerBody()?['monthlycost']}円<br>■内訳<br>@{variables('monthlyServicesCostFormatted')}<br><u><b><strong class="editor-text-bold editor-text-underline">今年度の利用料金</strong></b></u><br>■合計<br>@{triggerBody()?['resourcegroup']}:@{triggerBody()?['annualcost']}円<br>■内訳<br>@{variables('annualServicesCostFormatted')}</p><br>
最後に、保存
をクリックしてロジックアプリを保存します。
5.9. ロジックアプリのアドレスをRunbook変数に設定
ロジックアプリを保存するとRunbookからHTTPリクエストを受信するためのアドレスが割り当てられるので、Runbookの変数に値を設定します。
HTTPリクエストの受信
トリガーを選択し、パラメーター
>HTTP URL
をコピーします。
ナビゲーションバーでAutomation アカウント
に移動します。
作成したAutomationアカウント
>共有リソース
>変数
>LogicAppsUri
を選択し、値
にコピーしたアドレスをペーストして保存
します。
6. Teamsで通知確認
想定通りにAzureコストとサービス内訳をTeams通知できることを確認するため、Runbookを手動実行します。
Azure portalのナビゲーションバーでAutomation アカウント
に移動します。
作成したAutomationアカウント
>プロセス オートメーション
>Runbook
>作成したRunbook
を選択し、開始
>はい
をクリックします。
Teamsチャネルにコストが通知されていることを確認します。
サービスはコストの高いものから降順に表示されます。
7. まとめ
Azureコストとサービス毎の内訳をTeams通知する方法をご紹介しました。
注意点として、法人でCSP(Cloud Solution Provider)やEA(Enterprise Agreement)のライセンス形態を採用している場合、販売代理店ごとの割引や保守費用が発生するため、Azure portalで表示されるコストと実際の請求料金が一致しないことがあります。
ご利用の環境に合わせて算出式を変更するなどカスタマイズして取り入れていただければ幸いです。
※ 本ブログに記載した内容は個人の見解であり、所属する会社、組織とは全く関係ありません。
※ 2024年10月 現在