0
votes

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

2
could you try giving more permissions in order to discard if it might be permissions issue? - Oliver Aragon

2 Answers

2
votes

I fixed the issue by giving the Owner role of the GCP project to the service account used by the cloud function. But it is still unclear for me why this permission is needed (maybe for API access ?)

0
votes

Permission denied when creating budget alert with cloud function in Google cloud platform:

Solution:

If you plan to configure a Pub/Sub topic for programmatic budget notifications, you also need to add the service account as a member of the project where your Pub/Sub topic resides, and assign the IAM Security Admin role to the service account.

please refer the link for clarity

https://cloud.google.com/billing/docs/how-to/budget-api-setup