クラウドのコスト管理を考える

※この記事は [Microsoft Azure Tech Advent Calendar 2019](https://qiita.com/advent-calendar/2019/microsoft-azure-tech) の 2 日目の記事です。

技術的な記事はほかの方が素晴らしい記事を書かれると思いますので、この記事ではちょっと視点を変えてコスト管理やガバナンスといった観点で書いてみたいと思います。
また、機能的な部分は Azure をベースにはしているものの考え方・概念に関してはほかのクラウドをお使いの場合でも同じかと思いますのでご参考になれば幸いです。

# はじめに
私はプロアクティブサポートという立場で、さまざまなお客様に Azure の導入支援を行っています。
(ロールの紹介はこちらをご参照ください: https://aka.ms/intropfe)

Azure 内のネットワーク構成や仮想マシンのストレージ構成に関する設計に関わることも多いのですが、特に運用フェーズで出てくる支援として、コストに関するものがあります。
機能的な点については、どのようなサービスを使うか、どういう構成にするのか、といった形で考えることが分かりやすいのですが、コスト管理はそもそも検討されなかったり何か問題が発生してから検討されることが多い傾向にあります。

# クラウドのコスト管理でよくある課題
ではクラウドのコストに関する課題としてどのようなものがあるのでしょうか。いくつか例を見てみましょう。

1. どうやって見積りを作ればいいのかわからない(何にコストが発生するのかわからない)
1. 当初の予算に比べて利用料が高い
1. ここ数日～1か月の利用料が急に高くなった
1. 利用部署ごとによってコスト管理をしたい
2. コストをレポートするためにまとめたい

利用前の課題から、利用後の課題までさまざまありますが、カテゴライズすると概ねこんな感じでしょうか。

1. 見積り方法に関するもの
2. 予実差に関するもの(当初の予定から外れている)
3. コストの増減に関するもの(前月、3か月等の期間で見たときに増減している)
4. コスト分類に関するもの

ではこのような課題に対してどういうアプローチで対応していけばよいのか考えてみます。


# クラウドのコスト管理とは

## クラウドとオンプレミスの違い
クラウドとオンプレミスで、コストの観点から特徴的な違いとしては、**買い切り**か、**従量課金**か、の違いがあります。
ご存じの通り、従量課金の特徴としては、使った分だけ課金されるモデルです。
※特にエンタープライズな環境で Azure を利用する場合は、先払い(マネタリーコミット)でお支払いいただくことが多いのですが、それにしても従量課金という点は変わらず、先払いの枠から消費されていく形になります。

つまり、クラウドを使う上では、この従量課金という特徴をうまくコントロールしてあげることが必要になってきます。

## クラウドのコスト管理 = ガバナンス
ではどのようにコントロールをすればよいのでしょうか？
結論から書くと、このコントロールこそがガバナンスということになります。
従来から IT ガバナンスという考え方はありましたが、クラウド利用においてはコストに直結してくることになるので、特に現場レベルで触れる機会が多くなったのではと思います。

**IT ガバナンスとは？**
そもそもIT ガバナンスというキーワードはかなり範囲が広く、これをやればガバナンスがある状態だ、というものが決まっているわけではありません。
Wikipedia によると以下の様に書かれています。
>経済産業省では「企業が競争優位性の構築を目的としてIT戦略の策定及び実行をコントロールし、あるべき方向へと導く組織能力」と定義しており、日本監査役協会では「リスクマネジメントとパフォーマンスマネジメントを実施するにあたっての健全性確保のためのコンプライアンスマネジメントの確立」と定義している。あるいは、ITガバナンス協会（ITGI）による「取締役会及び経営陣の責任」といった定義も存在する。<br/>https://ja.wikipedia.org/wiki/IT%E3%82%AC%E3%83%90%E3%83%8A%E3%83%B3%E3%82%B9

私の解釈にはなりますが、**ビジネスにおける IT システムが正常に稼働するためにコントロールされている状態・手法**のように捉えています。
先にも書いていますが、クラウドの場合はリソース(システム)の利用状況がコストにそのまま反映されるため、管理されていない状況がコストとして現れてくることになります。


## コスト管理を実装する
ではコスト管理をクラウド運用に取り入れよう、となったとしても、何を設計し、どうやって取り入れていけばいいのか、具体的な方法が体系的に理解されているケースは多くありません。ここではカテゴリを分けて具体的に何をすればよいのかを見てみましょう。

### 1. Planning
IT システムの導入においてはあたり前のことかとは思いますが、まず初めに計画、予算を作ります。
クラウド特有の考え方としては、さまざまなサービスがあり、それぞれのサービスで課金のされ方が異なるということを理解しておく必要があります。

例えば、仮想マシン(IaaS)をベースにした構成の場合、特に Azure の場合何に課金がされるかというと、
1. 仮想マシン
2. ネットワーク帯域
3. パブリック IP アドレス
4. ストレージ
が主になります。

さらに、仮想マシンは CPU 数やメモリ容量等のスペックに応じて、ストレージは容量や種類(HDD or SSD)に応じて、という形でリソースの課金のされ方は細かく変わってきます。
また、Cognitive Service やデータベース等の PaaS サービスを利用する場合においては、まったく異なる課金モデルになるため、予算を立てる上ではそれぞれのサービスの機能や課金のされ方をちゃんと理解しておく必要があります。

私が過去経験したお客様では、事前に PoC を行い、どういう機能をもっているのか、どのくらいのスペックなのか、何に課金されるのか、ということを確認した上で、あとはサービスと単価、利用量を Excel でまとめられていることが多いです。
**<font color=red>※特に、クラウドにおいては、机上計算のみではなく PoC を行うことは必須と言えるでしょう。</font>**

また、この計画段階で、どのサービスをどのくらいの期間利用するか(成長率も考えてどのくらいでシステム構成の見直しが必要なのか)、といった点もクリアにしておきます。後ほど紹介しますが、Reserved Instance といった長期利用を前提にすると割引される仕組みもあり、その際の情報として使います。

### 2. Visibility
実際どのくらい使われているのか、を確認する方法を考えます。Azure の場合ですと、Cost Management(コストの管理と請求) 機能を使います。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/132347/78f0b27d-6db0-f21d-2c52-2dec95986e0c.png)

どのようにコストを管理するかにもよりますが、月単位で利用料金を確認できることは必須でしょう。しかし、分析を行う上ではそれだけではほとんどの場合十分でないことが多いです。以下の様な観点で確認できる方法があるといいと思います。

1. **サービスごと(VM や DB 等のサービスのカテゴリ単位)の利用料**<br/>
   例えば、PaaS ベースにすると安くなるかも等サービスの変更でコスト最適化できないか、の分析を可能とする
2. **リソースごと(実際ユーザーが展開している 1 つのリソース単位)の利用料**
   <br/>例えば、急激に利用料が上がったリソースがある、といった場合に特定できるようにする
4. **1 日ごと、1 週間ごとの利用料**
   <br/>例えば、ある日から急激に利用料が増加した等のように期間的に細かい粒度で確認できるようにする
1. **タグごとの利用料**
   <br/>例えば、○○システムで使っているリソース、××部に関するリソース、のように機能単位でなく管理単位でコストを確認できるようにする

特に、最後のタグのように、機能単位ではなく、ユーザーが自由に付けられる情報を使った利用料の確認ができると管理できる幅が広がります。
Azure では、タグという Key-Value 形式の情報をリソースやリソース グループに付けることができ、さらにコスト管理のフィルターやグループをタグ単位で行うことができます。

**1 日ごとのタグ単位の利用料の確認例**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/132347/7f5ce5f1-c5fd-6f15-57e7-10733cb848e7.png)

