Confirmation
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
Confirmation
Affected resource(s)
cloudflare_ai_gateway_provider_config(does not exist)Description
#6720 was closed by #6938, which added
cloudflare_ai_gatewayandcloudflare_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_gatewaycreates the gateway, andcloudflare_secrets_store_secretcan hold the credential with theai_gatewayscope, 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/containsai_gateway.mdandai_gateway_dynamic_routing.mdonly.Additional Info
Desired shape:
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), plussecret,secret_id,rate_limit,rate_limit_period. The response returnsidandsecret_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 thesecret_idthe 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_datapluslocal-execandcurl, 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-schemasopenapi.json, so this looks like a codegen coverage gap rather than undocumented surface.References
cloudflare_ai_gatewayandcloudflare_ai_gateway_dynamic_routingcloudflare_ai_gateway_custom_domain