Skip to content

Missing cloudflare_ai_gateway_provider_config (AI Gateway BYOK) from the provider #7332

Description

@kalw

Confirmation

  • I have searched the issue tracker and my suggestion does not already have an associated feature request.

Affected resource(s)

  • cloudflare_ai_gateway_provider_config (does not exist)

Description

#6720 was closed by #6938, which added cloudflare_ai_gateway and cloudflare_ai_gateway_dynamic_routing. AI Gateway provider configs — the BYOK linkage — are still missing, and without them a Terraform-managed gateway cannot actually reach a provider.

The half-finished state is what makes this awkward. cloudflare_ai_gateway creates the gateway, and cloudflare_secrets_store_secret can hold the credential with the ai_gateway scope, but nothing attaches the two together. So every gateway needs a dashboard step or an out-of-band API call before it can serve a single request.

The endpoints are documented and in the published API schema:
https://developers.cloudflare.com/ai-gateway/configuration/bring-your-own-keys/

Checked against v5.23.0 and against main: docs/resources/ contains ai_gateway.md and ai_gateway_dynamic_routing.md only.

Additional Info

Desired shape:

resource "cloudflare_ai_gateway" "this" {
  account_id                 = var.account_id
  id                         = "my-gateway"
  authentication             = true
  collect_logs               = true
  cache_ttl                  = 0
  cache_invalidate_on_update = true
  rate_limiting_interval     = 0
  rate_limiting_limit        = 0
  store_id                   = var.secrets_store_id
}

resource "cloudflare_secrets_store_secret" "anthropic" {
  account_id = var.account_id
  store_id   = var.secrets_store_id
  # AI Gateway resolves BYOK credentials by secret name:
  # <gateway_id>_<provider_slug>_<alias>
  name   = "my-gateway_anthropic_default"
  value  = var.anthropic_api_key
  scopes = ["ai_gateway"]
}

resource "cloudflare_ai_gateway_provider_config" "anthropic" {
  account_id        = var.account_id
  gateway_id        = cloudflare_ai_gateway.this.id
  provider_slug     = "anthropic"
  alias             = "default"
  default_config    = true
  secret_id         = cloudflare_secrets_store_secret.anthropic.id
  rate_limit        = 100
  rate_limit_period = 60
}

Full CRUD is available on the API:

  • POST /accounts/{account_id}/ai-gateway/gateways/{gateway_id}/provider_configs (create)
  • GET /accounts/{account_id}/ai-gateway/gateways/{gateway_id}/provider_configs (list)
  • PUT /accounts/{account_id}/ai-gateway/gateways/{gateway_id}/provider_configs/{id} (update)
  • DELETE /accounts/{account_id}/ai-gateway/gateways/{gateway_id}/provider_configs/{id} (delete)

Request fields per the schema: provider_slug, alias, default_config (required), plus secret, secret_id, rate_limit, rate_limit_period. The response returns id and secret_preview.

One wrinkle worth encoding in the resource: AI Gateway resolves the credential by Secrets Store secret name (<gateway_id>_<provider_slug>_<alias>), not by the secret_id the API accepts and returns — the docs call this out for API-created secrets. A misnamed secret fails only at request time, with nothing for Terraform to show.

Working around this today needs terraform_data plus local-exec and curl, reconciling with list-then-POST-or-PUT, which gives up drift detection and delete-on-destroy. data "http" is not an alternative for the create side, since a data source is read on every plan and would re-POST.

The endpoint is present in cloudflare/api-schemas openapi.json, so this looks like a codegen coverage gap rather than undocumented surface.

References

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions