LiteLLM Terraform Provider:用 litellm_guardrails 数据源盘点网关上的全部护栏定义
2026/9/8 17:25:13 网站建设 项目流程

LiteLLM Terraform Provider:用 litellm_guardrails 数据源盘点网关上的全部护栏定义

【免费下载链接】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_guardrails数据源文档展开:它不接收任何参数,一次性从 LiteLLM 代理(同时覆盖配置文件与数据库中登记的护栏)拉取全部护栏列表,且刻意不暴露可能携带 API Key 的敏感参数。读完后,你可以在 Terraform 配置中安全地输出护栏 ID、名称与定义位置,并理解该数据源在 Provider 侧(Go 源码)与代理侧(Python 端点)的完整实现链路。

数据源定位:只读、无参、聚合双来源

官方文档 guardrails.md 对该数据源的定义非常明确:

  • 功能:检索 LiteLLM 代理上配置的全部护栏(guardrails),来源同时包括config(代理配置文件)与DB(通过 API/控制台注册到数据库的护栏);
  • 安全边界:敏感的litellm_params不会被暴露——因为护栏的litellm_params中可能存放第三方服务的 API Key(如 Lakera、Presidio 等护栏后端凭证),IaC 状态文件中不应出现这些值;
  • 参数data "litellm_guardrails"资源不接收任何参数,直接执行即可拉取全量列表;
  • 典型场景:跨环境(dev/staging/prod)比对护栏清单、在 Terraform 中做护栏存在性校验、将护栏 ID 作为输入传递给下游资源。

Provider 侧通过 provider.go 将其注册为litellm_guardrails(复数,列表查询),与单条查询数据源litellm_guardrail(按guardrail_id读取)并列,两者共用同一套读取逻辑。

快速上手:完整可用示例

以下是官方文档给出的示例用法,补上 Provider 声明后即为可直接运行的配置(Provider 声明方式参考 terraform/provider/README.md):

terraform { required_providers { litellm = { source = "BerriAI/litellm" version = "~> 1.99.0" # 与你代理运行的 LiteLLM 版本保持一致 } } } provider "litellm" { api_base = var.litellm_api_base api_key = var.litellm_api_key } # 拉取全部护栏(config + DB) data "litellm_guardrails" "all" {} # 输出所有护栏 ID output "guardrail_ids" { value = data.litellm_guardrails.all.ids } # 输出所有护栏名称 output "guardrail_names" { value = [for g in data.litellm_guardrails.all.guardrails : g.guardrail_name] }

两个输出分别利用了数据源的两个顶层属性:ids是扁平的 ID 列表,guardrails是结构化对象列表,可用 Terraform 的for表达式进一步派生(如按guardrail_definition_location过滤出配置文件中定义的护栏)。

版本约束提示:README 明确说明 Provider 版本号与 LiteLLM 代理版本号一致(例如代理跑1.99.0就 pin~> 1.99.0),并且 CI 会用tools/endpointaudit/静态审计 Provider 调用的每个端点是否与代理生成的 OpenAPI schema 一致,因此保持两者同版本可以避免接口漂移。

参数与属性参考

Argument Reference

数据源不接受任何参数(no arguments)。调用data "litellm_guardrails" "all" {}即完成声明。

Attribute Reference

属性类型说明
guardrailsList of object护栏列表,每个元素包含下表 6 个字段
guardrails[].guardrail_idString护栏的唯一标识
guardrails[].guardrail_nameString护栏的可读名称
guardrails[].guardrail_infoMap (String)护栏的附加元数据(描述、类型说明等)
guardrails[].guardrail_definition_locationString护栏定义来源:configdb
guardrails[].created_atString护栏创建时间戳
guardrails[].updated_atString护栏最近更新时间戳
idsList of String所有护栏 ID 的扁平列表

所有属性均为Computed(只读,由 Provider 从代理 API 回填),这一点可以从 data_source_guardrail.go 中的 Schema 定义得到确认——整个 Schema 里只有Computed: true的字段,没有任何Required/Optional项。

源码解析:一次 GET /guardrails/list 的完整链路

Provider 侧(Go)

数据源实现在 data_source_guardrail.go 中,核心是三个部分:

  1. 端点常量(L11):
const endpointGuardrailList = "/guardrails/list"

列表查询走代理的/guardrails/list端点;单条查询则使用/guardrails/{guardrail_id}/info风格的模板端点(endpointGuardrailInfo)。

  1. API 响应结构体(L49-L56),JSON 字段名与代理返回一一对应:
type guardrailListItemAPIResponse struct { GuardrailID string `json:"guardrail_id"` GuardrailName string `json:"guardrail_name"` GuardrailInfo map[string]interface{} `json:"guardrail_info"` GuardrailDefinitionLocation string `json:"guardrail_definition_location"` CreatedAt string `json:"created_at"` UpdatedAt string `json:"updated_at"` }
  1. Read 函数(L139-L178):通过MakeRequest(client, "GET", endpointGuardrailList, nil)发起无参 GET 请求,解析顶层{"guardrails": [...]}后逐条映射进 Terraform 状态,最终:
d.SetId("guardrails") // 数据源 ID 固定为 "guardrails" d.Set("guardrails", guardrails) d.Set("ids", ids)

值得注意的是源码中单条查询函数末尾的注释(L87):

// litellm_params is intentionally not exposed: it can carry API keys.

这解释了为什么结构体里干脆没有litellm_params字段——即便 API 有返回,Provider 也在解码结构层面将其排除在外,与文档中“Sensitivelitellm_paramsare not exposed”的描述相互印证。

代理侧(Python)

Provider 请求最终落在 guardrail_endpoints.py 定义的护栏 CRUD 路由上。从源码结构看,列表响应的构造函数_get_guardrails_list_response(L99-L120)在返回前会对每条护栏的litellm_params做掩码处理:

masked_params = _get_masked_values( litellm_params, unmasked_length=4, number_of_asterisks=4, )

也就是说存在双层防线:代理 API 本身对litellm_params做掩码(前 4 位可见、其余以 4 个星号代替),Terraform Provider 则干脆不把该字段纳入状态。

关于访问权限,从 litellm/proxy/_types.py 的路由分组可以看到,/guardrails/list(及其 v2 变体/v2/guardrails/list)被列入多组只读路由白名单,其中包括面向管理/查看角色的分组,注释明确写着 “Guardrails / Policies pages (read-only views)”。可以推断:持有具备管理查看权限的 API Key 即可成功调用该数据源,而创建/注册护栏的写端点(如/guardrails/register)则有更严格的团队/管理员级校验。

测试验证

Provider 的单元测试 data_source_guardrail_test.go 用httptest起了一个 mock 服务器来固化上述行为:

  • TestDataSourceGuardrailsRead断言 Provider 发出的请求必须精确为GET /guardrails/list;mock 返回两条护栏(一条db、一条config),测试校验guardrails列表长度为 2、首条 ID/名称正确,且ids输出为[gid-1, gid-2]
  • 单条数据源测试TestDataSourceGuardrailRead同样断言请求路径为/guardrails/gid-1/info,并验证guardrail_definition_locationguardrail_info(如description: "pii guard")被正确回填。

这组测试也直观展示了两种guardrail_definition_location取值的真实样本:同一代理实例上,db来源的护栏(经 API 注册)与config来源的护栏(写在代理配置里)会混排在同一列表中,这正是文档“from both config and DB”的含义。

使用建议与注意事项

  • 区分 config 与 dbguardrail_definition_locationconfig的护栏由代理配置文件管理,Terraform 只能通过本数据源读取它;db来源的护栏才能配合 Provider 的litellm_guardrail资源做完整生命周期管理。做 IaC 盘点时可按此字段过滤,避免误以为列表中的护栏都能被 Terraform 增删。
  • 不要把敏感信息写回状态:本数据源不包含litellm_params,因此不要试图用 Terraform 输出重建护栏的完整参数;需要凭证时仍应走代理配置或 Secret Manager。
  • 版本对齐:按 terraform/provider/README.md 的约定,Provider 版本必须与代理版本同一发行线(~> <LiteLLM 版本>);旧版 Provider(0.x序列)与当前数据源行为不兼容,~> 0.4之类的约束永远不会拿到新特性。
  • 只读语义:该数据源每次plan/apply都会重新请求/guardrails/list,代理侧护栏变更后 Terraform 状态会自动同步,无需手动刷新。

小结

litellm_guardrails数据源以“零参数 + 全量只读”的方式解决了护栏盘点问题:一个data块即可拿到全部护栏的 ID、名称、元数据、定义来源(config/db)与时间戳,并在 Provider 与代理两层实现上共同屏蔽了可能泄露密钥的litellm_params。结合 data_source_guardrail.go 的读取逻辑、guardrail_endpoints.py 的掩码实现与 data_source_guardrail_test.go 的端点断言,你可以完整复核这条从 HCL 到代理 API 的数据链路。

【免费下载链接】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),仅供参考

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

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

立即咨询