みなさん、こんにちは。サイオステクノロジー武井です。今回は、Azureの使いすぎを防止するOSS「Azure Cost Keeper」をご紹介致します。
クラウドの課金体系について
Azure、AWS、GCPなどのパブリッククラウドは、利用した時間に応じて料金が課金される「従量課金型」のサービスがほとんどです。例えば、AzureでいうところのVirtual Machine、AWSでいうところのEC2インスタンスは、起動した時間に応じて課金されます。Azure Functions、Lambdaなどのサーバーレスアキテクチャは、時間ではなく、リクエストの数に応じて課金されますが、これも従量課金型と言えますし、Azureの各種APIも発行した分に応じて課金されるものが多くあります。
クラウドは「使った分だけ料金を支払う」という、合理的な課金体系によって普及したともいえますが、これには一長一短があります。
意図せぬ課金が…
「使った分だけ料金を支払う」ので、当然使った分はきっちり請求されてしまいます。実はここに意図せぬ課金が発生するケースが隠れています。
例えば、Virtual Machineを作成する際にはインスタンスサイズを選択する必要があります。このインスタンスサイズの課金体系をよく知らない人が、ものすごい高価なサイズを選択してしまうと、月末になってあらびっくり、すごい金額が請求されてしまいます。
まだ、Virtual Machineなどはわかりやすいですが、それ以外にもAzureは数多のサービスがあります。中には、少々課金体系が難しいものもあり、うっかり高額なプランを選んでしまうなんてことも十分ありえます。
また、先程申し上げたようにAzure Functionsはリクエストの数に応じて課金されます。うっかりプログラムがバグって、もしくはまだテスト中のプログラムで、Azure Functionsを無限ループで回してしまった場合はどうなるでしょう?これも月末になってあらビックリパターンです。
そこでCost Management
そんなときのCost Managementです。Azureには課金を管理するサービスであるCost Managementがあります。サブスクリプションやリソースグループ、リソースごとの実際の利用料、予測利用料などを監視し、しきい値を超えたらメールを送信したり任意のアクションを実行可能です。このアクションには、Azure FunctionやLogic App、Azure Automationなどを指定できるので、例えば、ある一定の利用料を超えたら、Virtual Machineを停止させるなんてことも可能です。
ちなみに以下はCost Managementの画面です。とあるリソースグループの実際の利用料(¥1,495.20)、月末時点での予測利用料(¥9,273.58)など、コストに関する様々な情報が記載されています。
Azure Cost Keeperでコスト管理をもっと便利に!!
Cost Managementを使うと、あらかじめ設定したしきい値を超えた場合、メールやTeams、Slackなどでアラートを上げたり、当該リソースを停止するなどして、意図せぬ課金を防いでくれます。
とっても便利なCost Managementなんですが、やっぱりもっともっと便利に使えるといいなと思うときもあります。
そこで、Azure Cost KeeperというOSSを開発しました。Cost ManagementのAPIを用いて、Cost Managementをよりもっと便利にするツールです。ソースコードは以下で公開しております。
https://github.com/SIOS-Technology-Inc/azure-cost-keeper
またDockerレジストリにDockerイメージも公開しているので、すぐ使うことができます。
機能について、これからご説明します。
リソースグループごとの使用料一覧をもっと細かく見れる
企業では、検証目的で複数のエンジニアが一つのサブスクリプションの中に用途別に複数のリソースグループを作る場合があります。大学の研究室や研究機関などでも、用途別に複数のリソースグループを作る場合があるのではないでしょうか?あんな検証をしたい、こんな研究をしたい、つまり「研究」や「検証」ごとにリソースを作る場合、その管理単位はリソースグループが適しているかと思います。
サブスクリプション単位で分けてもいいですが、その場合請求単位も別れてしまいますし、なによりもサブスクリプションはリソースグループほど気軽には作れません。こんな検証したいなと思ってパッと作って不要になったらパッと消す、そんな用途にはリソースグループはぴったりなのです。
Cost Managementでも複数のリソースグループを管理・閲覧できます。それぞれのリソースグループごとにしきい値を設定し、その値を超えたらアラートを上げることができますし、リソースグループごとの使用料も把握できます。
ただし、先のように検証や研究目的の環境では、リソースグループは発生しては消えて、、、を繰り返します。そのたびに、そのリソースグループのしきい値の設定をするのは面倒です。リソースグループごとのレポートも確かに見ることはできますが、肝心の「誰がそのリソースグループを作成したのか」を把握することはできませんし、そのレポートをメールやSlack、Teams等で送るようにするのも一手間必要です。
そんな問題をAzure Cost Keeperは解決します。Azure Cost Keeperは、定期的に以下のレポートをメールやSlackで送信します。
リソースグループ単位の日毎の利用料を上位50位(変更可能)まで表示し、そのリソースグループの管理者(=作成者)も合わせて表示します。サブスクリプションをまたいでリソースグループを表示することも可能です。
月ごとの最大想定使用料も設定可能であり、それを上回るペースで使うと、以下のようにレポート上でアラートが上がります。そして、一日あたりどのくらい利用料を削減すれば、月額最大想定使用料の範囲内に収まるかもわかります。
つまり、このレポートを毎日、もしくは定期的にAzure利用者に送付し、以下のように現状・原因・解決策を認知させることでAzureの使いすぎを防止ることができるわけです。
- 現状:今使いすぎているのかそうでないのか
- 原因:使いすぎているとしたらどこに(どのリソースグループに)問題があるのか
- 解決策:どうしたらその問題を解決できるのか
この現状・原因・解決策は、レポートの以下の部分に相当します。
不要なリソースの停止ができる(リリース予定)
Azureは先程も申し上げたように従量課金体系です。Virtual MachineやAzure Database for MySQLなどは起動している時間に応じて料金が加算されていきますので、不要なときにはこれらを停止すると、相当な費用削減が’期待できます。
リソースの利用者自身で使い終わったら停止するというのが望ましいのですが、やはり、それは人間、、、停止するのを忘れてしまうこともあると思います。
そこで、Azure Cost Keeperに、Virtual Machine及びAzure Database for MySQLを一定時刻になったら停止する機能を追加予定です。
強制的にリソースが停止されれば、うっかり停止し忘れて意図せぬ課金が発生することもなくなります。
ただ、やはりリソースを停止させたくないときもあります。数日かけて行う性能試験などでVirtual Machineを起動しっぱなしにしたい場合などです。そんなときのために、そのリソースに特定のタグが付与されている場合のみ、そのリソースを停止対象から除外する機能を追加予定です。
リソースグループの棚卸しができる(リリース予定)
リソースグループがたくさんできますと、中には検証や調査が終わって用済みとなったリソースグループがたくさんでてきます。そんなリソースグループがたくさんあると、課金に影響してきますよね。特にストレージ周りはVMを停止しても課金され続けます。少額ではありますが、塵も積もれば山となります。
リソースグループを作成された人自身が、用済みとなったリソースグループを削除してくれればいいのですが、なかなかそうはいかないのが現状です。
そこで、Azure Cost Keeperでは、不要になったリソースグループを一括削除するための、以下の便利機能を提供する予定です。
- リソースグループ利用者に一斉にメールやメッセージを送信して、所有リソースグループ削除可否を確認
- 管理者にて削除OKと返事をもらったリソースグループを一括削除
フローは以下となります。
- Azure Cost Keeperは、リソースグループ利用者に、所有リソースグループ削除可否確認のメールorメッセージを送信する。
- 管理者は、利用者の削除可否状況に基づき、リソースグループの削除依頼をAzure Cost Keeperに送る。
- Azure Cost Keeperは、リソースグループの削除を行う。
使い方
ここからは各機能の使い方について説明します。
レポート機能
先程ご説明したリソースグループごとのレポート機能の使い方を説明します。
その前に、まずレポート機能のアーキテクチャを簡単に記載します。
- Azure Cost Keeperは、Docker Registry(Azure Container Registry)上にDockerイメージとして公開されていますので、これをpullしてコンテナ化します。
- コンテナ化したAzure Cost Keeperは、Azure上のリソースグループごとの課金情報をAPIで取得します。この際、リソースグループのアクティビティログからリソースグループの作成者を取得し、そのリソースグループにタグとして付与します。
- 2でアクティビティログから取得したリソースグループの作成者をキーとして、Azure Active Directoryから作成者の表示名(DisplayName)を取得します。
- リソースグループの利用料や作成者をレポートにして、メールやSlack等で利用者に通知します。
Dockerイメージとして公開されていますので、すぐ使うことができるのですが、いくつかの設定を環境変数で定義して上げる必要があります。その環境変数名と内容を以下の表にまとめました。
環境変数名 | 内容 |
CLIENT_ID | Azure Cost KeeperがAPIを実行するために必要なクライアントIDです。 |
TENANT_ID | クライアントIDが所属するテナントのIDです。 |
CLIENT_SECRET | クライアントIDのシークレットです。 |
LIMIT_MONTHLY_COST | 月ごとの最大想定使用料です。この値を超えると、レポートでアラートが上がります。 |
SMTP_FROM | レポートをメールで送信する際の送信元です。 |
SMTP_HOST | レポートをメールで送信する際のSMTPサーバーです。 |
SMTP_PORT | レポートをメールで送信する際のSMTPポートです。 |
SMTP_USER | レポートをメールで送信する際のSMTPユーザー名です。現在、SMTP認証のみの対応となります。 |
SMTP_PASSWORD | レポートをメールで送信する際のSMTPパスワードです。 |
SMTP_TO | レポートの送信先メールアドレスになります。 |
SUBSCRIPTION | 使用料取得対象のリソースグループが含まれるサブスクリプションのサブスクリプションIDを指定します。コロン(:)で区切ることで複数のサブスクリプションを指定可能です。 |
USAGE_BASEDATE_ADDDAYS | 本プログラム実行時から何日前の課金情報を取得するかを指定します。例えば-2を指定すると、2日前の課金情報を取得します。基本的にCost ManagementのAPIは直近の課金情報は安定して取れません(課金情報がお実際の値とは異なってしまうことがあります)。2日くらい前だと大丈夫のようですが、もしそれで安定して取れなければ、それ以上前にしたほうがよいかもしれません。何も指定しない場合の初期期は-2となります。 |
UID_ATTR | Azure Active Directoryからリソースグループ作成者の表示名を取得する際のキーとなる属性を指定します。例えば、mail属性にユーザーを一意に識別するキーが入っている場合は、mailと指定します。何も指定しなければ、UserPrincipalNameとなります。通常はUserPrincipalNameとなりますので、何も指定する必要はありません。 |
上記の環境変数を定義してあげれば、コンテナ化してすぐ動かすことはできるのですが、その前に一つやらなければいけないことがあります。それはクライアントID=サービスプリンシパルに対する権限の付与です。
まず使用料取得対象のリソースグループが含まれるサブスクリプションに対して以下の権限が必要になります。
- タグ共同作成者
- 課金データ閲覧者
つまり、サービスプリンシパル名がcostmanagementだとすると、サブスクリプションには以下のように権限が割あたっている必要があります。
また、サービスプリンシパルに以下のAPIの権限も必要です。
- Microsoft Graph:User.Read.All
つまりMicrosoft Graph APIによってAzure Active Directory上の全てのユーザーの全ての属性を取得できる必要があります。サービスプリンシパルの「アプリの登録」で以下のように定義されている必要があります。
これで準備は整いました。Dockerコマンドで起動する例を以下に示します。環境変数の部分を適宜置き換えて下さい。DockerイメージはDocker Hubではなく、Azureのマネージドなコンテナレジストリ「Azure Container Registry」に格納しております。
$ docker run -it --name azcostkeeper-rgreport \ -e CLIENT_ID=[クライアントID] \ -e TENANT_ID=[テナントID] \ -e CLIENT_SECRET=[クライアントシークレット] \ -e LIMIT_MONTHLY_COST=370000 \ -e SMTP_FROM="Azure課金管理サービス<azure-billing-notify@contoso.com>" \ -e SMTP_HOST=smtp.gmail.com \ -e SMTP_USER=azure-billing-notify@contoso.com \ -e SMTP_PASSWORD=XXXXXXXX \ -e SMTP_TO=billing@contoso.com \ -e SUBSCRIPTION=XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX:YYYYYYYY-YYYY-YYYY-YYYY-YYYYYYYYYYYY \ --rm azcostkeeper.azurecr.io/azcostkeeper-rgreport
まとめ
いかがでしょうか?Azure Cost Keeperを使うと、コスト管理をもっともっと便利にできて、気兼ねなくAzureを使うことができます。もうコストに怯える生活にはサヨナラですね(^_^)/~