みなさん、こんにちは。サイオステクノロジー武井です。今回は、AzureのノーコードソリューションであるLogic Appsを使って、使ってないAzureリソースを課金節約するお話をします。
Azureはいつも課金との戦い
Azure、AWS、GCPなどのパブリッククラウドは、利用した時間に応じて料金が課金される「従量課金型」のサービスがほとんどです。例えば、AzureでいうところのVirtual Machine、AWSでいうところのEC2インスタンスは、起動した時間に応じて課金されます。Azure Functions、Lambdaなどのサーバーレスアキテクチャは、時間ではなく、リクエストの数に応じて課金されますが、これも従量課金型と言えますし、Azureの各種APIも発行した分に応じて課金されるものが多くあります。
クラウドは「使った分だけ料金を支払う」という、合理的な課金体系によって普及したともいえますが、実は使いすぎによる意図せぬ高額請求も問題になります。よくある例が以下です。
- Virtual Machineなどのリソースを作成する際に、課金体系を十分理解せずに高価なプランを指定してしまう。
- Azure FunctionsなどのFaaSやAPIなどを発行しすぎてしまう。
- 不要なリソースをいつまでも稼働させたままにしてしまう。
どれもクラウドびっくり高額請求あるあるかと思います。
今回は3にフォーカスを当てて、その解決策をご提示したいと思います。
不要なリソースを止めよう
Virtual Machineは稼働しっぱなしにしておくとその分課金されていきますので、使わないときは止めておく(Azureポータルから割り当て解除する)のが一番です。
ただ、なかなかこれ、忘れずに止めるの難しいです。世の課金管理者が頭を悩ませるところですね。本人の意識に期待するのはなかなかに厳しいかなと思います。なので、強制的に止めてしまうのが一番かと思います。
でも、停止対象のリソースがたくさんある場合、手動で全て止めるのは骨が折れる作業と思います。
そこで、Logic Appsを使って今回、以下のリソースを自動停止する仕組みを作りました。
- Virtual Machine
- Azure Database for MySQL
不要なリソースを止めるLogic Apps
Logic Appsとは、Azureのサービスの一つで、ノーコードを実現するためのソリューションです。コネクタを言われる様々な部品を使って、プログラムを書かなくても、いろんなことを実現できます。
Logic Appsについては以下のブログがイメージがとてもつかみやすいです。
そんなLogic Appsで、不要なリソースを停止する処理を作りました。詳細な機能は以下のとおりです。
- 起動しているVirtual Machineの割り当て解除
- 起動しているAzure Database for MySQLの停止
- 特定のタグ(名前:deallocate、値:false)がついているリソースは停止対象外
3については、負荷テストなどで数日継続して動作させたいという場合に有効です。
使ってみよう
では早速使い方の説明をしたいと思います。
今回のLogic Appsをロジックアプリデザイナーでみるとこんな感じです。
なかなかに入り組んでいるかと思います(汗)
本来であれば、このLogic Appsの構築方法をロジックアプリデザイナーベースでステップ・バイ・ステップでご説明できたらいいんですが、今回はサクッと利用することに主眼を置きたいと思います。なのでARM Templateによって、このLogic Appsを構築する方法をご説明いたします。
カスタムロールの作成
まずはサービスプリンシパルを作成します。サービスプリンシパルとはアプリケーション専用のIDであり、今回はLogic AppsがそのIDを使って、Azureのリソースを停止するためのAPIに認証をします。
サービスプリンシパルの詳細については以下のブログをご参照頂ければと思います。
しかし、その前にカスタムロールを作成する必要があります。今回サービスプリンシパルはMySQLを停止する権限が必要なのですが、ビルトインロールにはこれがありません。
以下のコマンドで「Stop MySQL」という名称のカスタムロールを作成します。Cloud Shellを使うと便利です。
$ SUBSCRIPTION_ID=$(az account show --query id --output tsv) $ az role definition create --role-definition "{ \"Name\": \"Stop MySQL\", \"Actions\": [ \"Microsoft.DBforMySQL/servers/stop/action\" ], \"DataActions\": [], \"NotDataActions\": [], \"AssignableScopes\": [\"/subscriptions/${SUBSCRIPTION_ID}\"] }"
サービスプリンシパルの作成
ではサービスプリンシパルを作成します。今回はazコマンドでサクッと作ります。必要なロールは以下の3つになります。
- 閲覧者
- 仮想マシンの共同作成者
- Stop MySQL
以下のコマンドでサービスプリンシパルが作成され、さらに閲覧者のロールが割り当てられます。appId、password、tenantは後で使いますのでメモって下さい。
$ SUBSCRIPTION_ID=$(az account show --query id --output tsv) $ az ad sp create-for-rbac --role Reader --scope /subscriptions/$SUBSCRIPTION_ID --name azresource-stop { "appId": "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX", "displayName": "azresource-stop", "password": "YYYYYYYYYYYYYYYYYYYYYY", "tenant": "ZZZZZZZZ-ZZZZ-ZZZZ-ZZZZZZZZZZZZZZ" }
残りのロールも割り当てます。
$ SP_OBJECT_ID=$(az ad sp list --display-name "azresource-stop" --query "[].{id:id}" --output tsv) $ az role assignment create --assignee $SP_OBJECT_ID --role "Stop MySQL" --scope /subscriptions/$SUBSCRIPTION_ID $ az role assignment create --assignee $SP_OBJECT_ID --role "Virtual Machine Contributor" --scope /subscriptions/$SUBSCRIPTION_ID
Logic Appsの作成
ARM Templateを用いて、Logic Appsを作成します。テンプレートを以下のGitリポジトリからCloneします。
https://github.com/noriyukitakei/logicapps4stopazresource
parameters.jsonの値を修正します。それぞれの値の内容は以下のとおりです。
tenantid | 先程作成したサービスプリンシパルが所属するAzure Active DirectoryテナントのIDです。サービスプリンシパルを作成したときのレスポンスのJSON内にあるtenantフィールドになります。 |
clientid |
先程作成したサービスプリンシパルのクライアントIDです。サービスプリンシパルを作成したときのレスポンスのJSON内にあるappIdフィールドになります。 |
clientsecret |
先程作成したサービスプリンシパルのクライアントシークレットです。サービスプリンシパルを作成したときのレスポンスのJSON内にあるpasswordフィールドになります。 |
subscriptions | 停止したいリソースが所属するサブスクリプションのIDです。配列で複数指定できます。 |
リソースグループを作成します。以下のコマンドを実行します。location(リージョン)はお好きな場所でOKです。
$ az group create \ --name myResourceGroup \ --location "Central US"
Logic AppsをARM Templateからデプロイします。
$ az deployment group create \ --name azresource-stop \ --resource-group myResourceGroup \ --template-file template.json \ --parameters @parameters.json
以下のような形で出来上がると思います。デフォルトでは、毎日22:00にリソースを停止するようにしておりますので、適宜変更してくださいませ。
まとめ
このLogic Appsを使って、Azureの課金を節約して、請求書に怯える日々からバイバイ(^_^)/~しましょう!!