また、Azure のコスト管理では、エクスポート機能でストレージ アカウントに定期的に CSV で出力することができますので、Power BI や Excel を使って独自のレポートを作成することができます。

### 3. Accountability
可視化できても、責任を持って対応が出来なければ管理しているとは言えません。

VM 全体の利用料が多い、特定の VM で異常に利用料金が上がっている、特定のリソース グループの利用料を最適化する、といった場合に、誰が(どの組織が、どの部署が)責任をもって対応するのかということを予め決めておく必要があります。

<font color=red>**ここで重要なのは、その責任をもっている担当者が、業務としての利用方法や、そのサービスについてきちんと理解をしておくということです。**</font>
どのリソースでこのくらいのコストが発生している、ということが分かったとしても、それが異常なのか妥当なのか、を判断できないと中途半端な確認になってしまいます。

私の経験でも稀によくあるのですが、特定のリソースにコストがかかっている、ということまで判明しているのに、何が理由なのかがわからず1か月や半年そのまま放置され、非常にもったいない状態になっていることがあります。

### 4. Optimization
何にどのくらいのコストが発生しているか、ということが分かったら、最適化を行います。
最適化は主に 2 つの軸で考えます。

#### 1. コスト(リソース)を削減する
今使っているリソースの停止、変更、削除のように、リソースを削減してコストを減らします。

いくつか例を挙げます。

- 起動したまま使っていないリソース(仮想マシン、VPN ゲートウェイ、データベース等)
- 上位の SKU、シリーズ(Premium SSD等)
- 不要な VM イメージ、スナップショット
- ストレージ アカウントに出力した VM の診断ログ
- 保護を停止した VM の Site Recovery / Backup のデータ
- 不正利用 / DDoS 攻撃

不正利用や DDoS 攻撃は毛色が違いますが、自分だけでなく周りにも迷惑をかけることにもなるので、早急に対処する必要があります。

