[Boto3 Adv-Cal DAY10]CostExplorerで指定期間のコストを取得してみた

boto3 で楽しむ AWS PythonLife 一人AdventCalendarです。

boto3のドキュメントを通して、サービス別にどういった事が出来るのかを理解したり、管理コンソールを通さずにTerminalだけで完結できるように検証していくことが目的になります。

10日目はCostExplorerで指定期間のコストを取得してみました

目次

boto3を通してCostExplorerで出来ること

ドキュメントは下記リンク先です。

ざっくりと以下のことができます。

  • 費用と利用量の取得
  • 過去の費用を元にした利用料の推測
  • 指定期間中の費用と利用料取得

利用手続き

管理コンソール上で利用開始するボタンを操作します。開始していない場合は操作権限がなくエラーとなります。

発生する費用

Cost Explorer ユーザーインターフェイスを使用したコストと使用状況を表示は無料です。Cost Explorer API を使用して、プログラムでデータにアクセスすることもできます。ページ分割された API リクエストごとに 0.01 USD の料金が発生します。

今回の操作

ロジック中に決め打ちで期間を指定して、該当期間のコストを取得します。

% python main.py
Input Profile name [default]>>
{'ResponseMetadata': {'HTTPHeaders': {'content-length': '4459',
                                      'content-type': 'application/x-amz-json-1.1',
                                      'date': 'Thu, 06 Dec 2018 10:04:59 GMT',
                                      'x-amzn-requestid': 'XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX'},
                      'HTTPStatusCode': 200,
                      'RequestId': 'XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX',
                      'RetryAttempts': 0}, 
'ResultsByTime': [{'Estimated': False,
                    'Groups': [],
                    'TimePeriod': {'End': '2018-10-02', 'Start': '2018-10-01'},
                    'Total': {'AmortizedCost': {'Amount': '0', 'Unit': 'USD'}}},
                   {'Estimated': False,
                    'Groups': [],
                    'TimePeriod': {'End': '2018-10-03', 'Start': '2018-10-02'},
                    'Total': {'AmortizedCost': {'Amount': '0', 'Unit': 'USD'}}},

main.py

import boto3
from pprint import pprint

class CostExplorerWizard:
    _start_date = '2018-10-01'
    _end_date = '2018-11-01'
    _client_name = 'ce'
    _session = None
    
    def __init__(self, profile_name):
        self._session = boto3.Session(profile_name=profile_name)

    @property
    def session(self):
        return self._session

    def get_client(self, client_name=None):
        if not client_name:
            client_name = self._client_name
        return self.session.client(client_name)

    @property
    def client_name(self):
        return self._client_name

    def prompt_date(self, message):
        value = None
        while True:
            value = input("\n {} >> ".format(message))
            if value and len(value) != 0:
                break
        return value

    def get_cost_and_usage(self):
        params = {
            'TimePeriod': {
                'Start': self._start_date,
                'End': self._end_date
            },
            'Granularity': 'DAILY',
            'Metrics': ['AmortizedCost']
        }
        return self.get_client().get_cost_and_usage(**params)

    @staticmethod
    def prompt():
        default_profile_name = 'default'
        profile_name = input('Input Profile name [{}]>> '.format(default_profile_name))
        if len(profile_name) == 0:
            profile_name = default_profile_name
        wizard = CostExplorerWizard(profile_name)

        result = wizard.get_cost_and_usage()
        pprint(result)

if __name__ == '__main__':
    CostExplorerWizard.prompt()

get_cost_and_usageのパラメータ

boto3のドキュメント上では必須とされているパラメータはありませんが、実際には以下を指定する必要がありました。

  • TimePeriod
  • Granularity
  • Metrics

まとめ

定期的に管理コンソールからコスト情報をローカルに落とそうとしている場合等に、作業工数削減で有効かもしれません。