Google Cloud supports a Cloud Billing Catalog API. I have not worked with this API yet. Today, I plan to experiment.
Documentation page to get started with Google Cloud Platform Pricing:
Get Google Cloud Platform Pricing Information
This API requires an API Key.
- Go to the Google Cloud Console.
- Go to APIs & Services.
- Select Credentials.
- Click the “Create Credentials” button, which displays a popup menu. Select API key.
- Save your API key.
I will use curl to play with the API.
Listing public services from the catalog. Replace API_KEY with your key.
1 |
curl https://cloudbilling.googleapis.com/v1/services?key=API_KEY > services.json |
This resulted in the following error:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
{ "error": { "code": 403, "message": "Cloud Billing API has not been used in project 123456789012 before or it is disabled. Enable it by visiting https://console.developers.google.com/apis/api/cloudbilling.googleapis.com/overview?project=123456789012 then retry. If you enabled this API recently, wait a few minutes for the action to propagate to our systems and retry.", "status": "PERMISSION_DENIED", "details": [ { "@type": "type.googleapis.com/google.rpc.Help", "links": [ { "description": "Google developers console API activation", "url": "https://console.developers.google.com/apis/api/cloudbilling.googleapis.com/overview?project=123456789012" } ] } ] } } |
To solve this I went to the Google Console -> APIs & Services -> API Library. In the search box, enter “Cloud Billing API”. Enabled the API.
I then tried the command again which resulted in a long listing. I have truncated the output for this article. 60 services were returned.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
{ "services": [ { "name": "services/02DA-B362-D983", "serviceId": "02DA-B362-D983", "displayName": "Cloud Text-to-Speech API" }, { "name": "services/04C4-B046-D8B2", "serviceId": "04C4-B046-D8B2", "displayName": "Cloud Natural Language API" } ], "nextPageToken": "" } |
Now lets use “jq” to process the output to get a list of the displayNames. We will sort the output and save to services.txt. The “-f” flag makes the sort case insensitive.
1 |
jq ".services[].displayName" services.json | sort -f > services.txt |
Now we have a list like this (truncated):
1 2 3 4 5 6 7 8 9 10 |
"Aerospike Server Enterprise" "App Engine" "Aqua Container Security Platform" "BigQuery Data Transfer Service" "BigQuery" "Cloud Bigtable" "Cloud Build" "Cloud CDN" "Cloud Composer" "Cloud Contact Center" |
The next step is to get the list of SKUs for a service. We will use curl for this. I am interested in Compute Engine. The SERVICE_ID for Compute Engine is 6F81-5844-456A which I obtained from the services.json file.
1 |
curl https://cloudbilling.googleapis.com/v1/services/6F81-5844-456A/skus?key=API_KEY > skus_compute_engine.json |
This command returned a huge amount of information. In my case 210,420 lines of information. Truncated example:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 |
{ "skus": [ { "name": "services/6F81-5844-456A/skus/0009-EA63-4404", "skuId": "0009-EA63-4404", "description": "Licensing Fee for Bitnami RabbitMQ (CPU cost)", "category": { "serviceDisplayName": "Compute Engine", "resourceFamily": "License", "resourceGroup": "BitnamiRabbitMQ", "usageType": "OnDemand" }, "serviceRegions": [ "global" ], "pricingInfo": [ { "summary": "", "pricingExpression": { "usageUnit": "h", "usageUnitDescription": "hour", "baseUnit": "s", "baseUnitDescription": "second", "baseUnitConversionFactor": 3600, "displayQuantity": 1, "tieredRates": [ { "startUsageAmount": 0, "unitPrice": { "currencyCode": "USD", "units": "0", "nanos": 0 } } ] }, "currencyConversionRate": 1, "effectiveTime": "2018-10-28T03:11:58.735Z" } ], "serviceProviderName": "Google" }, |
Again we can use “jq” to start to understand the data. We begin by just looking at the “description” key for each item.
1 |
jq ".skus[].description" skus_compute_engine.json | sort -f |
This command returned 5,000 lines. Let’s look at one of the “skus”.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
{ "name": "services/6F81-5844-456A/skus/4AB4-96FF-A1F6", "skuId": "4AB4-96FF-A1F6", "description": "Cloud Interconnect - 500Mbps VLAN attachment via Google partner", "category": { "serviceDisplayName": "Compute Engine", "resourceFamily": "Network", "resourceGroup": "InterconnectAttachment", "usageType": "OnDemand" }, "serviceRegions": [ "global" ], "pricingInfo": [ { "summary": "", "pricingExpression": { "usageUnit": "h", "usageUnitDescription": "hour", "baseUnit": "s", "baseUnitDescription": "second", "baseUnitConversionFactor": 3600, "displayQuantity": 1, "tieredRates": [ { "startUsageAmount": 0, "unitPrice": { "currencyCode": "USD", "units": "0", "nanos": 173600000 } } ] }, "currencyConversionRate": 1, "effectiveTime": "2018-10-28T03:11:58.735Z" } ], "serviceProviderName": "Google" }, |
In this example, “Cloud Interconnect – 500Mbps VLAN attachment via Google partner” let’s look at the pricing. Pricing is set by these three fields:
1 2 3 |
"currencyCode": "USD", "units": "0", "nanos": 173600000 |
The key “units” is in dollars if the “currencyCode” is “USD”. The key “nanos” is number of nano units. For example $1.25 would be:
1 2 |
"units": "1", "nanos": "250000000" |
The key “nanos” is 250,000,000 / 1,000,000,000 or 1/4 or $0.25.
This means that a 500 Mbps Cloud Interconnect Attachment is billed by the hour (“usageUnit”: “h”) and the cost is $0.1736 per hour (“units”: “0”, “nanos”: “173600000”). This is approximately $125.00 per month which matches published pricing on this page.
Very interesting how Google breaks everything down into a large number of details.
From the output we can see that the skuId for this Cloud Interconnect Attachment is “4AB4-96FF-A1F6”. We can combine curl with jq to only extract this sku to automate getting pricing.
1 |
curl https://cloudbilling.googleapis.com/v1/services/6F81-5844-456A/skus?key=API_KEY | jq ".skus[] | select(.skuId == \"4AB4-96FF-A1F6\")" |
Which returns this:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
{ "name": "services/6F81-5844-456A/skus/4AB4-96FF-A1F6", "skuId": "4AB4-96FF-A1F6", "description": "Cloud Interconnect - 500Mbps VLAN attachment via Google partner", "category": { "serviceDisplayName": "Compute Engine", "resourceFamily": "Network", "resourceGroup": "InterconnectAttachment", "usageType": "OnDemand" }, "serviceRegions": [ "global" ], "pricingInfo": [ { "summary": "", "pricingExpression": { "usageUnit": "h", "usageUnitDescription": "hour", "baseUnit": "s", "baseUnitDescription": "second", "baseUnitConversionFactor": 3600, "displayQuantity": 1, "tieredRates": [ { "startUsageAmount": 0, "unitPrice": { "currencyCode": "USD", "units": "0", "nanos": 173600000 } } ] }, "currencyConversionRate": 1, "effectiveTime": "2018-10-28T03:11:58.735Z" } ], "serviceProviderName": "Google" } |
Which can be easily processed by any json library.
Update: I realized that I could not find some of the SKUs in the downloaded json. The bottom of the json had “nextPageToken”. Consulting the documentation I realized that you need to make multiple calls to download the entire list of SKUs.
After more research I learned about this Platform SKUs Explorer which makes it easy to browse the SKUs if you know the “skuId”.
I design software for enterprise-class systems and data centers. My background is 30+ years in storage (SCSI, FC, iSCSI, disk arrays, imaging) virtualization. 20+ years in identity, security, and forensics.
For the past 14+ years, I have been working in the cloud (AWS, Azure, Google, Alibaba, IBM, Oracle) designing hybrid and multi-cloud software solutions. I am an MVP/GDE with several.
April 11, 2022 at 8:40 PM
how to set billing account for the project
April 12, 2022 at 7:30 PM
Consult the Google Cloud Documentation: https://cloud.google.com/billing/docs/how-to/manage-billing-account