You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Google Cloud Function无法禁用账单:权限问题求助

云函数stop_billing无法禁用账单的排查方案

我使用Google官方文档中的stop_billing云函数,预期在费用超预算时禁用项目账单,代码如下:

import base64
import json
import os
from googleapiclient import discovery
PROJECT_ID = os.getenv('GCP_PROJECT')
PROJECT_NAME = f'projects/{PROJECT_ID}'
def stop_billing(data, context):
    pubsub_data = base64.b64decode(data['data']).decode('utf-8')
    pubsub_json = json.loads(pubsub_data)
    cost_amount = pubsub_json['costAmount']
    budget_amount = pubsub_json['budgetAmount']
    if cost_amount <= budget_amount:
        print(f'No action necessary. (Current cost: {cost_amount})')
        return

    if PROJECT_ID is None:
        print('No project specified with environment variable')
        return

    billing = discovery.build(
        'cloudbilling',
        'v1',
        cache_discovery=False,
    )

    projects = billing.projects()

    billing_enabled = __is_billing_enabled(PROJECT_NAME, projects)

    if billing_enabled:
        __disable_billing_for_project(PROJECT_NAME, projects)
    else:
        print('Billing already disabled')


def __is_billing_enabled(project_name, projects):
    """
    Determine whether billing is enabled for a project
    @param {string} project_name Name of project to check if billing is enabled
    @return {bool} Whether project has billing enabled or not
    """
    try:
        res = projects.getBillingInfo(name=project_name).execute()
        return res['billingEnabled']
    except KeyError:
        # If billingEnabled isn't part of the return, billing is not enabled
        return False
    except Exception:
        print('Unable to determine if billing is enabled on specified project, assuming billing is enabled')
        return True


def __disable_billing_for_project(project_name, projects):
    """
    Disable billing for a project by removing its billing account
    @param {string} project_name Name of project disable billing on
    """
    body = {'billingAccountName': ''}  # Disable billing
    try:
        res = projects.updateBillingInfo(name=project_name, body=body).execute()
        print(f'Billing disabled: {json.dumps(res)}')
    except Exception:
        print('Failed to disable billing, possibly check permissions')

测试时日志始终显示"Failed to disable billing, possibly check permissions",已为云函数服务账号配置Billing Administrator权限,但仍无法成功禁用账单,以下是需要排查的缺失配置:

  • 确认服务账号权限作用于账单账号
    Billing Administrator权限需要添加到项目关联的账单账号权限列表中,而非仅作用于云函数所在项目。因为禁用项目账单本质是修改项目与账单账号的关联关系,必须拥有账单账号的管理权限。
    操作:打开账单账号的权限设置页面,将云函数服务账号添加为成员并授予Billing Administrator角色。

  • 检查项目级编辑权限
    服务账号需对目标项目拥有Editor角色(或包含resourcemanager.projects.updateBillingInfo权限的自定义角色),修改项目账单关联属于项目级配置变更,需要对应权限支撑。
    操作:进入项目IAM页面,确认云函数服务账号已被授予Editor或等价权限。

  • 启用Cloud Billing API
    确保目标项目中Cloud Billing API已启用,否则云函数无法调用账单相关接口。
    操作:在API库中搜索Cloud Billing API,确认状态为"已启用",未启用则点击启用。

  • 排查组织级政策限制
    如果项目属于Google Workspace或Cloud Identity组织,可能存在组织级政策禁止修改项目账单关联,需联系组织管理员确认是否有相关限制。

  • 优化异常日志定位问题
    当前代码的异常捕获仅输出通用提示,建议修改__disable_billing_for_project函数的异常处理逻辑,打印具体错误信息:

    except Exception as e:
        print(f'Failed to disable billing: {str(e)}')
    

    重新部署后查看日志,根据具体错误(如权限不足的具体API报错、资源不存在等)进一步定位问题。

内容的提问来源于stack exchange,提问作者OwlKnowledge

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.20 22:53:18