Skip to content

Commit 31496df

Browse files
committed
feat: add module
1 parent 8f11438 commit 31496df

File tree

5 files changed

+241
-0
lines changed

5 files changed

+241
-0
lines changed

iam.tf

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
data "databricks_group" "admins" {
2+
display_name = "admins"
3+
}
4+
5+
resource "databricks_group" "this" {
6+
for_each = toset([for group in keys(var.iam) : group if group != "admins"])
7+
8+
display_name = each.key
9+
lifecycle { ignore_changes = [external_id] }
10+
}
11+
12+
resource "databricks_user" "this" {
13+
for_each = toset(flatten([for k, v in { for group, member in var.iam : group => member["user"] } : distinct(flatten(v))]))
14+
15+
user_name = each.value
16+
databricks_sql_access = true
17+
lifecycle { ignore_changes = [external_id] }
18+
}
19+
20+
resource "databricks_service_principal" "this" {
21+
for_each = toset(flatten([for k, v in { for group, member in var.iam : group => member["service_principal"] } : distinct(flatten(v))]))
22+
23+
display_name = each.value
24+
application_id = lookup(var.user_object_ids, each.value)
25+
databricks_sql_access = true
26+
}
27+
28+
resource "databricks_group_member" "admin_users" {
29+
for_each = { for entry in flatten([for group, types in var.iam : [for type in types : [for member in type : {
30+
group = group, member = member
31+
} if group == "admins" && type == types["user"]]]]) : "${entry.group}.${entry.member}" => entry }
32+
33+
group_id = data.databricks_group.admins.id
34+
member_id = databricks_user.this[each.value.member].id
35+
}
36+
37+
resource "databricks_group_member" "admin_service_principals" {
38+
for_each = { for entry in flatten([for group, types in var.iam : [for type in types : [for member in type : {
39+
group = group, member = member
40+
} if group == "admins" && type == types["service_principal"]]]]) : "${entry.group}.${entry.member}" => entry }
41+
42+
group_id = data.databricks_group.admins.id
43+
member_id = databricks_service_principal.this[each.value.member].id
44+
}
45+
46+
resource "databricks_group_member" "users" {
47+
for_each = { for entry in flatten([for group, types in var.iam : [for type in types : [for member in type : {
48+
group = group, member = member
49+
} if group != "admins" && group != "users" && type == types["user"]]]]) : "${entry.group}.${entry.member}" => entry }
50+
51+
group_id = databricks_group.this[each.value.group].id
52+
member_id = databricks_user.this[each.value.member].id
53+
}
54+
55+
resource "databricks_group_member" "service_principals" {
56+
for_each = { for entry in flatten([for group, types in var.iam : [for type in types : [for member in type : {
57+
group = group, member = member
58+
} if group != "admins" && group != "users" && type == types["service_principal"]]]]) : "${entry.group}.${entry.member}" => entry }
59+
60+
group_id = databricks_group.this[each.value.group].id
61+
member_id = databricks_service_principal.this[each.value.member].id
62+
}
63+
64+
resource "databricks_permissions" "sql_endpoint" {
65+
for_each = { for entry in databricks_sql_endpoint.this : "${entry.name}" => "${entry.id}" }
66+
67+
sql_endpoint_id = each.value
68+
69+
dynamic "access_control" {
70+
for_each = { for entry in flatten([for resource, permissions in var.iam_permissions : [for permission, groups in permissions : [for group in groups : {
71+
resource = resource, permission = permission, group = group
72+
} if resource == "sql_endpoint"]]]) : "${entry.resource}.${entry.permission}.${entry.group}" => entry }
73+
content {
74+
group_name = access_control.value.group
75+
permission_level = access_control.value.permission
76+
}
77+
}
78+
79+
depends_on = [databricks_group.this]
80+
}
81+
82+
resource "databricks_permissions" "token" {
83+
authorization = "tokens"
84+
85+
dynamic "access_control" {
86+
for_each = { for entry in flatten([for resource, permissions in var.iam_permissions : [for permission, groups in permissions : [for group in groups : {
87+
resource = resource, permission = permission, group = group
88+
} if resource == "token"]]]) : "${entry.resource}.${entry.permission}.${entry.group}" => entry }
89+
content {
90+
group_name = access_control.value.group
91+
permission_level = access_control.value.permission
92+
}
93+
}
94+
depends_on = [databricks_group.this]
95+
}

main.tf

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
locals {
2+
ip_rules = var.ip_rules == null ? null : values(var.ip_rules)
3+
}
4+
5+
resource "databricks_workspace_conf" "this" {
6+
count = local.ip_rules == null ? 0 : 1
7+
8+
custom_config = {
9+
"enableIpAccessLists" : true
10+
}
11+
}
12+
13+
resource "databricks_ip_access_list" "this" {
14+
count = local.ip_rules == null ? 0 : 1
15+
16+
label = "allow_in"
17+
list_type = "ALLOW"
18+
ip_addresses = local.ip_rules
19+
20+
depends_on = [databricks_workspace_conf.this]
21+
}
22+
23+
resource "databricks_sql_endpoint" "this" {
24+
for_each = var.sql_endpoint
25+
26+
name = "${each.key}-${var.env}"
27+
cluster_size = lookup(each.value, "cluster_size", var.default_values_sql_endpoint["cluster_size"])
28+
min_num_clusters = lookup(each.value, "min_num_clusters", var.default_values_sql_endpoint["min_num_clusters"])
29+
max_num_clusters = lookup(each.value, "max_num_clusters", var.default_values_sql_endpoint["max_num_clusters"])
30+
auto_stop_mins = lookup(each.value, "auto_stop_mins", var.default_values_sql_endpoint["auto_stop_mins"])
31+
enable_photon = lookup(each.value, "enable_photon", var.default_values_sql_endpoint["enable_photon"])
32+
enable_serverless_compute = lookup(each.value, "enable_serverless_compute", var.default_values_sql_endpoint["enable_serverless_compute"])
33+
}

outputs.tf

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
output "sql_endpoint_jdbc_url" {
2+
value = [for n in databricks_sql_endpoint.this : n.jdbc_url]
3+
description = "JDBC connection string of SQL Endpoint"
4+
}
5+
6+
output "sql_endpoint_data_source_id" {
7+
value = [for n in databricks_sql_endpoint.this : n.data_source_id]
8+
description = "ID of the data source for this endpoint"
9+
}

variables.tf

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
variable "env" {
2+
type = string
3+
description = "Environment name"
4+
}
5+
6+
variable "project" {
7+
type = string
8+
description = "Project name"
9+
}
10+
11+
variable "workspace_id" {
12+
type = string
13+
description = "Id of Databricks workspace"
14+
}
15+
16+
variable "sku" {
17+
type = string
18+
description = "The sku to use for the Databricks Workspace: [standard|premium|trial]"
19+
}
20+
21+
# Optional
22+
variable "user_object_ids" {
23+
type = map(string)
24+
description = "Map of AD usernames and corresponding object IDs"
25+
default = {}
26+
}
27+
28+
variable "iam" {
29+
type = map(object({
30+
user = list(string)
31+
service_principal = list(string)
32+
}))
33+
description = "Map of groups and members of users and service principals to be created. You can add you own groups and members. E.g., `'group' = { user = ['user1','user2'] service_principal = ['sp1']}` and etc."
34+
default = {
35+
"admins" = {
36+
"user" = []
37+
"service_principal" = []
38+
}
39+
"default" = {
40+
"user" = []
41+
"service_principal" = []
42+
}
43+
}
44+
}
45+
46+
variable "iam_permissions" {
47+
type = map(object({
48+
CAN_USE = list(string)
49+
CAN_MANAGE = list(string)
50+
}))
51+
description = "Map of permission for groups. You can provide certain permission on services to groups. E.g., `'sql_endpoint'={'CAN_USE'=['group1', 'group2'] CAN_MANAGE=['group3']}"
52+
default = {
53+
"sql_endpoint" = {
54+
"CAN_USE" = ["default"]
55+
"CAN_MANAGE" = []
56+
}
57+
"token" = {
58+
"CAN_USE" = ["default"]
59+
"CAN_MANAGE" = []
60+
}
61+
}
62+
}
63+
64+
variable "ip_rules" {
65+
type = map(string)
66+
description = "Map of IP addresses permitted for access to DB"
67+
default = {}
68+
}
69+
70+
variable "sql_endpoint" {
71+
type = map(map(string))
72+
description = "Map of SQL Endoints to be deployed in Databricks Workspace"
73+
default = {}
74+
}
75+
76+
variable "default_values_sql_endpoint" {
77+
description = "Default values for SQL Endpoint"
78+
type = object({
79+
cluster_size = string
80+
min_num_clusters = number
81+
max_num_clusters = number
82+
auto_stop_mins = string
83+
enable_photon = bool
84+
enable_serverless_compute = bool
85+
})
86+
default = {
87+
cluster_size = "2X-Small"
88+
min_num_clusters = 0
89+
max_num_clusters = 1
90+
auto_stop_mins = "30"
91+
enable_photon = false
92+
enable_serverless_compute = false
93+
}
94+
}

versions.tf

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
terraform {
2+
required_version = ">=1.0.0"
3+
4+
required_providers {
5+
databricks = {
6+
source = "databricks/databricks"
7+
version = "=1.4.0"
8+
}
9+
}
10+
}

0 commit comments

Comments
 (0)