Skip to content

Commit 3a10034

Browse files
nkvuongvickyzhu-db
andauthored
Add resources for configuring Serverless network connectivity (#3402)
* add `databricks_mws_network_connectivity_config` * add `mws_ncc_binding` resource * add `mws_ncc_private_endpoint_rule` * add doc * fix tests * add provider * add integration tests * force new * fix test * feedback * feedback * Update docs/resources/mws_ncc_private_endpoint_rule.md Co-authored-by: vickyzhu-db <[email protected]> * feedback * correct storage account * wrong id * more computed * feedback * new integration test helpers * GA on Azure --------- Co-authored-by: vickyzhu-db <[email protected]>
1 parent 3ebabb3 commit 3a10034

15 files changed

+869
-107
lines changed

access/resource_permission_assignment.go

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ package access
33
import (
44
"context"
55
"fmt"
6-
"strconv"
76

87
"github.com/databricks/databricks-sdk-go/apierr"
98
"github.com/databricks/terraform-provider-databricks/common"
@@ -65,14 +64,6 @@ func (a PermissionAssignmentAPI) List() (list PermissionAssignmentList, err erro
6564
return
6665
}
6766

68-
func mustInt64(s string) int64 {
69-
n, err := strconv.ParseInt(s, 10, 64)
70-
if err != nil {
71-
panic(err)
72-
}
73-
return n
74-
}
75-
7667
// ResourcePermissionAssignment performs of users to a workspace
7768
// from a workspace context, though it requires additional set
7869
// data resource for "workspace account scim", whicl will be added later.
@@ -101,7 +92,7 @@ func ResourcePermissionAssignment() common.Resource {
10192
return err
10293
}
10394
data := entity{
104-
PrincipalId: mustInt64(d.Id()),
95+
PrincipalId: common.MustInt64(d.Id()),
10596
}
10697
permissions, err := list.ForPrincipal(data.PrincipalId)
10798
if err != nil {

common/util.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"context"
55
"log"
66
"regexp"
7+
"strconv"
78
"strings"
89

910
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
@@ -34,3 +35,11 @@ func SuppressDiffWhitespaceChange(k, old, new string, d *schema.ResourceData) bo
3435
log.Printf("[DEBUG] Suppressing diff for %v: old=%#v new=%#v", k, old, new)
3536
return strings.TrimSpace(old) == strings.TrimSpace(new)
3637
}
38+
39+
func MustInt64(s string) int64 {
40+
n, err := strconv.ParseInt(s, 10, 64)
41+
if err != nil {
42+
panic(err)
43+
}
44+
return n
45+
}

common/util_test.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,3 +30,7 @@ func TestSuppressDiffWhitespaceChange(t *testing.T) {
3030
assert.True(t, SuppressDiffWhitespaceChange("k", "value", " value ", nil))
3131
assert.False(t, SuppressDiffWhitespaceChange("k", "value", "new_value", nil))
3232
}
33+
34+
func TestMustInt64(t *testing.T) {
35+
assert.Equal(t, int64(123), MustInt64("123"))
36+
}

docs/resources/mws_ncc_binding.md

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
---
2+
subcategory: "Deployment"
3+
---
4+
# databricks_mws_ncc_binding Resource
5+
6+
-> **Note** Initialize provider with `alias = "account"`, `host = "https://accounts.azuredatabricks.net"` and use `provider = databricks.account` for all `databricks_mws_*` resources.
7+
8+
-> **Public Preview** This feature is available for AWS & Azure only, and is in [Public Preview](https://docs.databricks.com/release-notes/release-types.html) in AWS.
9+
10+
Allows you to attach a [Network Connectivity Config](mws_network_connectivity_config) object to a [databricks_mws_workspaces](mws_workspaces.md) resource to create a [Databricks Workspace that leverages serverless network connectivity configs](https://learn.microsoft.com/en-us/azure/databricks/sql/admin/serverless-firewall).
11+
12+
The NCC and workspace must be in the same region.
13+
14+
## Example Usage
15+
16+
```hcl
17+
variable "region" {}
18+
variable "prefix" {}
19+
20+
resource "databricks_mws_network_connectivity_config" "ncc" {
21+
provider = databricks.account
22+
name = "Network Connectivity Config for ${var.prefix}"
23+
region = var.region
24+
}
25+
26+
resource "databricks_mws_ncc_binding" "ncc_binding" {
27+
provider = databricks.account
28+
network_connectivity_config_id = databricks_mws_network_connectivity_config.ncc.network_connectivity_config_id
29+
workspace_id = var.databricks_workspace_id
30+
}
31+
```
32+
33+
## Argument Reference
34+
35+
The following arguments are available:
36+
37+
* `network_connectivity_config_id` - Canonical unique identifier of Network Connectivity Config in Databricks Account.
38+
* `workspace_id` - Identifier of the workspace to attach the NCC to. Change forces creation of a new resource.
39+
40+
## Related Resources
41+
42+
The following resources are used in the context:
43+
44+
* [databricks_mws_workspaces](mws_workspaces.md) to set up Databricks workspaces.
45+
* [databricks_mws_network_connectivity_config](mws_network_connectivity_config.md) to create Network Connectivity Config objects.
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
---
2+
subcategory: "Deployment"
3+
---
4+
# databricks_mws_ncc_private_endpoint_rule Resource
5+
6+
-> **Note** Initialize provider with `alias = "account"`, `host = "https://accounts.azuredatabricks.net"` and use `provider = databricks.account` for all `databricks_mws_*` resources.
7+
8+
-> **Note** This feature is only available in Azure.
9+
10+
Allows you to create a private endpoint in a [Network Connectivity Config](mws_network_connectivity_config.md) that can be used to [configure private connectivity from serverless compute](https://learn.microsoft.com/en-us/azure/databricks/security/network/serverless-network-security/serverless-private-link).
11+
12+
## Example Usage
13+
14+
```hcl
15+
variable "region" {}
16+
variable "prefix" {}
17+
18+
resource "databricks_mws_network_connectivity_config" "ncc" {
19+
provider = databricks.account
20+
name = "Network Connectivity Config for ${var.prefix}"
21+
region = var.region
22+
}
23+
24+
resource "databricks_mws_ncc_private_endpoint_rule" "storage" {
25+
provider = databricks.account
26+
network_connectivity_config_id = databricks_mws_network_connectivity_config.ncc.network_connectivity_config_id
27+
resource_id = "/subscriptions/653bb673-1234-abcd-a90b-d064d5d53ca4/resourcegroups/example-resource-group/providers/Microsoft.Storage/storageAccounts/examplesa"
28+
group_id = "blob"
29+
}
30+
```
31+
32+
## Argument Reference
33+
34+
The following arguments are available:
35+
36+
* `network_connectivity_config_id` - Canonical unique identifier of Network Connectivity Config in Databricks Account. Change forces creation of a new resource.
37+
* `resource_id` - The Azure resource ID of the target resource. Change forces creation of a new resource.
38+
* `group_id` - The sub-resource type (group ID) of the target resource. Must be one of `blob`, `dfs`, `sqlServer` or `mysqlServer`. Note that to connect to workspace root storage (root DBFS), you need two endpoints, one for blob and one for dfs. Change forces creation of a new resource.
39+
40+
## Attribute Reference
41+
42+
In addition to all arguments above, the following attributes are exported:
43+
44+
* `rule_id`- the ID of a private endpoint rule.
45+
* `endpoint_name` - The name of the Azure private endpoint resource, e.g. "databricks-088781b3-77fa-4132-b429-1af0d91bc593-pe-3cb31234"
46+
* `connection_state` - The current status of this private endpoint. The private endpoint rules are effective only if the connection state is ESTABLISHED. Remember that you must approve new endpoints on your resources in the Azure portal before they take effect.
47+
The possible values are:
48+
* `PENDING`: The endpoint has been created and pending approval.
49+
* `ESTABLISHED`: The endpoint has been approved and is ready to be used in your serverless compute resources.
50+
* `REJECTED`: Connection was rejected by the private link resource owner.
51+
* `DISCONNECTED`: Connection was removed by the private link resource owner, the private endpoint becomes informative and should be deleted for clean-up.
52+
* `deactivated` - Whether this private endpoint is deactivated.
53+
* `deactivated_at` - Time in epoch milliseconds when this object was deactivated.
54+
* `creation_time` - Time in epoch milliseconds when this object was created.
55+
* `updated_time` - Time in epoch milliseconds when this object was updated.
56+
57+
## Import
58+
59+
This resource can be imported by Databricks account ID and Network Connectivity Config ID.
60+
61+
```sh
62+
terraform import databricks_mws_ncc_private_endpoint_rule.rule <network_connectivity_config_id>/<rule_id>
63+
```
64+
65+
## Related Resources
66+
67+
The following resources are used in the context:
68+
69+
* [databricks_mws_network_connectivity_config](mws_network_connectivity_config.md) to create Network Connectivity Config objects.
70+
* [databricks_mws_ncc_binding](mws_ncc_binding.md) to attach an NCC to a workspace.
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
---
2+
subcategory: "Deployment"
3+
---
4+
# databricks_mws_network_connectivity_config Resource
5+
6+
-> **Note** Initialize provider with `alias = "account"`, `host = "https://accounts.azuredatabricks.net"` and use `provider = databricks.account` for all `databricks_mws_*` resources.
7+
8+
-> **Public Preview** This feature is available for AWS & Azure only, and is in [Public Preview](https://docs.databricks.com/release-notes/release-types.html) in AWS.
9+
10+
Allows you to create a [Network Connectivity Config] that can be used as part of a [databricks_mws_workspaces](mws_workspaces.md) resource to create a [Databricks Workspace that leverages serverless network connectivity configs](https://learn.microsoft.com/en-us/azure/databricks/security/network/serverless-network-security/serverless-firewall).
11+
12+
## Example Usage
13+
14+
```hcl
15+
variable "region" {}
16+
variable "prefix" {}
17+
18+
resource "databricks_mws_network_connectivity_config" "ncc" {
19+
provider = databricks.account
20+
name = "Network Connectivity Config for ${var.prefix}"
21+
region = var.region
22+
}
23+
24+
resource "databricks_mws_ncc_binding" "ncc_binding" {
25+
provider = databricks.account
26+
network_connectivity_config_id = databricks_mws_network_connectivity_config.ncc.network_connectivity_config_id
27+
workspace_id = var.databricks_workspace_id
28+
}
29+
```
30+
31+
## Argument Reference
32+
33+
The following arguments are available:
34+
35+
* `name` - Name of Network Connectivity Config in Databricks Account. Change forces creation of a new resource.
36+
* `region` - Region of the Network Connectivity Config. NCCs can only be referenced by your workspaces in the same region. Change forces creation of a new resource.
37+
38+
## Attribute Reference
39+
40+
In addition to all arguments above, the following attributes are exported:
41+
42+
* `network_connectivity_config_id` - Canonical unique identifier of Network Connectivity Config in Databricks Account
43+
* `default_rules.azure_service_endpoint_rule` - This provides a list of subnets. These subnets need to be allowed in your Azure resources in order for Databricks to access. See `default_rules.azure_service_endpoint_rule.target_services` for the supported Azure services.
44+
45+
## Import
46+
47+
This resource can be imported by Databricks account ID and Network Connectivity Config ID.
48+
49+
```sh
50+
terraform import databricks_mws_network_connectivity_config.ncc <account_id>/<network_connectivity_config_id>
51+
```
52+
53+
## Related Resources
54+
55+
The following resources are used in the context:
56+
57+
* [databricks_mws_workspaces](mws_workspaces.md) to set up Databricks workspaces.
58+
* [databricks_mws_ncc_binding](mws_ncc_binding.md) to attach an NCC to a workspace.
59+
* [databricks_mws_ncc_private_endpoint_rule](mws_ncc_private_endpoint_rule.md) to create a private endpoint rule.
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
package acceptance
2+
3+
import (
4+
"testing"
5+
)
6+
7+
func TestMwsAccNetworkConnectivityConfig(t *testing.T) {
8+
if isAzure(t) {
9+
accountLevel(t, step{
10+
Template: `
11+
resource "databricks_mws_network_connectivity_config" "this" {
12+
name = "tf-{var.RANDOM}"
13+
region = "eastus2"
14+
}
15+
16+
resource "databricks_mws_ncc_private_endpoint_rule" "this" {
17+
network_connectivity_config_id = databricks_mws_network_connectivity_config.this.network_connectivity_config_id
18+
resource_id = "/subscriptions/2a5a4578-9ca9-47e2-ba46-f6ee6cc731f2/resourceGroups/deco-prod-azure-eastus2-rg/providers/Microsoft.Storage/storageAccounts/decotestprodunity"
19+
group_id = "blob"
20+
}
21+
`,
22+
}, step{
23+
Template: `
24+
resource "databricks_mws_network_connectivity_config" "this" {
25+
name = "tf-{var.RANDOM}"
26+
region = "eastus2"
27+
}
28+
29+
resource "databricks_mws_ncc_private_endpoint_rule" "this" {
30+
network_connectivity_config_id = databricks_mws_network_connectivity_config.this.network_connectivity_config_id
31+
resource_id = "/subscriptions/2a5a4578-9ca9-47e2-ba46-f6ee6cc731f2/resourceGroups/deco-prod-azure-eastus2-rg/providers/Microsoft.Storage/storageAccounts/decotestprodunity"
32+
group_id = "blob"
33+
}
34+
`,
35+
})
36+
}
37+
if isAws(t) {
38+
accountLevel(t, step{
39+
Template: `
40+
resource "databricks_mws_network_connectivity_config" "this" {
41+
account_id = "{env.DATABRICKS_ACCOUNT_ID}"
42+
name = "tf-{var.RANDOM}"
43+
region = "{env.AWS_REGION}"
44+
}
45+
`,
46+
}, step{
47+
Template: `
48+
resource "databricks_mws_network_connectivity_config" "this" {
49+
account_id = "{env.DATABRICKS_ACCOUNT_ID}"
50+
name = "tf-{var.RANDOM}"
51+
region = "{env.AWS_REGION}"
52+
}
53+
`,
54+
})
55+
}
56+
}

mws/resource_mws_ncc_binding.go

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
package mws
2+
3+
import (
4+
"context"
5+
"log"
6+
7+
"github.com/databricks/databricks-sdk-go/service/provisioning"
8+
"github.com/databricks/terraform-provider-databricks/common"
9+
10+
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
11+
)
12+
13+
func ResourceMwsNccBinding() common.Resource {
14+
type binding struct {
15+
WorkspaceId int64 `json:"workspace_id" tf:"force_new"`
16+
NccId string `json:"network_connectivity_config_id"`
17+
}
18+
s := common.StructToSchema(binding{}, common.NoCustomize)
19+
p := common.NewPairSeparatedID("workspace_id", "network_connectivity_config_id", "/")
20+
createOrUpdate := func(ctx context.Context, d *schema.ResourceData, c *common.DatabricksClient) error {
21+
acc, err := c.AccountClient()
22+
if err != nil {
23+
return err
24+
}
25+
wait, err := acc.Workspaces.Update(ctx, provisioning.UpdateWorkspaceRequest{
26+
NetworkConnectivityConfigId: d.Get("network_connectivity_config_id").(string),
27+
WorkspaceId: int64(d.Get("workspace_id").(int)),
28+
})
29+
if err != nil {
30+
return err
31+
}
32+
_, err = wait.Get()
33+
if err != nil {
34+
return err
35+
}
36+
p.Pack(d)
37+
return nil
38+
}
39+
return common.Resource{
40+
Schema: s,
41+
Create: createOrUpdate,
42+
Read: func(ctx context.Context, d *schema.ResourceData, c *common.DatabricksClient) error {
43+
if d.IsNewResource() {
44+
log.Print("[WARN] Importing NCC binding is not supported, skipping...")
45+
}
46+
return nil
47+
},
48+
Update: createOrUpdate,
49+
Delete: func(ctx context.Context, d *schema.ResourceData, c *common.DatabricksClient) error {
50+
log.Printf("[WARN] Cannot remove network connectivity config binding, only update is supported.")
51+
return nil
52+
},
53+
}
54+
}

0 commit comments

Comments
 (0)