Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Updates to operation mode, SGs, cluster type, and additional flags. #57

Merged
merged 4 commits into from
May 14, 2024
Merged
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
8 changes: 4 additions & 4 deletions aws/tf/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,9 @@ In various `.tf` scripts, we have included direct links to the Databricks Terraf

## Operation Mode:

There are four separate operation modes you can choose for the underlying network configurations of your workspaces: **standard**, **firewall**, **isolated**, and **custom**.
There are four separate operation modes you can choose for the underlying network configurations of your workspaces: **sandbox**, **firewall**, **isolated**, and **custom**.

- **Standard**: Standard or standard open egress. Selecting 'standard' as the operation mode allows traffic to flow freely to the public internet. This mode is suitable for sandbox or development scenarios where data exfiltration protection is of minimal concern, and developers need to access public APIs, packages, and more.
- **Sandbox**: Sandbox or open egress. Selecting 'sandbox' as the operation mode allows traffic to flow freely to the public internet. This mode is suitable for sandbox or development scenarios where data exfiltration protection is of minimal concern, and developers need to access public APIs, packages, and more.

- **Firewall**: Firewall or limited egress. Choosing 'firewall' as the operation mode permits traffic flow only to a selected list of public addresses. This mode is applicable in situations where open internet access is necessary for certain tasks, but unfiltered traffic is not an option due to the sensitivity of the workloads or data. **NOTE**: Due to a limitation in the AWS Network Firewall's ability to use fully qualified domain names for non-HTTP/HTTPS traffic, an external data source is required for the external Hive metastore. For production scenarios, we recommend using Unity Catalog or self-hosted Hive metastores.

Expand Down Expand Up @@ -107,8 +107,8 @@ In this section, we break down additional security recommendations and opportuni
9. From `tf` directory, run `terraform plan -var-file ../example.tfvars`
10. Run `terraform apply -var-file ../example.tfvars`

