Skip to content

Commit e2b4c1b

Browse files
authored
Added databricks_user_role resource (#1054)
* Added `databricks_user_role` resource Adding AWS instance profile to a user ```hcl resource "databricks_instance_profile" "instance_profile" { instance_profile_arn = "my_instance_profile_arn" } resource "databricks_user" "my_user" { user_name = "[email protected]" } resource "databricks_user_role" "my_user_role" { user_id = databricks_user.my_user.id role = databricks_instance_profile.instance_profile.id } ``` Adding user as administrator to Databricks Account ```hcl provider "databricks" { host = "https://accounts.cloud.databricks.com" account_id = var.databricks_account_id username = var.databricks_user password = var.databricks_password } resource "databricks_user" "my_user" { user_name = "[email protected]" } resource "databricks_user_role" "my_user_account_admin" { user_id = databricks_user.my_user.id role = "account_admin" } ``` * whoopsie * remove unused * typo
1 parent ff3d6a1 commit e2b4c1b

File tree

9 files changed

+148
-4
lines changed

9 files changed

+148
-4
lines changed

CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,11 @@
44

55
* Clarified error messages around `azure_workspace_resource_id` provider configuration ([#1049](https://github.com/databrickslabs/terraform-provider-databricks/issues/1049)).
66
* Added optional `force` argument to `databricks_user` resource to ignore `cannot create user: User with username X already exists` errors and implicitly import the specific user into Terraform state, enforcing entitlements defined in the instance of resource ([#1048](https://github.com/databrickslabs/terraform-provider-databricks/pull/1048)).
7+
* Added `databricks_user_role` resource, that can assign roles on Databricks Account or `databricks_instance_profile` for data access ([#1047](https://github.com/databrickslabs/terraform-provider-databricks/pull/1047)).
8+
9+
**Deprecations**
10+
11+
* `databricks_user_instance_profile` is deprecated in favor of `databricks_user_role`.
712

813
Updated dependency versions:
914

aws/resource_user_instance_profile.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import (
1212

1313
// ResourceUserInstanceProfile binds user and instance profile
1414
func ResourceUserInstanceProfile() *schema.Resource {
15-
return common.NewPairID("user_id", "instance_profile_id").Schema(func(
15+
r := common.NewPairID("user_id", "instance_profile_id").Schema(func(
1616
m map[string]*schema.Schema) map[string]*schema.Schema {
1717
m["instance_profile_id"].ValidateDiagFunc = ValidInstanceProfile
1818
return m
@@ -33,4 +33,6 @@ func ResourceUserInstanceProfile() *schema.Resource {
3333
"remove", fmt.Sprintf(`roles[value eq "%s"]`, roleARN), ""))
3434
},
3535
})
36+
r.DeprecationMessage = "Please migrate to `databricks_user_role`. This resource will be removed in v0.5.x"
37+
return r
3638
}

aws/resource_user_instance_profile_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ func TestResourceUserInstanceProfileCreate_Error_BadARN(t *testing.T) {
5959
},
6060
Create: true,
6161
}.Apply(t)
62-
assert.EqualError(t, err, "invalid config supplied. [instance_profile_id] Invalid ARN")
62+
assert.EqualError(t, err, "invalid config supplied. [instance_profile_id] Invalid ARN. Deprecated Resource")
6363
}
6464

6565
func TestResourceUserInstanceProfileCreate_Error(t *testing.T) {

aws/resource_user_role.go

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
package aws
2+
3+
import (
4+
"context"
5+
"fmt"
6+
7+
"github.com/databrickslabs/terraform-provider-databricks/common"
8+
"github.com/databrickslabs/terraform-provider-databricks/scim"
9+
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
10+
)
11+
12+
func ResourceUserRole() *schema.Resource {
13+
return common.NewPairID("user_id", "role").BindResource(common.BindResource{
14+
CreateContext: func(ctx context.Context, userID, role string, c *common.DatabricksClient) error {
15+
return scim.NewUsersAPI(ctx, c).Patch(userID, scim.PatchRequest("add", "roles", role))
16+
},
17+
ReadContext: func(ctx context.Context, userID, roleARN string, c *common.DatabricksClient) error {
18+
user, err := scim.NewUsersAPI(ctx, c).Read(userID)
19+
hasRole := scim.ComplexValues(user.Roles).HasValue(roleARN)
20+
if err == nil && !hasRole {
21+
return common.NotFound("User has no role")
22+
}
23+
return err
24+
},
25+
DeleteContext: func(ctx context.Context, userID, roleARN string, c *common.DatabricksClient) error {
26+
return scim.NewUsersAPI(ctx, c).Patch(userID, scim.PatchRequest(
27+
"remove", fmt.Sprintf(`roles[value eq "%s"]`, roleARN), ""))
28+
},
29+
})
30+
}

aws/resource_user_role_test.go

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
package aws
2+
3+
import (
4+
"testing"
5+
6+
"github.com/databrickslabs/terraform-provider-databricks/qa"
7+
"github.com/databrickslabs/terraform-provider-databricks/scim"
8+
)
9+
10+
func TestUserRoleCornerCases(t *testing.T) {
11+
qa.ResourceCornerCases(t, ResourceUserRole(),
12+
qa.CornerCaseID("a|b"),
13+
qa.CornerCaseSkipCRUD("create"))
14+
}
15+
16+
func TestUserRoleCreate_AndGetResourceDrift(t *testing.T) {
17+
qa.ResourceFixture{
18+
Fixtures: []qa.HTTPFixture{
19+
{
20+
Method: "PATCH",
21+
Resource: "/api/2.0/preview/scim/v2/Users/a",
22+
ExpectedRequest: scim.PatchRequest("add", "roles", "b"),
23+
},
24+
{
25+
Method: "GET",
26+
Resource: "/api/2.0/preview/scim/v2/Users/a",
27+
Response: scim.User{},
28+
},
29+
},
30+
Create: true,
31+
Resource: ResourceUserRole(),
32+
HCL: `
33+
user_id = "a"
34+
role = "b"
35+
`,
36+
}.ExpectError(t, "User has no role")
37+
}

docs/resources/user_instance_profile.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ subcategory: "Security"
33
---
44
# databricks_user_instance_profile Resource
55

6-
-> **Note** This resource has an evolving API, which may change in future versions of the provider.
6+
-> **Deprecated** Please rewrite with [databricks_user_role](user_role.md). This resource will be removed in v0.5.x
77

88
This resource allows you to attach [databricks_instance_profile](instance_profile.md) (AWS) to [databricks_user](user.md).
99

docs/resources/user_role.md

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
---
2+
subcategory: "Security"
3+
---
4+
# databricks_user_role Resource
5+
6+
This resource allows you to attach a role or [databricks_instance_profile](instance_profile.md) (AWS) to [databricks_user](user.md).
7+
8+
## Example Usage
9+
10+
Adding AWS instance profile to a user
11+
12+
```hcl
13+
resource "databricks_instance_profile" "instance_profile" {
14+
instance_profile_arn = "my_instance_profile_arn"
15+
}
16+
17+
resource "databricks_user" "my_user" {
18+
user_name = "[email protected]"
19+
}
20+
21+
resource "databricks_user_role" "my_user_role" {
22+
user_id = databricks_user.my_user.id
23+
role = databricks_instance_profile.instance_profile.id
24+
}
25+
```
26+
27+
Adding user as administrator to Databricks Account
28+
29+
```hcl
30+
provider "databricks" {
31+
host = "https://accounts.cloud.databricks.com"
32+
account_id = var.databricks_account_id
33+
username = var.databricks_user
34+
password = var.databricks_password
35+
}
36+
37+
resource "databricks_user" "my_user" {
38+
user_name = "[email protected]"
39+
}
40+
41+
resource "databricks_user_role" "my_user_account_admin" {
42+
user_id = databricks_user.my_user.id
43+
role = "account_admin"
44+
}
45+
```
46+
47+
## Argument Reference
48+
49+
The following arguments are supported:
50+
51+
* `user_id` - (Required) This is the id of the [user](user.md) resource.
52+
* `role` - (Required) Either a role name or the id of the [instance profile](instance_profile.md) resource.
53+
54+
## Attribute Reference
55+
56+
In addition to all arguments above, the following attributes are exported:
57+
58+
* `id` - The id in the format `<user_id>|<role>`.
59+
60+
## Related Resources
61+
62+
The following resources are often used in the same context:
63+
64+
* [End to end workspace management](../guides/workspace-management.md) guide.
65+
* [databricks_group_instance_profile](group_instance_profile.md) to attach [databricks_instance_profile](instance_profile.md) (AWS) to [databricks_group](group.md).
66+
* [databricks_group_member](group_member.md) to attach [users](user.md) and [groups](group.md) as group members.
67+
* [databricks_instance_profile](instance_profile.md) to manage AWS EC2 instance profiles that users can launch [databricks_cluster](cluster.md) and access data, like [databricks_mount](mount.md).
68+
* [databricks_user](user.md) to [manage users](https://docs.databricks.com/administration-guide/users-groups/users.html), that could be added to [databricks_group](group.md) within the workspace.
69+
* [databricks_user](../data-sources/user.md) data to retrieves information about [databricks_user](user.md).

provider/provider.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,7 @@ func DatabricksProvider() *schema.Provider {
108108
"databricks_token": tokens.ResourceToken(),
109109
"databricks_user": scim.ResourceUser(),
110110
"databricks_user_instance_profile": aws.ResourceUserInstanceProfile(),
111+
"databricks_user_role": aws.ResourceUserRole(),
111112
"databricks_workspace_conf": workspace.ResourceWorkspaceConf(),
112113
},
113114
Schema: providerSchema(),

qa/testing.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -333,7 +333,7 @@ func ResourceCornerCases(t *testing.T, resource *schema.Resource, cc ...CornerCa
333333
}
334334
diags := v(ctx, validData, client)
335335
if assert.Len(t, diags, 1) {
336-
assert.Equalf(t, diags[0].Summary, config["expect_error"],
336+
assert.Equalf(t, config["expect_error"], diags[0].Summary,
337337
"%s didn't handle correct error on valid data", n)
338338
}
339339
}

0 commit comments

Comments
 (0)