Saturday, January 25, 2014

Decoding Your AWS Bill (Part 1)

As you begin to adopt AWS you will likely be asked to report on both usage and cost. One way to do this is using the Monthly Billing report. In this post I will show you how to download your bill and analyze it using PowerShell.
AWS offers a feature called Programmatic Billing Access. When programmatic billing access is enabled, AWS periodically saves a copy of your bill to an S3 bucket. To enable programmatic billing access click here. Be sure to enable the Monthly Report.
Once programmatic billing access is enabled you can download your bill using PowerShell. The function below will download the monthly report and load it in to memory.

 
Function Get-MonthlyReport {
    Param(
        [string][parameter(mandatory=$false)]$AccountId,
        [string][parameter(mandatory=$false)]$BucketName,
        [string][parameter(mandatory=$false)]$Month,
        [string][parameter(mandatory=$false)]$Year
    )
 
    If($BucketName -eq $Null){
        #If no BucketName was specified, assume it is the same as the account alias
        $BucketName = Get-IAMAccountAlias
    }
 
    If($AccountID -eq $Null){
        #If no AccountId was specified, use the account of the current user
        $AccountID = (Get-IAMUser).ARN.Replace('arn:aws:iam::','').Substring(0,12)
    }
   
    #If no month and year were specified, use last month
    If([System.String]::IsNullOrEmpty($Month)) {$Month = If((Get-Date).Month -eq 1){12}Else{(Get-Date).Month}}
    If([System.String]::IsNullOrEmpty($Year)) {$Year = If($Month -eq 12){(Get-Date).Year - 1}Else{(Get-Date).Year}}
    $Month = "{0:D2}" -f [int]$Month #Pad single digit with 0
 
    #Download the report from S3 and save to the temp directory
    $Key = "$AccountId-aws-billing-csv-$Year-$Month.csv"
    $FileName = "$env:TEMP\$AccountId-aws-billing-csv-$Year-$Month.csv"
    If(Test-Path $FileName) {Remove-Item $FileName}
    $Null = Read-S3Object -BucketName $BucketName -Key $Key -File $FileName
 
    #Import the file from the temp directory
    Import-Csv $FileName
}
The monthly report is a CSV file with all of the line items in the bill you receive each month. In addition to the line items, the bill includes a few total lines. If you have consolidated billing enabled, there is an invoice total for each account and a statement total that includes the overall total. To get the total of your bill, you simply find the StatementTotal line. For example:

$Report = Get-MonthlyReport
$Report | Where-Object {$_.RecordType -eq 'StatementTotal'}
Alternatively you could sum up the PayerLineItems using Measure-Object.
($Report | Where-Object {$_.RecordType -eq 'PayerLineItem'} | Measure-Object TotalCost -Sum ).Sum
You can also find specific line items. For example, the following script will find the total number of on-demand instance hours.
($Report | Where-Object {$_.UsageType -like 'BoxUsage*'} | Measure-Object UsageQuantity -Sum ).Sum
And this line will find the total cost of the on-demand instances.
($Report | Where-Object {$_.UsageType -like 'BoxUsage*'} | Measure-Object TotalCost -Sum ).Sum
These will find the usage and cost of EBS storage.
($Report | Where-Object {$_.UsageType -like 'EBS:VolumeUsage*'} | Measure-Object UsageQuantity -Sum ).Sum
($Report | Where-Object {$_.UsageType -like 'EBS:VolumeUsage*'} | Measure-Object TotalCost -Sum ).Sum
These will find the usage and cost of S3.
($Report | Where-Object {$_.UsageType -like 'TimedStorage*'} | Measure-Object UsageQuantity -Sum ).Sum
($Report | Where-Object {$_.UsageType -like 'TimedStorage*'} | Measure-Object TotalCost -Sum ).Sum
And this one will show you snapshots.
($Report | Where-Object {$_.UsageType -like 'EBS:SnapshotUsage*'} | Measure-Object UsageQuantity -Sum ).Sum
($Report | Where-Object {$_.UsageType -like 'EBS:SnapshotUsage*'} | Measure-Object TotalCost -Sum ).Sum
As you can see there is a lot of interesting information in your bill that you can use to report on both usage and costs. In the next post I will use cost allocation report to calculate chargebacks.



1 comment: