LiteLLM Terraform Provider 的 litellm_budgets 数据源:以基础设施即代码方式读取代理中的全部预算
2026/9/8 19:58:02 网站建设 项目流程

LiteLLM Terraform Provider 的 litellm_budgets 数据源:以基础设施即代码方式读取代理中的全部预算

【免费下载链接】litellmThe fastest, litest AI Gateway. Rust core with Python SDK. Call 100+ LLM APIs in OpenAI (or native) format with cost tracking, guardrails, load balancing, and logging [Bedrock, Azure, OpenAI, Anthropic, OpenAI, VertexAI, vLLM, Nvidia NIM]项目地址: https://gitcode.com/GitHub_Trending/li/litellm

本篇技术指南聚焦 LiteLLM Terraform Provider 中的litellm_budgets数据源(对应文档 budgets.md),讲清它如何在 Terraform 中一次性拉取 LiteLLM Proxy 上配置的全部预算(budget),返回budgets列表与ids两个核心属性。读完本文,你可以直接在 HCL 中枚举、审计和消费 Proxy 上的预算配置,并理解该数据源从 Terraform 到 Proxy REST API 的完整实现链路。

什么是 litellm_budgets 数据源

LiteLLM 支持在代理(proxy)层面创建"预算"对象,将其应用到 team、组织、用户或 API key 上,统一约束美元额度、TPM/RPM 速率与并发请求数。当预算已经由其他流程(控制台、litellm_budget资源或其他 IaC 栈)创建后,litellm_budgets数据源提供了一种只读的读取方式:

Retrieves all budgets configured on the LiteLLM proxy.

它与litellm_budget单数数据源(按budget_id查询单个预算,见 budget.md)配对使用,两者共同覆盖"查单个"与"列全部"两类只读场景。

前置条件:配置 Provider

数据源依赖 Provider 完成鉴权。Provider 的根 Schema 定义在 provider.go,包含三个参数,均支持同名环境变量作为默认值:

参数类型必填环境变量说明
api_basestringLITELLM_API_BASELiteLLM API 的基础 URL
api_keystringLITELLM_API_KEY用于鉴权的 API key(标记为 Sensitive)
insecure_skip_verifyboolLITELLM_INSECURE_SKIP_VERIFY跳过 TLS 证书校验,仅建议开发环境或自签证书使用

一个最小可用的 Provider 声明:

terraform { required_providers { litellm = { source = "BerriAI/litellm" version = "~> 1.99.0" # 与你 proxy 运行的 LiteLLm 版本保持一致 } } } provider "litellm" { api_base = var.litellm_api_base api_key = var.litellm_api_key }

注意 terraform/provider/README.md 强调的版本策略:Provider 版本与 LiteLLM 版本一一对应,每次 proxy 发布会同步发布同版本的 Provider,因此required_providers中的版本约束应与 proxy 实际运行的版本行对齐。

使用示例与属性参考

完整用法

继承自 budgets.md 的官方示例:

data "litellm_budgets" "all" {} output "budget_ids" { value = data.litellm_budgets.all.ids }

该数据源不接收任何参数("This data source takes no arguments"),terraform plan阶段即会调用代理接口读取全量预算并填充输出。

Attribute Reference

属性类型说明
budgetslist of object代理上配置的全部预算列表,每个条目包含下表字段
idslist of string全部预算的 ID 列表(等价于budgets[*].budget_id的扁平化)

budgets列表中每个条目的字段:

字段Terraform 类型说明
budget_idstring预算 ID
max_budgetfloat硬预算上限(USD),超出后请求会失败
soft_budgetfloat软预算上限(USD),超出仅触发告警,不拦截请求
max_parallel_requestsint该预算允许的最大并发请求数
tpm_limitint该预算的每分钟 token 上限
rpm_limitint该预算的每分钟请求数上限
budget_durationstring预算重置周期,如1hr1d28d
model_max_budgetstring按模型的预算配置,JSON 字符串格式,例如{"gpt-4o": {"max_budget": 10.0}}
budget_reset_atstring预算重置的时间(datetime)

以上类型并非文档惯例,而是与源码 Schema 逐一对应——data_source_budget.go 中budgetsTypeList(元素是嵌套 Resource),ids为元素TypeStringTypeListmax_budget/soft_budgetTypeFloatmax_parallel_requests/tpm_limit/rpm_limitTypeInt

实战:按预算迭代消费

由于返回的是结构化列表,可以直接驱动for_each做审计或二次编排,例如把预算 ID 导出给合规报表,或为某个预算下的 key 做交叉校验:

data "litellm_budgets" "all" {} # 仅输出设置了硬预算上限的条目 output "budgets_with_hard_limit" { value = [ for b in data.litellm_budgets.all.budgets : b if b.max_budget > 0 ] } # 用预算 ID 作为 for_each 键,逐个拉取单预算详情 data "litellm_budget" "each" { for_each = toset(data.litellm_budgets.all.ids) budget_id = each.value }

源码实现解析:从 HCL 到 /budget/list

读取流程

litellm_budgets数据源的实现位于 data_source_budget.go 的dataSourceLiteLLMBudgetsRead,核心链路为:

  1. 通过MakeRequest(client, "GET", endpointBudgetList, nil)发起GET /budget/list请求(端点常量endpointBudgetList = "/budget/list"定义在 data_source_budget.go);
  2. handleResponse校验响应状态;
  3. 将响应体反序列化为[]budgetResponse切片——该结构体定义在 resource_budget.go,除BudgetID外所有字段均为指针类型(*float64*int*string),用于区分"未设置"与"零值";
  4. 遍历切片,通过budgetListEntry组装每个预算 map,同时收集ids
  5. 执行d.SetId("budgets")d.Set("budgets", ...)d.Set("ids", ...)写入 state。

字段映射与可空语义

budgetListEntry(data_source_budget.go)对每个可选字段都做了判空:只有当对应指针非 nil 时才写入条目。这意味着代理上未设置的限额不会出现在返回的条目中,HCL 侧消费时应使用coalescelist/条件判断等防御式写法,而不是假设九个字段必然齐全。

model_max_budget 的 JSON 归一化

model_max_budget是数据源中最容易踩坑的字段:Proxy 接口返回时它可能是嵌套对象(dict)而非字符串,而 Terraform Schema 要求 string。源码通过budgetModelMaxBudgetString(data_source_budget.go)做了归一化——若已是 string 直接透传,若是 map 则json.Marshal成字符串(空 map 视为未设置)。因此你在 HCL 中拿到的始终是合法 JSON 字符串,如需在 Terraform 内解析,应配合jsondecode(data.litellm_budgets.all.budgets[0].model_max_budget)使用。

测试用例对行为的印证

单元测试 data_source_budget_test.go 中的TestDataSourceBudgetsRead_MapsList用一个httptest假服务器覆盖了上述关键行为,可作为行为契约:

  • 断言请求必须是GET /budget/list(与单数数据源的POST /budget/info形成对比);
  • 返回两个预算(bud-1max_budget/tpm_limit/model_max_budget对象,bud-2仅带soft_budget),验证budgets列表长度、各字段映射,以及model_max_budget被转为可json.Unmarshal的字符串且包含gpt-4o键;
  • 验证ids精确为[bud-1 bud-2]

后端 API:/budget/list 的服务端约束

数据源调用的后端接口定义在 budget_management_endpoints.py 的list_budget,有三个直接决定可用性的前提:

  1. 必须连接数据库prisma_client is None时接口返回 400(db not connected error)。也就是说纯配置 YAML 启动、未接入数据库的 proxy 无法提供该列表;
  2. 需要 admin 视角:接口经过user_api_key_auth依赖鉴权后,还会调用_user_has_admin_view(user_api_key_dict)校验角色,非 admin/proxy admin 角色会得到 400 权限错误。因此provider "litellm"使用的api_key应是一个具备管理员角色的 master key;
  3. 数据源实现:服务端通过BudgetRepository(prisma_client).table.find_many()全量拉取预算表记录后原样返回。

同一文件头部注释列出了完整的预算管理端点集合(/budget/new/budget/info/budget/update/budget/delete/budget/settings/budget/list),其中读写端点分别对应 Provider 中的litellm_budget资源(resource_budget.go 定义了对应的四个端点常量)与两个数据源。

单数与复数数据源的差异对比

维度litellm_budget(单数)litellm_budgets(复数,本篇)
参数budget_id(必填)
后端请求POST /budget/info,body 为{"budgets": ["<id>"]}GET /budget/list
未命中行为返回budget '<id>' not found错误空列表(budgets/ids为空)
典型用途依赖已知预算 ID 的精确引用枚举、审计、for_each驱动

两个实现细节值得注意:单数数据源在 404 或空响应时直接报错(data_source_budget.go),而资源侧的resourceLiteLLMBudgetRead遇到预算消失时会执行d.SetId("")将其移出 state,二者在漂移处理策略上并不相同。

小结

litellm_budgets数据源用零参数设计换来了最简的枚举体验:一条data "litellm_budgets" "all" {}声明即可在 state 中获得全量预算对象与 ID 列表。从源码看,其字段判空映射、model_max_budget的 JSON 归一化均有单元测试固化;使用时需牢记三件事——proxy 必须接入数据库、调用 key 必须具有 admin 视角、Provider 版本应与 proxy 版本保持一致。对于预算的创建与变更,则应使用 resource_budget 相关文档 同系列的litellm_budget资源,配合本篇的数据源完成"写-读-校验"的完整 IaC 闭环。

【免费下载链接】litellmThe fastest, litest AI Gateway. Rust core with Python SDK. Call 100+ LLM APIs in OpenAI (or native) format with cost tracking, guardrails, load balancing, and logging [Bedrock, Azure, OpenAI, Anthropic, OpenAI, VertexAI, vLLM, Nvidia NIM]项目地址: https://gitcode.com/GitHub_Trending/li/litellm

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询