Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions NEXT_CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
* Added support for `databricks_data_quality_monitor` resource ([#5193](https://github.com/databricks/terraform-provider-databricks/pull/5193)).
* Fix typo in the name of environment variable ([#5158](https://github.com/databricks/terraform-provider-databricks/pull/5158)).
* Export permission assignments on workspace level ([#5169](https://github.com/databricks/terraform-provider-databricks/pull/5169)).
* Added support for UC Tag policies ([#5213](https://github.com/databricks/terraform-provider-databricks/pull/5213)).
* Added support for Databricks Apps resources ([#5208](https://github.com/databricks/terraform-provider-databricks/pull/5208)).

### Internal Changes
2 changes: 2 additions & 0 deletions docs/guides/experimental-exporter.md
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,7 @@ Services could be specified in combination with predefined aliases (`all` - for
* `uc-shares` - **listing** [databricks_share](../resources/share.md) and [databricks_recipient](../resources/recipient.md)
* `uc-storage-credentials` - **listing** exports [databricks_storage_credential](../resources/storage_credential.md) resources on workspace or account level.
* `uc-system-schemas` - **listing** exports [databricks_system_schema](../resources/system_schema.md) resources for the UC metastore of the current workspace.
* `uc-tags` - **listing** exports [databricks_tag_policy](../resources/tag_policy.md) resources.
* `uc-tables` - **listing** (*we can't list directly, only via dependencies to top-level object*) [databricks_sql_table](../resources/sql_table.md) resource.
* `uc-volumes` - **listing** (*we can't list directly, only via dependencies to top-level object*) [databricks_volume](../resources/volume.md)
* `users` - **listing** [databricks_user](../resources/user.md) and [databricks_service_principal](../resources/service_principal.md) are written to their own files, simply because of their number. If Identity Federation is enabled on the workspace (when UC Metastore is attached), then users and service principals are exposed as data sources because they are defined on an account level. See the note above on how to perform migration between workspaces with Identity Federation enabled.
Expand Down Expand Up @@ -313,6 +314,7 @@ Exporter aims to generate HCL code for most of the resources within the Databric
| [databricks_sql_widget](../resources/sql_widget.md) | Yes | Yes | Yes | No |
| [databricks_storage_credential](../resources/storage_credential.md) | Yes | Yes | Yes | No |
| [databricks_system_schema](../resources/system_schema.md) | Yes | No | Yes | No |
| [databricks_tag_policy](../resources/tag_policy.md) | Yes | No | Yes | No |
| [databricks_token](../resources/token.md) | Not Applicable | No | Yes | No |
| [databricks_user](../resources/user.md) | Yes | No | Yes | Yes |
| [databricks_user_instance_profile](../resources/user_instance_profile.md) | No | No | No | No |
Expand Down
10 changes: 10 additions & 0 deletions exporter/exporter_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import (
"github.com/databricks/databricks-sdk-go/service/settings"
"github.com/databricks/databricks-sdk-go/service/sharing"
sdk_sql "github.com/databricks/databricks-sdk-go/service/sql"
"github.com/databricks/databricks-sdk-go/service/tags"
sdk_vs "github.com/databricks/databricks-sdk-go/service/vectorsearch"
sdk_workspace "github.com/databricks/databricks-sdk-go/service/workspace"

Expand Down Expand Up @@ -311,6 +312,13 @@ var emptyConnections = qa.HTTPFixture{
Response: sdk_uc.ListConnectionsResponse{},
}

var emptyTagPolicies = qa.HTTPFixture{
Method: "GET",
Resource: "/api/2.1/tag-policies?",
Response: tags.ListTagPoliciesResponse{},
ReuseRequest: true,
}

var emptyRepos = qa.HTTPFixture{
Method: "GET",
ReuseRequest: true,
Expand Down Expand Up @@ -556,6 +564,7 @@ func TestImportingUsersGroupsSecretScopes(t *testing.T) {
emptyShares,
emptyDataQualityMonitors,
emptyConnections,
emptyTagPolicies,
emptyRecipients,
emptyGitCredentials,
emptyWorkspace,
Expand Down Expand Up @@ -835,6 +844,7 @@ func TestImportingNoResourcesError(t *testing.T) {
emptyUcCredentials,
emptyShares,
emptyConnections,
emptyTagPolicies,
emptyRecipients,
emptyModelServing,
emptyMlflowWebhooks,
Expand Down
24 changes: 24 additions & 0 deletions exporter/impl_uc.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (

"github.com/databricks/databricks-sdk-go/service/catalog"
"github.com/databricks/databricks-sdk-go/service/dataquality"
"github.com/databricks/databricks-sdk-go/service/tags"
tf_uc "github.com/databricks/terraform-provider-databricks/catalog"
"github.com/databricks/terraform-provider-databricks/common"
data_quality_monitor "github.com/databricks/terraform-provider-databricks/internal/providers/pluginfw/products/data_quality_monitor"
Expand Down Expand Up @@ -674,6 +675,29 @@ func listArtifactAllowLists(ic *importContext) error {
return nil
}

func listTagPolicies(ic *importContext) error {
tagPolicies, err := ic.workspaceClient.TagPolicies.ListTagPoliciesAll(ic.Context, tags.ListTagPoliciesRequest{})
if err != nil {
return err
}
i := 0
for _, tagPolicy := range tagPolicies {
i++
if !ic.MatchesName(tagPolicy.TagKey) {
continue
}
ic.Emit(&resource{
Resource: "databricks_tag_policy",
ID: tagPolicy.TagKey,
})
if i%50 == 0 {
log.Printf("[INFO] Imported %d Tag Policies", i)
}
}
log.Printf("[INFO] Listed %d Tag Policies", i)
return nil
}

func importSqlTable(ic *importContext, r *resource) error {
tableFullName := r.ID
ic.emitUCGrantsWithOwner("table/"+tableFullName, r)
Expand Down
88 changes: 88 additions & 0 deletions exporter/impl_uc_test.go
Original file line number Diff line number Diff line change
@@ -1,8 +1,14 @@
package exporter

import (
"context"
"fmt"
"os"
"testing"

"github.com/databricks/databricks-sdk-go/service/tags"
"github.com/databricks/terraform-provider-databricks/common"
"github.com/databricks/terraform-provider-databricks/qa"
"github.com/stretchr/testify/assert"
)

Expand All @@ -26,3 +32,85 @@ func TestEmitUserSpOrGroup(t *testing.T) {
assert.Contains(t, ic.testEmits, "databricks_group[<unknown>] (display_name: users @ test.com)")

}

func TestTagPolicyExport(t *testing.T) {
qa.HTTPFixturesApply(t, []qa.HTTPFixture{
meAdminFixture,
noCurrentMetastoreAttached,
{
Method: "GET",
Resource: "/api/2.1/tag-policies?",
Response: tags.ListTagPoliciesResponse{
TagPolicies: []tags.TagPolicy{
{
TagKey: "environment",
Description: "Environment tag policy",
Values: []tags.Value{
{Name: "dev"},
{Name: "staging"},
{Name: "production"},
},
},
{
TagKey: "team",
Description: "Team tag policy",
Values: []tags.Value{
{Name: "engineering"},
{Name: "data"},
},
},
},
},
},
{
Method: "GET",
Resource: "/api/2.1/tag-policies/environment?",
ReuseRequest: true,
Response: tags.TagPolicy{
TagKey: "environment",
Description: "Environment tag policy",
Values: []tags.Value{
{Name: "dev"},
{Name: "staging"},
{Name: "production"},
},
},
},
{
Method: "GET",
Resource: "/api/2.1/tag-policies/team?",
ReuseRequest: true,
Response: tags.TagPolicy{
TagKey: "team",
Description: "Team tag policy",
Values: []tags.Value{
{Name: "engineering"},
{Name: "data"},
},
},
},
}, func(ctx context.Context, client *common.DatabricksClient) {
tmpDir := fmt.Sprintf("/tmp/tf-%s", qa.RandomName())
defer os.RemoveAll(tmpDir)

ic := newImportContext(client)
ic.noFormat = true
ic.Directory = tmpDir
ic.enableListing("uc-tags")
ic.enableServices("uc-tags")

err := ic.Run()
assert.NoError(t, err)

content, err := os.ReadFile(tmpDir + "/uc-tags.tf")
assert.NoError(t, err)
contentStr := normalizeWhitespace(string(content))
assert.Contains(t, contentStr, `resource "databricks_tag_policy" "environment"`)
assert.Contains(t, contentStr, `resource "databricks_tag_policy" "team"`)
assert.Contains(t, contentStr, `tag_key = "environment"`)
assert.Contains(t, contentStr, `description = "Environment tag policy"`)
assert.Contains(t, contentStr, `name = "dev"`)
assert.Contains(t, contentStr, `name = "staging"`)
assert.Contains(t, contentStr, `name = "production"`)
})
}
8 changes: 8 additions & 0 deletions exporter/importables.go
Original file line number Diff line number Diff line change
Expand Up @@ -3350,4 +3350,12 @@ var resourcesMap map[string]importable = map[string]importable{
{Path: "alert_configurations.action_configurations.target", Resource: "databricks_user", Match: "user_name"},
},
},
"databricks_tag_policy": {
WorkspaceLevel: true,
PluginFramework: true,
Service: "uc-tags",
List: listTagPolicies,
// TODO: add import function that will emit access control rule set for the tag policy
// This requires knowing the account ID, so will be added later
},
}
Loading