forked from databricks/terraform-provider-databricks
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Added
databricks_service_principal_role
resource (databricks#1340)
This PR adds a new resource `databricks_service_principal_role` that grants Databricks Service Principals access to Databricks Instance Profiles. At the moment, this has to be done as a manual step via the Databricks UI. Similar attachment/pairing resources already exist for Databricks users (`databricks_user_instance_profile` superseded by `databricks_user_role`) and groups (`databricks_group_instance_profile`).
- Loading branch information
1 parent
44a683e
commit ec15230
Showing
5 changed files
with
227 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
package aws | ||
|
||
import ( | ||
"context" | ||
"fmt" | ||
|
||
"github.com/databrickslabs/terraform-provider-databricks/common" | ||
"github.com/databrickslabs/terraform-provider-databricks/scim" | ||
|
||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" | ||
) | ||
|
||
// ResourceServicePrincipalRole binds service principal and instance profile | ||
func ResourceServicePrincipalRole() *schema.Resource { | ||
r := common.NewPairID("service_principal_id", "role").BindResource(common.BindResource{ | ||
CreateContext: func(ctx context.Context, servicePrincipalID, role string, c *common.DatabricksClient) error { | ||
return scim.NewServicePrincipalsAPI(ctx, c).Patch(servicePrincipalID, scim.PatchRequest("add", "roles", role)) | ||
}, | ||
ReadContext: func(ctx context.Context, servicePrincipalID, roleARN string, c *common.DatabricksClient) error { | ||
servicePrincipal, err := scim.NewServicePrincipalsAPI(ctx, c).Read(servicePrincipalID) | ||
hasRole := scim.ComplexValues(servicePrincipal.Roles).HasValue(roleARN) | ||
if err == nil && !hasRole { | ||
return common.NotFound("Service Principal has no role") | ||
} | ||
return err | ||
}, | ||
DeleteContext: func(ctx context.Context, servicePrincipalID, roleARN string, c *common.DatabricksClient) error { | ||
return scim.NewServicePrincipalsAPI(ctx, c).Patch(servicePrincipalID, scim.PatchRequest( | ||
"remove", fmt.Sprintf(`roles[value eq "%s"]`, roleARN), "")) | ||
}, | ||
}) | ||
return r | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,134 @@ | ||
package aws | ||
|
||
import ( | ||
"github.com/databrickslabs/terraform-provider-databricks/common" | ||
"testing" | ||
|
||
"github.com/databrickslabs/terraform-provider-databricks/scim" | ||
|
||
"github.com/databrickslabs/terraform-provider-databricks/qa" | ||
) | ||
|
||
func TestResourceServicePrincipalRoleCreate(t *testing.T) { | ||
qa.ResourceFixture{ | ||
Fixtures: []qa.HTTPFixture{ | ||
{ | ||
Method: "PATCH", | ||
Resource: "/api/2.0/preview/scim/v2/ServicePrincipals/abc", | ||
ExpectedRequest: scim.PatchRequest( | ||
"add", | ||
"roles", | ||
"arn:aws:iam::999999999999:instance-profile/my-fake-instance-profile"), | ||
Response: scim.User{ | ||
ID: "abc", | ||
}, | ||
}, | ||
{ | ||
Method: "GET", | ||
Resource: "/api/2.0/preview/scim/v2/ServicePrincipals/abc", | ||
Response: scim.User{ | ||
Schemas: []scim.URN{scim.ServicePrincipalSchema}, | ||
DisplayName: "ABC SP", | ||
Roles: []scim.ComplexValue{ | ||
{ | ||
Value: "arn:aws:iam::999999999999:instance-profile/my-fake-instance-profile", | ||
}, | ||
}, | ||
ID: "abc", | ||
}, | ||
}, | ||
}, | ||
Resource: ResourceServicePrincipalRole(), | ||
State: map[string]interface{}{ | ||
"service_principal_id": "abc", | ||
"role": "arn:aws:iam::999999999999:instance-profile/my-fake-instance-profile", | ||
}, | ||
Create: true, | ||
}.ApplyAndExpectData(t, map[string]interface{}{"id": "abc|arn:aws:iam::999999999999:instance-profile/my-fake-instance-profile"}) | ||
} | ||
|
||
func TestResourceServicePrincipalRoleCreate_Error(t *testing.T) { | ||
qa.ResourceFixture{ | ||
Fixtures: []qa.HTTPFixture{ | ||
{ | ||
Method: "PATCH", | ||
Resource: "/api/2.0/preview/scim/v2/ServicePrincipals/abc", | ||
Response: common.APIErrorBody{ | ||
ErrorCode: "INVALID_REQUEST", | ||
Message: "Internal error happened", | ||
}, | ||
Status: 400, | ||
}, | ||
}, | ||
Resource: ResourceServicePrincipalRole(), | ||
State: map[string]interface{}{ | ||
"service_principal_id": "abc", | ||
"role": "arn:aws:iam::999999999999:instance-profile/my-fake-instance-profile", | ||
}, | ||
Create: true, | ||
}.ExpectError(t, "Internal error happened") | ||
} | ||
|
||
func TestResourceServicePrincipalRoleRead(t *testing.T) { | ||
qa.ResourceFixture{ | ||
Fixtures: []qa.HTTPFixture{ | ||
{ | ||
Method: "GET", | ||
Resource: "/api/2.0/preview/scim/v2/ServicePrincipals/abc", | ||
Response: scim.User{ | ||
Schemas: []scim.URN{scim.ServicePrincipalSchema}, | ||
DisplayName: "ABC SP", | ||
Roles: []scim.ComplexValue{ | ||
{ | ||
Value: "arn:aws:iam::999999999999:instance-profile/my-fake-instance-profile", | ||
}, | ||
}, | ||
ID: "abc", | ||
}, | ||
}, | ||
}, | ||
Resource: ResourceServicePrincipalRole(), | ||
Read: true, | ||
ID: "abc|arn:aws:iam::999999999999:instance-profile/my-fake-instance-profile", | ||
}.ApplyAndExpectData(t, map[string]interface{}{"id": "abc|arn:aws:iam::999999999999:instance-profile/my-fake-instance-profile"}) | ||
} | ||
|
||
func TestResourceServicePrincipalRoleRead_NoRole(t *testing.T) { | ||
qa.ResourceFixture{ | ||
Fixtures: []qa.HTTPFixture{ | ||
{ | ||
Method: "GET", | ||
Resource: "/api/2.0/preview/scim/v2/ServicePrincipals/abc", | ||
Response: scim.User{ | ||
Schemas: []scim.URN{scim.ServicePrincipalSchema}, | ||
DisplayName: "ABC SP", | ||
ID: "abc", | ||
}, | ||
}, | ||
}, | ||
Resource: ResourceServicePrincipalRole(), | ||
Read: true, | ||
Removed: true, | ||
ID: "abc|arn:aws:iam::999999999999:instance-profile/my-fake-instance-profile", | ||
}.ApplyNoError(t) | ||
} | ||
|
||
func TestResourceServicePrincipalRoleRead_NotFound(t *testing.T) { | ||
qa.ResourceFixture{ | ||
Fixtures: []qa.HTTPFixture{ | ||
{ | ||
Method: "GET", | ||
Resource: "/api/2.0/preview/scim/v2/ServicePrincipals/abc", | ||
Response: common.APIErrorBody{ | ||
ErrorCode: "NOT_FOUND", | ||
Message: "Item not found", | ||
}, | ||
Status: 404, | ||
}, | ||
}, | ||
Resource: ResourceServicePrincipalRole(), | ||
Read: true, | ||
Removed: true, | ||
ID: "abc|arn:aws:iam::999999999999:instance-profile/my-fake-instance-profile", | ||
}.ApplyNoError(t) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
--- | ||
subcategory: "Security" | ||
--- | ||
# databricks_service_principal_role Resource | ||
|
||
This resource allows you to attach a role or [databricks_instance_profile](instance_profile.md) (AWS) to a [databricks_service_principal](service_principal.md). | ||
|
||
## Example Usage | ||
|
||
Granting a service principal access to an instance profile | ||
|
||
```hcl | ||
resource "databricks_instance_profile" "instance_profile" { | ||
instance_profile_arn = "my_instance_profile_arn" | ||
} | ||
resource "databricks_service_principal" "this" { | ||
display_name = "My Service Principal" | ||
} | ||
resource "databricks_service_principal_role" "my_service_principal_instance_profile" { | ||
service_principal_id = databricks_service_principal.this.id | ||
role = databricks_instance_profile.instance_profile.id | ||
} | ||
``` | ||
## Argument Reference | ||
|
||
The following arguments are supported: | ||
|
||
* `service_principal_id` - (Required) This is the id of the [service principal](service_principal.md) resource. | ||
* `role` - (Required) This is the id of the role or [instance profile](instance_profile.md) resource. | ||
|
||
## Attribute Reference | ||
|
||
In addition to all arguments above, the following attributes are exported: | ||
|
||
* `id` - The id in the format `<service_principal_id>|<role>`. | ||
|
||
## Import | ||
|
||
-> **Note** Importing this resource is not currently supported. | ||
|
||
## Related Resources | ||
|
||
The following resources are often used in the same context: | ||
|
||
* [End to end workspace management](../guides/workspace-management.md) guide. | ||
* [databricks_user_role](user_instance_profile.md) to attach role or [databricks_instance_profile](instance_profile.md) (AWS) to [databricks_user](user.md). | ||
* [databricks_group_instance_profile](group_instance_profile.md) to attach [databricks_instance_profile](instance_profile.md) (AWS) to [databricks_group](group.md). | ||
* [databricks_group_member](group_member.md) to attach [users](user.md) and [groups](group.md) as group members. | ||
* [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). |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters