I want to create budget alerts via a Cloud Function written in Python using the beta BillingBudgets API.
My cloud function is written in Python and is located in an admin project and aims to create one budget alert per existing project in the same parent billing account.
I got quite easily the list of projects and existing budgets, but now I can't succeed in creating budgets. I always got the following response.
{
"error": {
"code": 403,
"message": "The caller does not have permission",
"status": "PERMISSION_DENIED"
}
}
Quite an obvious message, but the service account used by the cloud function has the Billing account Administrator role, so I can't figure out which permission is missing.
Cloud function code extract:
import google.auth
from googleapiclient import discovery
scopes = ['https://www.googleapis.com/auth/cloud-platform', 'https://www.googleapis.com/auth/cloud-billing']
credentials, project_id = google.auth.default(scopes)
billingbudgetsService = discovery.build('billingbudgets', 'v1beta1', credentials=credentials, cache_discovery=False)
billing_account = "billingAccounts/000000-AAAAAA-BBBBBB"
budget_body = {
"budget": {
"displayName": "MyBudget",
"budgetFilter": {
"projects": [
"projects/11111111"
],
"creditTypesTreatment": "INCLUDE_ALL_CREDITS"
},
"amount": {
"specifiedAmount": {
"currencyCode": "EUR",
"units": "300"
}
},
"thresholdRules": [
{
"thresholdPercent": 0.5,
"spendBasis": "CURRENT_SPEND"
},
{
"thresholdPercent": 0.9,
"spendBasis": "CURRENT_SPEND"
},
{
"thresholdPercent": 1,
"spendBasis": "CURRENT_SPEND"
}
],
"allUpdatesRule": {
"pubsubTopic": "projects/billing-project/topics/budgets-alerts",
"schemaVersion": "1.0"
}
}
}
res = billingbudgetsService.billingAccounts().budgets().create(parent=billing_account, body=budget_body).execute()
I already validated the API call via the API Explorer with my personal account (also Billing Account Administrator).
In addition I got the same unauthorized error by submitting the request through curl command, even with my personal account (which is working with API explorer)
curl --request POST \
'https://billingbudgets.googleapis.com/v1beta1/billingAccounts/AAAAAA-BBBBBB-DDDDDDD/budgets' \
--header "authorization: Bearer $(gcloud auth application-default print-access-token)" \
--header 'Accept: application/json' \
--header 'Content-Type: application/json' \
--data '{"budget":{"displayName":"mybudget","budgetFilter":{"projects":["projects/11111111111"],"creditTypesTreatment":"INCLUDE_ALL_CREDITS"},"amount":{"specifiedAmount":{"currencyCode":"EUR","units":"300"}},"thresholdRules":[{"thresholdPercent":0.5,"spendBasis":"CURRENT_SPEND"},{"thresholdPercent":0.9,"spendBasis":"CURRENT_SPEND"},{"thresholdPercent":1,"spendBasis":"CURRENT_SPEND"}],"allUpdatesRule":{"pubsubTopic":"projects/project-billing/topics/budgets-alerts","schemaVersion":"1.0"}}}' \
--compressed
So I suspect an OAuth issue, but after multiple workarounds around OAuth credentials and token generation, I still have no idea.
Any thoughts or suggestions are welcome. Thanks