Automate your budgeting with the Billing Budgets API
Google Cloud Developer Advocate
TL;DR - Budgets are ideal for visibility into your costs but they can become tedious to manually update. Using the Billing Budgets API you can automate updates and changes with your custom business logic!
We've talked a lot about what budgets are and how to set them up. Once you're working with a larger company or lots of projects, it can become useful to have multiple budgets that line up to things like lines of business or certain teams. Unfortunately, manually going in and updating budgets can be a tedious task especially if you're in a rapidly changing environment. Thankfully, the Billing Budgets API can help!
Automation through APIs and Service Accounts
There's plenty of ways you can automate Google Cloud project creation, such as Terraform or using the API directly. For this post, we'll focus on the steps for interacting with the Billing Budget API so you can automate budgets regardless of which tool you're using. We'll also be using Python but the documentation covers more ways/languages to use the API.
The first thing we'll need is an identity with which to manage these budgets! To create a Service Account, you'll want to head to the Service Accounts page under IAM & Admin.
Feel free to use an even more descriptive name, like "Billing Budget API Automation Service Account"
If you need more information about Service Accounts, check out the documentation here. We're keeping things pretty simple by creating a simple Service Account and JSON key (don't forget to download this!) to authenticate with it. We'll also need to do one more thing and give the Service Account access to manage budgets on the billing account itself. You can choose Billing from the menu in the top left, choose which billing account you want to work with, and then choose Account management from the left navigation.
We'll grant this Service Account administrator access so it can manage all budgets. Of course, if this were a production account and environment, it would be worth setting up a custom role to ensure that just in case the Service Account key was compromised, the amount of damage would be limited. Principle of least privilege and all that!
We'll also have to make sure the API is enabled, which you can do from the Cloud Billing Budget API page. Each project that you plan to use this API from will need to enable it, which is all the more reason to have a centralized Billing Administration project for projects like these.
Get to the codeWith all the setup done, the next step is to start coding! We'll work with a quick Python script here to keep it simple but this could be run from anywhere that makes sense for your setup, such as a Cloud Function that you could call whenever a new project gets created. Since we're using Python and the client libraries here, we'll first create a virtualenv and then run:
pip install google-cloud-billing-budgets
Now let's look at some code!
This part is pretty simple, as all we're doing is listing out the existing budgets. To break it down a bit further:
We'll need to import the budgets resource from the Google Cloud billing client library. We're also setting the location of the Service Account key manually (though you could skip this if you just set the environment variable outside of the script) as well as setting a variable for the billing account ID. You can find this ID on the billing account page and it should look like three sets of six characters or numbers. Finally, we set up the client so we can make calls.
list_budgets function, we're using the client library to request a list of the budgets and passing in that billing account ID as the parent. Simple enough!
Now we're looping through the results and printing out their display name, along with the budget amount (refer back to this post for more details on how the different amounts work). So, running this function gives us the following:
This can be a handy way to see our existing budgets and get the details that are relevant. That's a great starting point but let's take it a step further.
Create and update
First, let's create a new budget, which can be useful to automate if you're doing things like spinning up multiple projects or a whole new environment. Here's some quick code to do just that!
Keeping it simple, this function will take in the name for the budget and the amount, as well as a flag for specified amount versus the dynamic last month amount. So if we call this function with something like this:
create_budget("Dynamically created budget", 100, False)
We'll see our new budget show up in the console!
Isn't it great when code works?
Of course, this is a pretty default budget since all we've set is the name and an amount. What if we only want to limit this budget to a certain set of projects? Back to the code!
This function takes the budget ID (you can find this through the API or the console URL) and the project number you want to add (project IDs are separate from project numbers, but you can find both through the API or console) in order to add that to the scope of the budget. If the budget didn't have a scope before, this would scope the budget to just a single project. Here's the output when we run it:
We created and updated a budget through code today! Pat yourself on the back, you've done a great job.
Hopefully this code serves as a good starting point for how you can automate your budgets to make sure your budgets can stay updated even if your environments are changing quickly. Check out the client library and the documentation if you want to learn more and automate away!