## Network Diagram - Standard
![Architecture Diagram](https://github.com/databricks/terraform-databricks-sra/blob/main/aws/img/Standard%20-%20Network%20Topology.png)
## Network Diagram - Sandbox
![Architecture Diagram](https://github.com/databricks/terraform-databricks-sra/blob/main/aws/img/Sandbox%20-%20Network%20Topology.png)

## Network Diagram - Firewall
![Architecture Diagram](https://github.com/databricks/terraform-databricks-sra/blob/main/aws/img/Firewall%20-%20Network%20Topology.png)
Expand Down
6 changes: 4 additions & 2 deletions aws/tf/modules/sra/databricks_workspace.tf
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ module "uc_external_location" {

// Workspace Admin Configuration
module "admin_configuration" {
count = var.enable_admin_configs ? 1 : 0
source = "./databricks_workspace/workspace_security_modules/admin_configuration"
providers = {
databricks = databricks.created_workspace
Expand Down Expand Up @@ -96,8 +97,9 @@ module "cluster_configuration" {
databricks = databricks.created_workspace
}

secret_config_reference = module.secret_management.config_reference
resource_prefix = var.resource_prefix
compliance_security_profile = var.compliance_security_profile
secret_config_reference = module.secret_management.config_reference
resource_prefix = var.resource_prefix
depends_on = [
module.databricks_mws_workspace, module.secret_management
]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,16 @@

resource "databricks_workspace_conf" "just_config_map" {
custom_config = {
"enableResultsDownloading" = "false",
"enableNotebookTableClipboard" = "false",
"enableVerboseAuditLogs" = "true",
"enable-X-Frame-Options" = "true",
"enable-X-Content-Type-Options" = "true",
"enable-X-XSS-Protection" = "true",
"enableDbfsFileBrowser" = "false",
"enforceUserIsolation" = "true"
"enableResultsDownloading" = "false", // https://docs.databricks.com/en/notebooks/notebook-outputs.html#download-results
"enableNotebookTableClipboard" = "false", // https://docs.databricks.com/en/administration-guide/workspace-settings/notebooks.html#enable-users-to-copy-data-to-the-clipboard-from-notebooks
"enableVerboseAuditLogs" = "true", // https://docs.databricks.com/en/administration-guide/account-settings/verbose-logs.html
"enable-X-Frame-Options" = "true",
"enable-X-Content-Type-Options" = "true",
"enable-X-XSS-Protection" = "true",
"enableDbfsFileBrowser" = "false", // https://docs.databricks.com/en/administration-guide/workspace-settings/dbfs-browser.html
"enableExportNotebook" = "false", // https://docs.databricks.com/en/administration-guide/workspace-settings/notebooks.html#enable-users-to-export-notebooks
"enforceUserIsolation" = "true", // https://docs.databricks.com/en/administration-guide/workspace-settings/enforce-user-isolation.html
"storeInteractiveNotebookResultsInCustomerAccount" = "true", // https://docs.databricks.com/en/administration-guide/workspace-settings/notebooks.html#manage-where-notebook-results-are-stored
"enableUploadDataUis" = "false" // https://docs.databricks.com/en/ingestion/add-data/index.html
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,19 +31,23 @@ resource "databricks_cluster_policy" "example" {

// Cluster Creation
resource "databricks_cluster" "example" {
cluster_name = "Shared Cluster"
spark_version = data.databricks_spark_version.latest_lts.id
node_type_id = "i3.xlarge"
policy_id = databricks_cluster_policy.example.id
cluster_name = "Shared Cluster"
data_security_mode = "USER_ISOLATION"
spark_version = data.databricks_spark_version.latest_lts.id
node_type_id = var.compliance_security_profile ? "i3en.xlarge" : "i3.xlarge"
policy_id = databricks_cluster_policy.example.id

autoscale {
min_workers = 1
max_workers = 8
max_workers = 2
}

spark_conf = {
# ...
# Add additional spark configurations here
"secret.example" = var.secret_config_reference
}

depends_on = [
databricks_cluster_policy.example
]
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,10 @@ variable "resource_prefix" {

variable "secret_config_reference" {
type = string
}

variable "compliance_security_profile" {
type = bool
description = "Add 2443 to security group configuration or nitro instance"
nullable = false
}
31 changes: 23 additions & 8 deletions aws/tf/modules/sra/network.tf
Original file line number Diff line number Diff line change
Expand Up @@ -38,32 +38,47 @@ resource "aws_security_group" "sg" {
dynamic "ingress" {
for_each = var.sg_ingress_protocol
content {
from_port = 0
to_port = 65535
protocol = ingress.value
self = true
description = "Databricks - Data Plane Security Group - Internode Communication"
from_port = 0
to_port = 65535
protocol = ingress.value
self = true
}
}

dynamic "egress" {
for_each = var.sg_egress_protocol
content {
from_port = 0
to_port = 65535
protocol = egress.value
self = true
description = "Databricks - Data Plane Security Group - Internode Communication"
from_port = 0
to_port = 65535
protocol = egress.value
self = true
}
}

dynamic "egress" {
for_each = var.sg_egress_ports
content {
description = "Databricks - Data Plane Security Group - REST (443), Secure Cluster Connectivity (6666), Future Extendability (8443-8451)"
from_port = egress.value
to_port = egress.value
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
}

dynamic "egress" {
for_each = var.compliance_security_profile ? [2443] : []

content {
description = "Databricks - Data Plane Security Group - FIPS encryption"
from_port = 2443
to_port = 2443
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
}
tags = {
Name = "${var.resource_prefix}-data-plane-sg"
}
Expand Down
108 changes: 48 additions & 60 deletions aws/tf/modules/sra/privatelink.tf
Original file line number Diff line number Diff line change
@@ -1,3 +1,50 @@
// Security group for privatelink - skipped in custom operation mode
resource "aws_security_group" "privatelink" {
count = var.operation_mode != "custom" ? 1 : 0

vpc_id = module.vpc[0].vpc_id

ingress {
description = "Databricks - PrivateLink Endpoint SG - REST API"
from_port = 443
to_port = 443
protocol = "tcp"
security_groups = [aws_security_group.sg[0].id]
}

ingress {
description = "Databricks - PrivateLink Endpoint SG - Secure Cluster Connectivity"
from_port = 6666
to_port = 6666
protocol = "tcp"
security_groups = [aws_security_group.sg[0].id]
}

ingress {
description = "Databricks - PrivateLink Endpoint SG - Future Extendability"
from_port = 8443
to_port = 8451
protocol = "tcp"
security_groups = [aws_security_group.sg[0].id]
}

dynamic "ingress" {
for_each = var.compliance_security_profile ? [2443] : []

content {
description = "Databricks - Data Plane Security Group - FIPS encryption"
from_port = 2443
to_port = 2443
protocol = "tcp"
security_groups = [aws_security_group.sg[0].id]
}
}

tags = {
Name = "${var.resource_prefix}-private-link-sg"
}
}

// EXPLANATION: VPC Gateway Endpoint for S3, Interface Endpoint for Kinesis, and Interface Endpoint for STS


Expand Down Expand Up @@ -205,7 +252,7 @@ module "vpc_endpoints" {
version = "3.11.0"

vpc_id = module.vpc[0].vpc_id
security_group_ids = [aws_security_group.sg[0].id]
security_group_ids = [aws_security_group.privatelink[0].id]

endpoints = {
s3 = {
Expand Down Expand Up @@ -241,65 +288,6 @@ module "vpc_endpoints" {
]
}

// Security group for privatelink - skipped in custom operation mode
resource "aws_security_group" "privatelink" {
count = var.operation_mode != "custom" ? 1 : 0

vpc_id = module.vpc[0].vpc_id

ingress {
description = "Inbound rules"
from_port = 443
to_port = 443
protocol = "tcp"
security_groups = [aws_security_group.sg[0].id]
}

ingress {
description = "Inbound rules"
from_port = 2443
to_port = 2443
protocol = "tcp"
security_groups = [aws_security_group.sg[0].id]
}

ingress {
description = "Inbound rules"
from_port = 6666
to_port = 6666
protocol = "tcp"
security_groups = [aws_security_group.sg[0].id]
}

egress {
description = "Outbound rules"
from_port = 443
to_port = 443
protocol = "tcp"
security_groups = [aws_security_group.sg[0].id]
}

egress {
description = "Outbound rules"
from_port = 2443
to_port = 2443
protocol = "tcp"
security_groups = [aws_security_group.sg[0].id]
}

egress {
description = "Outbound rules"
from_port = 6666
to_port = 6666
protocol = "tcp"
security_groups = [aws_security_group.sg[0].id]
}

tags = {
Name = "${var.resource_prefix}-private-link-sg"
}
}

// Databricks REST endpoint - skipped in custom operation mode
resource "aws_vpc_endpoint" "backend_rest" {
count = var.operation_mode != "custom" ? 1 : 0
Expand Down
16 changes: 14 additions & 2 deletions aws/tf/modules/sra/variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -167,11 +167,23 @@ variable "operation_mode" {
nullable = false

validation {
condition = contains(["standard", "firewall", "custom", "isolated"], var.operation_mode)
error_message = "Invalid network type. Allowed values are: standard, firewall, custom, isolated."
condition = contains(["sandbox", "firewall", "custom", "isolated"], var.operation_mode)
error_message = "Invalid network type. Allowed values are: sandbox, firewall, custom, isolated."
}
}

variable "compliance_security_profile" {
type = bool
description = "Add 2443 to security group configuration or nitro instance"
nullable = false
}

variable "enable_admin_configs" {
type = bool
description = "Enable workspace configs"
nullable = false
}

variable "private_subnets_cidr" {
description = "CIDR blocks for private subnets."
type = list(string)
Expand Down
6 changes: 4 additions & 2 deletions aws/tf/sra.tf
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,14 @@ module "SRA" {
external_location_admin = null // REQUIRED - Read-only external location is created, this user will become an admin of that exteranl location (e.g. firstname.lastname@company.com)

// Workspace - operation mode:
operation_mode = "standard" // REQUIRED - Accepted values: standard, custom, firewall, or isolated. https://github.com/databricks/terraform-databricks-sra/blob/main/aws/tf/README.md#operation-mode
operation_mode = "sandbox" // REQUIRED - Accepted values: sandbox, custom, firewall, or isolated. https://github.com/databricks/terraform-databricks-sra/blob/main/aws/tf/README.md#operation-mode
compliance_security_profile = false // REQUIRED - If you are using compliance security profile, please enable this to true. This adds port 2443 (FIPS) as a security group rule.

// Workspace - AWS non-networking variables:
dbfsname = join("", [var.resource_prefix, "-", var.region, "-", "dbfsroot"])
cmk_admin_arn = null // If not provided, the root user of the AWS account is used
enable_cluster_boolean = false // WARNING: Clusters will spin-up Databricks clusters and AWS EC2 instances
enable_admin_configs = false // WARNING: The workspace_conf resource is evolving API that may change from provider to provider. Please review the in-resource documentation (admin_configuration.tf) before enabling.
workspace_service_principal_name = "sra-example-sp"

// Workspace - networking variables (optional if using custom operation mode):
Expand All @@ -44,7 +46,7 @@ module "SRA" {
privatelink_subnets_cidr = ["10.0.32.0/26", "10.0.32.64/26"]
public_subnets_cidr = ["10.0.32.128/26", "10.0.32.192/26"]
availability_zones = [data.aws_availability_zones.available.names[0], data.aws_availability_zones.available.names[1]]
sg_egress_ports = [443, 2443, 3306, 6666, 8443, 8444, 8445, 8446, 8447, 8448, 8449, 8450, 8451]
sg_egress_ports = [443, 3306, 6666, 8443, 8444, 8445, 8446, 8447, 8448, 8449, 8450, 8451]
sg_ingress_protocol = ["tcp", "udp"]
sg_egress_protocol = ["tcp", "udp"]
relay_vpce_service = var.scc_relay[var.region]
Expand Down