Decoding Your AWS Bill (Part 2) Chargeback with Tags
By Brian
It took 6 months but I finally got time to continue the series on Decoding Your AWS bill. In the last post, we used PowerShell to download and query the monthly bill. In this post we use tags to create a cost allocation report. In the next, and final post in this series, I will show you how to load the hourly detail report into SQL Server.
Let's assume that we have multiple project teams at our company and they all have servers running in the same AWS account. We want to "charge back" each team for their usage. We begin by tagging each instance with a project name (see figure below). Notice that I also include a name and owner.
This is good start, but we learned in part one that charges are allocated to the instances as well as the volumes and network interfaces that are attached to them. Therefore, we have to tag the resources as well as the instance itself. It is probably unrealistic to ask our users to tag all the resources so let's create a script that copies tags from the instance any resources attached to it. This way our users only have to remember to tag their instances.
The script below will read all of the tags from the instance and copy them to each resource. I have something very similar scheduled to run once a day on each of my accounts.
This is a good start, but it will not really scale well. It makes an API call for ever resource every time we run it. It will work well for a handful of instances, but as we add more instances the script will take longer and longer to run. It would be better to cache the tags collection and only change update those resources that need to be changed. Here is a much better version.
Now we have to add the tags we created to our reports. I assume at this point that you have billing reports enabled. If not, see my prior blog post. Log into the web console using your account credentials (not IAM credentials) and click on your name in the top right corner. From the dropdown, click "Billing and Cost Management." Choose "Preferences" from the menu down the left side of the screen. Finally, click the "Manage Report Tags" link toward the end of the screen.
Now, find the tags you want to include in the report (see the figure below). Make sure you include the project tag.
Now we can download and query the report just like we did in the last post. The only change is that we are going to use the "$AccountId-aws-cost-allocation-$Year-$Month.csv" report rather than the "$AccountId-aws-billing-csv-$Year-$Month.csv" report we used before.
In addition, note that the custom tags we added will appear in the report as user:tag. So our Project tag will appear as user:Project. Therefore, if we wanted to return all the costs associated with the ERP project we would use a PowerShell query like this:
Now, we have a little problem. You may notice that if you add up all costs associated to all projects, it does not sum to the invoice total. This is expected. There are a few costs we did not capture. First, we only tagged EC2. If you want to allocate other services, you will need to develop a similar strategy to the one we used above for EC2. Second, you may have a support contract that adds 10% to the bill. Third, there are some EC2 costs, like snapshots that do not include tags in the report. There is nothing we do we these last two, but allocate them to the projects as overhead. The script below will do just that. I'm not going to go into detail, but you can look though my script to understand it.
When you run this script it should output the statement total and a table showing the costs allocated to each project. Similar to the the following.
That's it for this post. In the next post we use the hourly report to populate a warehouse in SQL Server.
Let's assume that we have multiple project teams at our company and they all have servers running in the same AWS account. We want to "charge back" each team for their usage. We begin by tagging each instance with a project name (see figure below). Notice that I also include a name and owner.
This is good start, but we learned in part one that charges are allocated to the instances as well as the volumes and network interfaces that are attached to them. Therefore, we have to tag the resources as well as the instance itself. It is probably unrealistic to ask our users to tag all the resources so let's create a script that copies tags from the instance any resources attached to it. This way our users only have to remember to tag their instances.
The script below will read all of the tags from the instance and copy them to each resource. I have something very similar scheduled to run once a day on each of my accounts.
|
|
This is a good start, but it will not really scale well. It makes an API call for ever resource every time we run it. It will work well for a handful of instances, but as we add more instances the script will take longer and longer to run. It would be better to cache the tags collection and only change update those resources that need to be changed. Here is a much better version.
|
|
Now we have to add the tags we created to our reports. I assume at this point that you have billing reports enabled. If not, see my prior blog post. Log into the web console using your account credentials (not IAM credentials) and click on your name in the top right corner. From the dropdown, click "Billing and Cost Management." Choose "Preferences" from the menu down the left side of the screen. Finally, click the "Manage Report Tags" link toward the end of the screen.
Now, find the tags you want to include in the report (see the figure below). Make sure you include the project tag.
Now we can download and query the report just like we did in the last post. The only change is that we are going to use the "$AccountId-aws-cost-allocation-$Year-$Month.csv" report rather than the "$AccountId-aws-billing-csv-$Year-$Month.csv" report we used before.
In addition, note that the custom tags we added will appear in the report as user:tag. So our Project tag will appear as user:Project. Therefore, if we wanted to return all the costs associated with the ERP project we would use a PowerShell query like this:
|
|
Now, we have a little problem. You may notice that if you add up all costs associated to all projects, it does not sum to the invoice total. This is expected. There are a few costs we did not capture. First, we only tagged EC2. If you want to allocate other services, you will need to develop a similar strategy to the one we used above for EC2. Second, you may have a support contract that adds 10% to the bill. Third, there are some EC2 costs, like snapshots that do not include tags in the report. There is nothing we do we these last two, but allocate them to the projects as overhead. The script below will do just that. I'm not going to go into detail, but you can look though my script to understand it.
|
|
When you run this script it should output the statement total and a table showing the costs allocated to each project. Similar to the the following.
|
|
That's it for this post. In the next post we use the hourly report to populate a warehouse in SQL Server.