In my previous blog I wrote about billing report for EBS Volumes under EC2 – Other service category of AWS Cost Explorer API. Today, I am going to provide another script which will help you to generate billing report specific to Elastic IP address usage in AWS.
So, if you have already gone through the EBS Volume billing report, you know what are the prerequisites you need to have before writing this script. If not, here I am repeating those steps again.
Make sure, all your Elastic IPs (EIPs) tagged properly with a specific tag key to distinguish it from rest of resource types. For my example, I am using “EIPName” as tag key and value as the name of the EIP instance.
Once you have set Tags on all EIPs, you need to add this new Tag Key to AWS Cost allocation Tag list. If you have already set it , you are good! If not, Open Billing Console through link – https://console.aws.amazon.com/billing/home#/ .
Now, click on Cost Allocation tag option from the left side menu as shown in the screenshot .
Finally, from the list of available tag keys used in your subscription, you should see the Tag applied on EIPs (Example, EIPName) as mentioned previously. Select the tag and click on Activate button under User-Defined Cost Allocation Tags. Once activated, it takes few hours before you can actually use it to generate Billing report using that tag.
Ok, now we are all set to start writing our Powershell script. This script assumes you have already setup your AWS credentials and AWS Powershell SDK to run this script on your system. If you face any issue setting those, please refer following documents to set those:
- https://docs.aws.amazon.com/powershell/latest/userguide/specifying-your-aws-credentials.html
- https://aws.amazon.com/powershell/
Let’s provide the time range for which this billing report will be generated. Make sure, the time range you are providing is with in the allowed range of AWS Billing API. I will be setting this script to either accept start and end date as parameters or generate it for the last month if nothing is provided. Then we will set CostExplorer Date interval using the start and end date as below
$interval = New-Object Amazon.CostExplorer.Model.DateInterval
$interval.Start = $firstDay
$interval.End = $lastDay
We now need to set Dimension, Filter and Grouping Definition as below. Note, Service set to “EC2 – Other”.
$dimension = New-Object Amazon.CostExplorer.Model.DimensionValues
$dimension.Key = "SERVICE"
$dimension.Values ="EC2 - Other"
$Filter = New-Object Amazon.CostExplorer.Model.Expression
$Filter.Dimensions = $dimension
$groupInfo = New-Object Amazon.CostExplorer.Model.GroupDefinition
$groupInfo.Type = "TAG"
$groupInfo.Key = "EIPName"
Define AWS Billing Metric as BlendedCost and UsageQuantity.
$metric = @("BlendedCost","UsageQuantity")
Finally, call the AWS CostExplorer API and parse through the result to generate CSV output with all required information.
$costUsage = Get-CECostAndUsage -TimePeriod $interval -Granularity DAILY -Metric $metric -Filter $Filter -GroupBy $groupInfo
ForEach($c in $costUsage.ResultsByTime){
$sTime = $cost = $eipName = ""
$sTime = $c.TimePeriod.Start
ForEach($grp in $c.Groups){
$eipName = $grp.Keys.Split("$")[1]
if([String]::IsNullOrEmpty($eipName)){$eipName = "No Name Tag"}
$cost = $grp.Metrics["BlendedCost"].Amount
$usageHours = $grp.Metrics["UsageQuantity"].Amount
"$eipName,$sTime,$usageHours,$cost" | Out-File $tFile -Append -Encoding ASCII
}
}
Here is the complete script. Leave your comment in the comment section if you have any suggestion or question.
Param(
[Parameter(Mandatory=$false)]
[String]$firstDay,
[Parameter(Mandatory=$false)]
[String]$lastDay
)
#Print cost details for the Account for previous month
if([String]::IsNullOrEmpty($firstDay)){
$firstDay = Get-Date -Year (Get-Date).Year -Month (Get-Date).AddMonths(-1).Month -Day 1 -UFormat "%Y-%m-%d"
}
if([String]::IsNullOrEmpty($lastDay)){
$lastDay = Get-Date -Year (Get-Date).Year -Month (Get-Date).AddMonths(-1).Month -Day ([DateTime]::DaysInMonth((Get-Date).Year, (Get-Date).Month)) -UFormat "%Y-%m-%d"
}
$currentDir = $(Get-Location).Path
$oFile = "$($currentDir)\aws_eip_billing_usage_data.csv"
$tFile = "$($currentDir)\aws_eip_billing_usage_data_temp.csv"
if(Test-Path $oFile){
Remove-Item $oFile -Force
}
if(Test-Path $tFile){
Remove-Item $tFile -Force
}
Import-Module AWSPowershell
"Name,Date,UsageHours,Cost" | Out-File $tFile -Append -Encoding ASCII
$interval = New-Object Amazon.CostExplorer.Model.DateInterval
$interval.Start = $firstDay
$interval.End = $lastDay
$dimension = New-Object Amazon.CostExplorer.Model.DimensionValues
$dimension.Key = "SERVICE"
$dimension.Values ="EC2 - Other"
$Filter = New-Object Amazon.CostExplorer.Model.Expression
$Filter.Dimensions = $dimension
$groupInfo = New-Object Amazon.CostExplorer.Model.GroupDefinition
$groupInfo.Type = "TAG"
$groupInfo.Key = "EIPName"
$metric = @("BlendedCost","UsageQuantity")
####
$costUsage = Get-CECostAndUsage -TimePeriod $interval -Granularity DAILY -Metric $metric -Filter $Filter -GroupBy $groupInfo
ForEach($c in $costUsage.ResultsByTime){
$sTime = $cost = $eipName = ""
$sTime = $c.TimePeriod.Start
ForEach($grp in $c.Groups){
$eipName = $grp.Keys.Split("$")[1]
if([String]::IsNullOrEmpty($eipName)){$eipName = "No Name Tag"}
$cost = $grp.Metrics["BlendedCost"].Amount
$usageHours = $grp.Metrics["UsageQuantity"].Amount "$eipName,$sTime,$usageHours,$cost" | Out-File $tFile -Append -Encoding ASCII
}
}
Import-Csv $tFile | Sort-Object 'Name','Date' | Export-Csv -Path $oFile -NoTypeInformation
if(Test-Path $tFile){
Remove-Item $tFile -Force
}