これらを人手でやろうとすると漏れが発生するので、**Azure Policy** や**管理グループ**等のガバナンス機能を使って機械的にチェックできるようにします。


#### 2. 支払方法・ライセンスを変更する
もう１つは、支払い方法やライセンスオプションでコストそのものを削減します。
Azure の場合、Reserved Instance やハイブリット特典を使うと仮想マシンやデータベースの利用料を安く出来ることがあります
※Reserved Instance とは仮想マシンやデータベース等を 1 年もしくは 3 年間利用することを前提に、通常料金から割り引く購入方法です。

##### Tips: Azure Advisor と Reserved Instance
Azure Advisor を使うと、Reserved Instance(RI) を購入することで、どの仮想マシン(DB等)が何円年間で削減できるか、ということまで確認できます。
画面をお見せすることが出来ないのが残念ですが、リソース単位でどの仮想マシン、ということまで出してくれるので非常に有効です。
Azure Advisor の画面で確認できた台数ごとに RI を購入することもできますが、おすすめの買い方としては、RI を参考しつつ最終的に何年間で何台必要か、ということを整理してまとめて買う方法です。Azure Advisor から出てきたものを基準に細かく購入すると、どのくらいの数をいつ購入したのかが管理しきれなくなるためです。

### 5. Iteration
あとは、1～4を繰り返します。

日々の利用料のチェックは月例で、年間のコミットメント額に対するチェックは四半期や半期でチェックをされることが多いようです。

## 一旦まとめ
ここまでの内容をフェーズごとにまとめてみました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/132347/cacdbef2-3101-2aaf-9cbd-856fb4f27d24.png)

機能的な実装と同様に、コスト管理においても設計から運用まで一連の流れを追って考えると何をやればいいのかが見えてくるかと思います。

# Azure におけるガバナンスのサービスや機能
最後に、これまで書いてきた内容を Azure で実装するためのサービスや機能を紹介します。

|機能名|概要|ドキュメント|
|:----|:----|:----|
|管理グループ|サブスクリプションを階層化できる機能です。<br/>1 つのプロジェクトで運用サブスクリプション、開発サブスクリプションのように複数のサブスクリプションが存在するときにそれらをグループ化し、コスト分析やアクセス権の制御ができます。|https://docs.microsoft.com/ja-jp/azure/governance/management-groups/overview|
|タグ|リソースやリソース グループに Key-Value 形式で情報を付加できる機能です。<br/>コスト管理におけるフィルターや SLA 単位のグルーピング等で活用できます。(クラシックリソースには付与できません)|https://docs.microsoft.com/ja-jp/azure/azure-resource-manager/resource-group-using-tags|
|Cost Management|Azure のコスト分析を行うための機能です。<br/>可視化以外にも予算の設定やコストのエクスポート機能があります。AWS の課コスト管理にも利用できます。|https://docs.microsoft.com/ja-jp/azure/cost-management/overview-cost-mgt|
|ロック|リソースが不用意に削除・変更されないようにするための機能です。|https://docs.microsoft.com/ja-jp/azure/azure-resource-manager/resource-group-lock-resources|
|Blueprints|Azure のリソースやポリシーをサブスクリプションに展開し、一貫した展開・管理を行うための機能です。|https://docs.microsoft.com/ja-jp/azure/governance/blueprints/overview|
|Resource Graph|大量のリソースを効率よく検索するための機能です。検索には Kusto クエリ言語を使います。<br/>大規模な環境ではリソースが数千になることがあり、ポータルやコマンドでは目的のリソースの情報を確認することが困難になることがあります。そのような場合にこの機能を使います。|https://docs.microsoft.com/ja-jp/azure/governance/resource-graph/overview|
|Advisor|展開されたリソースの情報をチェックし、推奨事項を提示します。パフォーマンスやコストに関するチェックを行うことができ、Reserved Instance 購入時の参考情報として利用できます。|https://docs.microsoft.com/ja-jp/azure/advisor/advisor-overview|
|Policy|リソースの展開時やスケジュールされたタイミングでチェックを行い、定義されたポリシーと乖離がある場合は展開の拒否や監査、適用等のアクションが行われます。<br/>特定のリージョンにのみ仮想マシンの展開を行いたい、NSG の適用を強制したい等のアクションを定義することもできます。|https://docs.microsoft.com/ja-jp/azure/governance/policy/overview|

# まとめ
クラウドのコスト管理は、オンプレミスのコスト管理と概念や手法はことなりますが、クラウドの特徴を理解し、そのクラウドに用意されたサービスや機能を活用することで、漏れなく効率よく行うことが出来ます。
皆さんの環境においても一度コスト管理を見直して頂き、無駄の削減、さらなるクラウド活用を行っていただけるようになれば幸いです。

最後までお読みいただきありがとうございました。