Coder Social home page Coder Social logo

aws-cost-explorer's Introduction

Overview

A simple Python 3 script to run via AWS Lambda to report last month's billing broken down by Tag.

Setup

Creating a python3 virtualenv:

$ which python3
/usr/local/bin/python3
$ mkvirtualenv --python=/usr/local/bin/python3 aws-cost-explorer
$ pip install boto3

Getting the Data

Getting the data is pretty straigtforward. Create a Cost Explorer client:

client = boto3.client('ce')

Query for the cost data for the time period defined by start and end:

    response = client.get_cost_and_usage(
        TimePeriod={
            'Start': start,
            'End':  end
        },
        Granularity='MONTHLY',
        Metrics=['BlendedCost'],
        GroupBy=[
            {
                'Type': 'TAG',
                'Key': 'Project'
            },
        ]
    )

Our AWS account has (most) every thing marked with a customer Project Tag. I want the results grouped by that so our finance team can track expenditures appropriately.

The part of the response we care about looks like the below snippet ('Amount' has been redacted but they're float values):

'ResultsByTime': [{'Estimated': True,
                    'Groups': [{'Keys': ['Project$'],
                                'Metrics': {'BlendedCost': {'Amount': '<FLOAT>',
                                                            'Unit': 'USD'}}},
                               {'Keys': ['Project$Allegro'],
                                'Metrics': {'BlendedCost': {'Amount': '<FLOAT>',
                                                            'Unit': 'USD'}}},
                               {'Keys': ['Project$ExtraLife'],
                                'Metrics': {'BlendedCost': {'Amount': '<FLOAT>',
                                                            'Unit': 'USD'}}},
                               {'Keys': ['Project$HG Internal'],
                                'Metrics': {'BlendedCost': {'Amount': '<FLOAT>',
                                                            'Unit': 'USD'}}},
                               {'Keys': ['Project$Mercury'],
                                'Metrics': {'BlendedCost': {'Amount': '<FLOAT>',
                                                            'Unit': 'USD'}}},
                               ...

Note that the Keys value is of the form TAG$VALUE and that anything without a Project tag shows up under the first empty value. We're going to clean this up before reporting it in our .tsv.

After reformatting the data, we email it using AWS SES (see Amazon SES Quick Start for instructions on enabling SES and creating an authorized email endpoint). Because we're including a file attachment, we need to create an email using MIMEMultipart().

AWS

Log into the AWS Console to create the Lambda function, give it the correct access permissions, and configure its run schedule.

Create the Lambda function

  • Lambda > Functions > Create function

  • Name: monthlyBillingEmail

  • Runtime: Python 3.6

  • Role: Create a custom role

  • IAM Role: Create a new IAM Role

  • Role Name: lambda_send_billing_email

Create Function

Creating IAM permissions

Create a Policy that allows access to the Cost Explorer API:

  • IAM > Policies > Create policy
  • Service: Cost Explorer Service
  • Actions: All
  • Name: allowCostExplorerRead
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "VisualEditor0",
            "Effect": "Allow",
            "Action": "ce:*",
            "Resource": "*"
        }
    ]
}

Create another Policy that allows sending email over SES:

  • IAM > Policies > Create new
  • Service: SES
  • Write: SendEmail, SendRawEmail
  • Name: allowSESSendEmail
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "VisualEditor0",
            "Effect": "Allow",
            "Action": [
                "ses:SendEmail",
                "ses:SendRawEmail"
            ],
            "Resource": "*"
        }
    ]
}

Bundle these Policies into a Role:

  • IAM > Roles > Search "lambda_send_billing_email"
  • Attach policy:
  • allowCostExplorerRead
  • allowSESSendEmail

Actually create the Lambda function

Lambda > Functions > monthlyBillingEmail

We don't have any external libraries other than boto, so we can just edit inline

Paste the contents of generate_report.py into the lambda_function tab (except the shebang line although maybe that doesn't matter?)

Create a test, using Hello World as a template (we're not actually using the contents so NBD)

Run the test; it should report success and the billing output!

Add Triggers

In order to schedule the function to run automatically each month, we create a Trigger in CloudWatch. We will schedule it to run at midnight on the third of each month just in cause there is some latency is AWS aggregating the billing data (note that that is pure speculative paranoia on my part).

  • CloudWatch Events
  • Configure triggers
  • Create a new rule
    • Rule name: lambda_monthly_billing
    • Rule description: Running on the 3rd of the month
    • Rule type: Schedule expression
    • Schedule expression: cron(0 0 3 * ? *) <- Syntax on this is a little wonky... need to have ? for Day-of-month or Day-of-week

References

aws-cost-explorer's People

Contributors

agussman avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.