Skip to content

Commit 7c9072e

Browse files
Added databricks_model_serving support to databricks_permissions (#2331)
* Add model serving support to `databricks_permissions` To support permissions assignment we also need to expose a new attribute with internal ID of the model serving endpoint. * Update docs/resources/model_serving.md Co-authored-by: Arpit Jasapara <[email protected]> * Update docs/resources/model_serving.md Co-authored-by: Arpit Jasapara <[email protected]> --------- Co-authored-by: Arpit Jasapara <[email protected]>
1 parent d7e401d commit 7c9072e

File tree

5 files changed

+83
-2
lines changed

5 files changed

+83
-2
lines changed

docs/resources/model_serving.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,17 @@ The following arguments are supported:
6868
* `served_model_name` - (Required) The name of the served model this route configures traffic for. This needs to match the name of a `served_models` block
6969
* `traffic_percentage` - (Required) The percentage of endpoint traffic to send to this route. It must be an integer between 0 and 100 inclusive.
7070

71+
## Attribute Reference
72+
73+
In addition to all arguments above, the following attributes are exported:
74+
75+
* `id` - Equal to the `name` argument and used to identify the serving endpoint.
76+
* `serving_endpoint_id` - Unique identifier of the serving endpoint primarily used to set permissions and refer to this instance for other operations.
77+
78+
## Access Control
79+
80+
* [databricks_permissions](permissions.md#model-serving-usage) can control which groups or individual users can *Manage*, *Query* or *View* individual serving endpoints.
81+
7182
## Timeouts
7283

7384
The `timeouts` block allows you to specify `create` and `update` timeouts. The default right now is 45 minutes for both operations.

docs/resources/permissions.md

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -517,6 +517,52 @@ resource "databricks_permissions" "model_usage" {
517517
}
518518
```
519519

520+
## Model serving usage
521+
522+
Valid permission levels for [databricks_model_serving](model_serving.md) are: `CAN_VIEW`, `CAN_QUERY`, and `CAN_MANAGE`.
523+
524+
```hcl
525+
resource "databricks_model_serving" "this" {
526+
name = "tf-test"
527+
config {
528+
served_models {
529+
name = "prod_model"
530+
model_name = "test"
531+
model_version = "1"
532+
workload_size = "Small"
533+
scale_to_zero_enabled = true
534+
}
535+
}
536+
}
537+
538+
resource "databricks_group" "auto" {
539+
display_name = "Automation"
540+
}
541+
542+
resource "databricks_group" "eng" {
543+
display_name = "Engineering"
544+
}
545+
546+
resource "databricks_permissions" "ml_serving_usage" {
547+
serving_endpoint_id = databricks_model_serving.this.serving_endpoint_id
548+
549+
access_control {
550+
group_name = "users"
551+
permission_level = "CAN_VIEW"
552+
}
553+
554+
access_control {
555+
group_name = databricks_group.auto.display_name
556+
permission_level = "CAN_MANAGE"
557+
}
558+
559+
access_control {
560+
group_name = databricks_group.eng.display_name
561+
permission_level = "CAN_QUERY"
562+
}
563+
}
564+
```
565+
520566
## Passwords usage
521567

522568
By default on AWS deployments, all admin users can sign in to Databricks using either SSO or their username and password, and all API users can authenticate to the Databricks REST APIs using their username and password. As an admin, you [can limit](https://docs.databricks.com/administration-guide/users-groups/single-sign-on/index.html#optional-configure-password-access-control) admin users’ and API users’ ability to authenticate with their username and password by configuring `CAN_USE` permissions using password access control.
@@ -734,6 +780,7 @@ Exactly one of the following arguments is required:
734780
- `repo_path` - path of databricks repo directory(`/Repos/<username>/...`)
735781
- `experiment_id` - [MLflow experiment](mlflow_experiment.md) id
736782
- `registered_model_id` - [MLflow registered model](mlflow_model.md) id
783+
- `serving_endpoint_id` - [Model Serving](model_serving.md) endpoint id.
737784
- `authorization` - either [`tokens`](https://docs.databricks.com/administration-guide/access-control/tokens.html) or [`passwords`](https://docs.databricks.com/administration-guide/users-groups/single-sign-on/index.html#configure-password-permission).
738785
- `sql_endpoint_id` - [SQL warehouse](sql_endpoint.md) id
739786
- `sql_dashboard_id` - [SQL dashboard](sql_dashboard.md) id

internal/acceptance/model_serving_test.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,15 @@ func TestAccModelServing(t *testing.T) {
122122
}
123123
}
124124
}
125+
126+
resource "databricks_permissions" "ml_serving_usage" {
127+
serving_endpoint_id = databricks_model_serving.endpoint.serving_endpoint_id
128+
129+
access_control {
130+
group_name = "users"
131+
permission_level = "CAN_VIEW"
132+
}
133+
}
125134
`, name),
126135
},
127136
step{

permissions/resource_permissions.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,7 @@ func urlPathForObjectID(objectID string) string {
124124
// permissions when POSTing permissions changes through the REST API, to avoid accidentally
125125
// revoking the calling user's ability to manage the current object.
126126
func (a PermissionsAPI) shouldExplicitlyGrantCallingUserManagePermissions(objectID string) bool {
127-
for _, prefix := range [...]string{"/registered-models/", "/clusters/", "/instance-pools/", "/queries/", "/sql/warehouses"} {
127+
for _, prefix := range [...]string{"/registered-models/", "/clusters/", "/instance-pools/", "/serving-endpoints/", "/queries/", "/sql/warehouses"} {
128128
if strings.HasPrefix(objectID, prefix) {
129129
return true
130130
}
@@ -309,6 +309,7 @@ func permissionsResourceIDFields() []permissionsIDFieldMapping {
309309
{"experiment_id", "mlflowExperiment", "experiments", []string{"CAN_READ", "CAN_EDIT", "CAN_MANAGE"}, SIMPLE},
310310
{"registered_model_id", "registered-model", "registered-models", []string{
311311
"CAN_READ", "CAN_EDIT", "CAN_MANAGE_STAGING_VERSIONS", "CAN_MANAGE_PRODUCTION_VERSIONS", "CAN_MANAGE"}, SIMPLE},
312+
{"serving_endpoint_id", "serving-endpoint", "serving-endpoints", []string{"CAN_VIEW", "CAN_QUERY", "CAN_MANAGE"}, SIMPLE},
312313
}
313314
}
314315

serving/resource_model_serving.go

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,14 @@ func ResourceModelServing() *schema.Resource {
2121
common.MustSchemaPath(m, "config", "served_models", "scale_to_zero_enabled").Optional = true
2222
common.MustSchemaPath(m, "config", "served_models", "scale_to_zero_enabled").Default = true
2323
common.MustSchemaPath(m, "config", "served_models", "name").Computed = true
24+
25+
common.MustSchemaPath(m, "config", "traffic_config").Computed = true
26+
27+
m["serving_endpoint_id"] = &schema.Schema{
28+
Computed: true,
29+
Type: schema.TypeString,
30+
}
31+
2432
return m
2533
})
2634

@@ -48,7 +56,12 @@ func ResourceModelServing() *schema.Resource {
4856
if err != nil {
4957
return err
5058
}
51-
return common.StructToData(*endpoint, s, d)
59+
err = common.StructToData(*endpoint, s, d)
60+
if err != nil {
61+
return err
62+
}
63+
d.Set("serving_endpoint_id", endpoint.Id)
64+
return nil
5265
},
5366
Update: func(ctx context.Context, d *schema.ResourceData, c *common.DatabricksClient) error {
5467
w, err := c.WorkspaceClient()

0 commit comments

Comments
 (0)