Skip to content

Add direct-mode bundle support for AI Gateway securables - #6410

Open
alex-khakhlyuk wants to merge 3 commits into
databricks:mainfrom
alex-khakhlyuk:aigov-dabs-securables
Open

Add direct-mode bundle support for AI Gateway securables#6410
alex-khakhlyuk wants to merge 3 commits into
databricks:mainfrom
alex-khakhlyuk:aigov-dabs-securables

Conversation

@alex-khakhlyuk

@alex-khakhlyuk alex-khakhlyuk commented Aug 27, 2026

Copy link
Copy Markdown

Summary

Adds Databricks Asset Bundle support (direct deployment engine) for three Unity Catalog AI Gateway securables, so they can be declared and deployed from databricks.yml:

  • model_services — AI Gateway model service
  • mcp_services — AI Gateway MCP service
  • model_provider_services — AI Gateway model provider service

What's included

For each resource, following the existing direct-engine pattern (cf. volume / database_instance):

  • bundle/config/resources/<r>.go — config/state struct implementing ConfigResource (Exists, TerraformResourceName, ResourceDescription, etc.). A flat struct exposes the immutable identity (parent + <r>_id, which the server composes into the resource name) plus the mutable comment/config body; the SDK models the identity inputs as URL params, so the create request can't be embedded directly.
  • bundle/direct/dresources/<r>.go — CRUD mapped 1:1 onto the AiGateway service in databricks-sdk-go (Create/Get/Update/Delete). The engine tracks the bare {catalog}.{schema}.{leaf} id and re-adds the resource-name prefix at each call; DoRead reconstructs the identity from the server-returned name so it participates in drift detection.
  • resources.yml classification — parent + <r>_id as immutable id fields; model_provider_service.config.provider_type is immutable (recreate); output-only config fields (inference_table.*, source_connection.is_deleted) and the write-only provider secrets (*.plaintext, never returned by GET) are suppressed to avoid phantom drift.
  • Registration (bundle/config/resources.go, bundle/direct/dresources/all.go), a resource test server implementation (libs/testserver/), regenerated schema, and updates to the shared "all resources" coverage tests.

Owner is deferred (the API returns effective_owner), permissions use grants rather than bundle permissions (classified in unsupportedResources), and there is no Catalog Explorer URL wired up yet.

Status

Draft. go build ./... and go test ./bundle/direct/dresources/ ./bundle/config/... ./libs/testserver/ pass (full create/read/update/delete/drift per resource).

Live-cloud smoke test (direct engine, model_provider_service, staging workspace): full CRUD verified. bundle deploy created the resource, editing a field + redeploying updated it, and bundle destroy deleted it (confirmed gone). This also confirms the ["comment","config"] update mask is accepted over the immutable provider_type — no mask narrowing needed. model_service / mcp_service share the identical direct-engine code path (not separately deployed here; they need a routing target / UC connection to create).

Remaining before merge-ready (per bundle/direct/dresources/README.md):

  • Acceptance tests under acceptance/bundle/resources/<r>/basic (deploy/summary/update-in-place/recreate-on-immutable) + remote-delete (drift) for all three resources
  • Invariant configs (acceptance/bundle/invariant/configs/*.yml.tmpl) and bind/unbind tests (acceptance/bundle/deployment/bind/*)
  • Live-cloud smoke test — done for model_provider_service (see above)

alexkh-db and others added 2 commits August 27, 2026 22:10
Add three Unity Catalog AI Gateway securables as Databricks Asset Bundle
resources on the direct deployment engine: model_service, mcp_service,
and model_provider_service.

Each resource follows the existing direct-engine pattern (cf. volume /
database_instance):
- bundle/config/resources/<r>.go: a flat state struct exposing the
  immutable identity (parent + <r>_id, which the server composes into the
  resource name) plus the mutable comment/config body. The SDK models the
  identity inputs as URL params, so the create request cannot be embedded
  directly.
- bundle/direct/dresources/<r>.go: CRUD mapped 1:1 onto the SDK AiGateway
  service (Create/Get/Update/Delete). The engine tracks the bare
  {catalog}.{schema}.{leaf} id and re-adds the resource name prefix at
  each call; DoRead reconstructs the identity from the server-returned
  name so it participates in drift detection.

resources.yml classification: parent + <r>_id are provided id fields
(immutable, recreate on change); model_provider_service.config.provider_type
is immutable (recreate); output-only config fields (inference_table.*,
mcp source_connection.is_deleted) and the write-only provider secrets
(*.plaintext, never returned by GET) are suppressed to avoid phantom drift.

Wires up registration, the resource test server, the generated schema,
and the shared "all resources" coverage tests. Builds and the
dresources/config/testserver unit tests pass.

Follow-up (not in this commit): acceptance tests, invariant configs,
bind/unbind tests, and live-cloud validation (including confirming the
model_provider_service update mask is accepted over the immutable
provider_type field).

Co-authored-by: Isaac <no-reply@databricks.com>
@alex-khakhlyuk
alex-khakhlyuk marked this pull request as ready for review August 28, 2026 11:25
@github-actions

github-actions Bot commented Aug 28, 2026

Copy link
Copy Markdown
Contributor

Approval status: pending

/acceptance/bundle/ - needs approval

58 files changed
Suggested: @denik
Also eligible: @janniklasrose, @pietern, @andrewnester, @shreyas-goenka, @anton-107, @lennartkats-db

/bundle/ - needs approval

18 files changed
Suggested: @denik
Also eligible: @janniklasrose, @pietern, @andrewnester, @shreyas-goenka, @anton-107, @lennartkats-db

General files (require maintainer)

5 files changed
Based on git history:

  • @denik -- recent work in libs/testserver/, bundle/direct/dresources/, acceptance/bundle/invariant/configs/

Any maintainer (@andrewnester, @anton-107, @denik, @pietern, @shreyas-goenka, @simonfaltum, @renaudhartert-db, @janniklasrose, @lennartkats-db, @rugpanov, @rclarey) can approve all areas.
See OWNERS for ownership rules.

…e resources

Test coverage for the model_services, mcp_services, and
model_provider_services direct-engine bundle resources, all running offline
against the libs/testserver fakes:

- Acceptance tests (acceptance/bundle/resources/<r>/): a `basic` subtest
  (deploy -> summary -> read -> update comment in place -> plan a recreate on
  an immutable field -> destroy) and a `remote-delete` subtest (out-of-band
  delete -> plan detects drift). Pinned to the direct engine via
  EnvMatrix.DATABRICKS_BUNDLE_ENGINE = ["direct"] since these resources have no
  terraform converter (cf. genie_spaces).
- Invariant configs (acceptance/bundle/invariant/configs/*.yml.tmpl) wired into
  the invariant matrix; excluded from the cloud run (no routing target /
  provider / connection is provisioned there) and from the migrate test
  (direct-only resources can't be terraform-seeded), matching genie_space /
  cluster_policy.
- Bind/unbind tests (acceptance/bundle/deployment/bind/<r>/), with a [[Server]]
  GET stub so bind sees the remote resource.

The invariant no_drift test also confirms the resources.yml output-only /
secret suppression works: the model_provider_service's write-only
config.custom.direct.api_key.plaintext produces no post-deploy drift.

Co-authored-by: Isaac <no-reply@databricks.com>
@github-actions

Copy link
Copy Markdown
Contributor

An authorized user can trigger integration tests manually by following the instructions below:

Trigger:
go/deco-tests-run/cli

Inputs:

  • PR number: 6410
  • Commit SHA: 803cc5e7b518356e3ad7f8455889ca4ca5878658

Checks will be approved automatically on success.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants