(Python) Get AWS billing amount

Introduction

Now that I have an AWS account, I want to manage my billing. I want to avoid unplanned expenses if possible. So I use Python to get the billing information from AWS Cost Explorer.

environment

The execution environment is as follows

$ sw_vers
ProductName:    Mac OS X
ProductVersion: 10.15.1
BuildVersion:   19B88

$ python --version
Python 3.7.4

API specification

--Display the total billed amount. --Display the detailed billing amount for each service. --The period for obtaining the billed amount is as follows. --START: The first day of the month including the API execution date --END: The day before the API execution date --If the API execution date is one day, the billing amount of the previous month is displayed.

Get the API execution date and the first day of the execution month

Create a method to get the execution date and the first day of the execution month as follows using the datetime package.

from datetime import datetime, timedelta, date

#Get the first day of the execution month
def get_begin_of_month() -> str:
    return date.today().replace(day=1).isoformat()


#Get execution date
def get_today() -> str:
    return date.today().isoformat()

Acquire the billing amount acquisition period

Create a method to return the billing amount acquisition target period using the above method. However, if the START and END of the acquisition target period are the same, it cannot be set as an argument in the SDK of Cost Explorer. Therefore, if the START and END of the acquisition target period are the same, the end of the month should be returned from the 1st of the previous month.

#Acquire the billing amount acquisition period
def get_total_cost_date_range() -> (str, str):
    start_date = get_begin_of_month()
    end_date = get_today()

    # get_cost_and_usage()Because the same date cannot be specified for start and end of
    #If "Today is 1st", make it in the range from "Last month 1st to this month 1st (today)"
    if start_date == end_date:
        end_of_month = datetime.strptime(start_date, '%Y-%m-%d') + timedelta(days=-1)
        begin_of_month = end_of_month.replace(day=1)
        return begin_of_month.date().isoformat(), end_date
    return start_date, end_date

Get total billing amount acquisition

Acquire the total billing amount for the acquisition target period using the SDK.

import boto3
client = boto3.client('ce', region_name='us-east-1')

#Get total billing amount acquisition
def get_total_billing(client) -> dict:
    (start_date, end_date) = get_total_cost_date_range()
    response = client.get_cost_and_usage(
        TimePeriod={
            'Start': start_date,
            'End': end_date
        },
        Granularity='MONTHLY',
        Metrics=[
            'AmortizedCost'
        ]
    )
    
    return {
        'start': response['ResultsByTime'][0]['TimePeriod']['Start'],
        'end': response['ResultsByTime'][0]['TimePeriod']['End'],
        'billing': response['ResultsByTime'][0]['Total']['AmortizedCost']['Amount'],
    }

Get the detailed billing amount for each service

Get the detailed billing amount for each service as well as the total billing amount.

import boto3
client = boto3.client('ce', region_name='us-east-1')

#Get detailed billing amount for each service
def get_service_billings(client) -> list:
    (start_date, end_date) = get_total_cost_date_range()

#CostExplorer.Client.get_cost_and_usage
    response = client.get_cost_and_usage(
        TimePeriod={
            'Start': start_date,
            'End': end_date
        },
        Granularity='MONTHLY',
        Metrics=[
            'AmortizedCost'
        ],
        GroupBy=[
            {
                'Type': 'DIMENSION',
                'Key': 'SERVICE'
            }
        ]
    )

    billings = []

    for item in response['ResultsByTime'][0]['Groups']:
        billings.append({
            'service_name': item['Keys'][0],
            'billing': item['Metrics']['AmortizedCost']['Amount']
        })
    return billings

Execute the created API.

Below is the execution result.

{'start': '2020-01-01', 'end': '2020-01-12', 'billing': '0.44'}
[
  {'service_name': 'AWS Cost Explorer', 'billing': '0.4'}, 
  {'service_name': 'AWS Key Management Service', 'billing': '0'}, 
  {'service_name': 'AWS Lambda', 'billing': '0'}, 
  {'service_name': 'Amazon API Gateway', 'billing': '0'}, 
  {'service_name': 'Amazon DynamoDB', 'billing': '0'}, 
  {'service_name': 'Amazon Simple Notification Service', 'billing': '0'}, 
  {'service_name': 'Amazon Simple Storage Service', 'billing': '0'}, 
  {'service_name': 'AmazonCloudWatch', 'billing': '0'}, 
  {'service_name': 'Tax', 'billing': '0.04'}
]

in conclusion

Process this result into a message you want to display on Slack etc. and incorporate it into the bot API created by here. It will be displayed like this. スクリーンショット 2020-01-12 16.46.57.png

Recommended Posts

(Python) Get AWS billing amount
[Python] Get environment variables
[Python] Get Qiita trends
[Python3] Get date diff
Get date with python
AWS CDK with Python
python get current time
Get YouTube Comments in Python
Get country code with python
Python --bitflyer Get asset balance
Get last month in python
[Python] Scraping in AWS Lambda
Get Twitter timeline with python
AWS CDK-Lambda + API Gateway (Python)
Get Youtube data with python
[Python] Get the previous month
Get thread ID with python
Get started with Python! ~ ② Grammar ~
[python] Get quotient and remainder
Get stock price with Python
Get Evernote notes in Python
python> Get substring> print serial [5:10] / print serial [5: -1]
Get home directory with python
Get keyboard events with python
IfcOpenShell python bindings get started
Python --bitflyer Get chat content
Get Alembic information with Python
Python> dictionary> get ()> optional value
Get Japanese synonyms in Python
Get Leap Motion data in Python.
Get started with Python! ~ ① Environment construction ~
Summary if using AWS Lambda (Python)
Link to get started with python
Get data from Quandl in Python
Get reviews with python googlemap api
Text extraction with AWS Textract (Python3.6)
Get the desktop path in Python
Write AWS Lambda function in Python
Get the weather with Python requests
Get web screen capture with python
Get the weather with Python requests 2
[Python] Get economic data with DataReader
Get the script path in Python
Run Python on Schedule on AWS Lambda
How to get the Python version
boto3 (AWS SDK for Python) Note
[Small story] Get timestamp with Python
Get, post communication memo in Python
AWS Layer Creation Script for python
Get Qiita trends with Python scraping
Get the desktop path in Python
Notify HipChat with AWS Lambda (Python)
Get the host name in Python
Python Note: Get the current month
Python version to get unused ports
Get started with Python in Blender
Get weather information with Python & scraping
[AWS SAM] Introduction to Python version
[Cloud102] # 1 Let's get started with Python (Part 2 Jupyter Notebook Construction AWS Edition)
I get a Python No module named'encodings' error with the aws command