Skip to content

Commit

Permalink
feat: Add support for Private Service Connect to ClickHouse (#168)
Browse files Browse the repository at this point in the history
  • Loading branch information
raubitsj authored Sep 12, 2024
1 parent a6320bd commit 62dbc62
Show file tree
Hide file tree
Showing 7 changed files with 134 additions and 1 deletion.
5 changes: 5 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ resources that lack official modules.
|------|--------|---------|
| <a name="module_app_gke"></a> [app\_gke](#module\_app\_gke) | ./modules/app_gke | n/a |
| <a name="module_app_lb"></a> [app\_lb](#module\_app\_lb) | ./modules/app_lb | n/a |
| <a name="module_clickhouse"></a> [clickhouse](#module\_clickhouse) | ./modules/clickhouse | n/a |
| <a name="module_database"></a> [database](#module\_database) | ./modules/database | n/a |
| <a name="module_gke_app"></a> [gke\_app](#module\_gke\_app) | wandb/wandb/kubernetes | 1.14.1 |
| <a name="module_kms"></a> [kms](#module\_kms) | ./modules/kms | n/a |
Expand Down Expand Up @@ -111,6 +112,9 @@ resources that lack official modules.
| <a name="input_bucket_location"></a> [bucket\_location](#input\_bucket\_location) | Location of the bucket (US, EU, ASIA) | `string` | `"US"` | no |
| <a name="input_bucket_name"></a> [bucket\_name](#input\_bucket\_name) | Use an existing bucket. | `string` | `""` | no |
| <a name="input_bucket_path"></a> [bucket\_path](#input\_bucket\_path) | path of where to store data for the instance-level bucket | `string` | `""` | no |
| <a name="input_clickhouse_private_endpoint_service_name"></a> [clickhouse\_private\_endpoint\_service\_name](#input\_clickhouse\_private\_endpoint\_service\_name) | ClickHouse private endpoint 'Service name' (ends in -clickhouse-cloud). | `string` | `""` | no |
| <a name="input_clickhouse_region"></a> [clickhouse\_region](#input\_clickhouse\_region) | ClickHouse region (us-east1, us-central1, etc). | `string` | `""` | no |
| <a name="input_clickhouse_subnetwork_cidr"></a> [clickhouse\_subnetwork\_cidr](#input\_clickhouse\_subnetwork\_cidr) | ClickHouse private service connect subnetwork | `string` | `"10.50.0.0/24"` | no |
| <a name="input_create_private_link"></a> [create\_private\_link](#input\_create\_private\_link) | Whether to create a private link service. | `bool` | `false` | no |
| <a name="input_create_redis"></a> [create\_redis](#input\_create\_redis) | Boolean indicating whether to provision an redis instance (true) or not (false). | `bool` | `false` | no |
| <a name="input_create_workload_identity"></a> [create\_workload\_identity](#input\_create\_workload\_identity) | Flag to indicate whether to create a workload identity for the service account. | `bool` | `false` | no |
Expand Down Expand Up @@ -162,6 +166,7 @@ resources that lack official modules.
| <a name="output_bucket_name"></a> [bucket\_name](#output\_bucket\_name) | Name of google bucket. |
| <a name="output_bucket_path"></a> [bucket\_path](#output\_bucket\_path) | path of where to store data for the instance-level bucket |
| <a name="output_bucket_queue_name"></a> [bucket\_queue\_name](#output\_bucket\_queue\_name) | Pubsub queue created for google bucket file upload events. |
| <a name="output_clickhouse_private_endpoint_id"></a> [clickhouse\_private\_endpoint\_id](#output\_clickhouse\_private\_endpoint\_id) | ClickHouse Private endpoint Endpoint ID to secure access inside VPC |
| <a name="output_cluster_ca_certificate"></a> [cluster\_ca\_certificate](#output\_cluster\_ca\_certificate) | Certificate of the kubernetes (GKE) cluster. |
| <a name="output_cluster_client_certificate"></a> [cluster\_client\_certificate](#output\_cluster\_client\_certificate) | n/a |
| <a name="output_cluster_client_key"></a> [cluster\_client\_key](#output\_cluster\_client\_key) | n/a |
Expand Down
11 changes: 11 additions & 0 deletions main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,17 @@ module "redis" {
depends_on = [module.project_factory_project_services, module.kms_default_sql]
}

module "clickhouse" {
count = var.clickhouse_private_endpoint_service_name != "" ? 1 : 0
source = "./modules/clickhouse"
network = local.network.id
namespace = var.namespace

clickhouse_reserved_ip_range = var.clickhouse_subnetwork_cidr
clickhouse_private_endpoint_service_name = var.clickhouse_private_endpoint_service_name
clickhouse_region = var.clickhouse_region
}

locals {
redis_certificate = var.create_redis ? module.redis[0].ca_cert : null
redis_connection_string = var.create_redis ? "redis://:${module.redis[0].auth_string}@${module.redis[0].connection_string}?tls=true&ttlInSeconds=604800&caCertPath=/etc/ssl/certs/server_ca.pem" : null
Expand Down
50 changes: 50 additions & 0 deletions modules/clickhouse/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
resource "google_compute_subnetwork" "psc_network" {
name = "${var.namespace}-subnet-clickhouse"

region = var.clickhouse_region
ip_cidr_range = var.clickhouse_reserved_ip_range
private_ip_google_access = true
network = var.network
}

resource "google_compute_address" "psc_endpoint_ip" {
name = "${var.namespace}-clickhouse-psc-ip"
address_type = "INTERNAL"
purpose = "GCE_ENDPOINT"
subnetwork = google_compute_subnetwork.psc_network.self_link
region = var.clickhouse_region
}

resource "google_compute_forwarding_rule" "psc_forward_rule" {
name = "${var.namespace}-clickhouse-psc-forward"
ip_address = google_compute_address.psc_endpoint_ip.self_link
network = var.network
region = var.clickhouse_region
load_balancing_scheme = ""
allow_psc_global_access = true

target = "https://www.googleapis.com/compute/v1/${var.clickhouse_private_endpoint_service_name}"
}

resource "google_dns_managed_zone" "psc_dns_zone" {
name = "${var.namespace}-clickhouse-dns-zone"
description = "Private DNS zone for accessing ClickHouse Cloud using Private Service Connect"
dns_name = "${var.clickhouse_region}.p.gcp.clickhouse.cloud."
force_destroy = true
visibility = "private"

// associate private DNS zone with network
private_visibility_config {
networks {
network_url = var.network
}
}
}

resource "google_dns_record_set" "psc_dns_record" {
name = "*.${var.clickhouse_region}.p.gcp.clickhouse.cloud."
managed_zone = google_dns_managed_zone.psc_dns_zone.name
type = "A"
rrdatas = [ google_compute_address.psc_endpoint_ip.address ]
ttl = 3600
}
4 changes: 4 additions & 0 deletions modules/clickhouse/output.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
output "psc_connection_id" {
value = google_compute_forwarding_rule.psc_forward_rule.psc_connection_id
description = "Add GCP PSC Connection ID to ClickHouse allow list."
}
37 changes: 37 additions & 0 deletions modules/clickhouse/variables.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
variable "namespace" {
type = string
description = "The name prefix for all resources created."
}

variable "network" {
type = string
description = "Google Compute Engine network to which the cluster is connected."
}

variable "clickhouse_reserved_ip_range" {
type = string
description = "Reserved IP range for ClickHouse private link"
default = "10.50.0.0/24"
}

variable "clickhouse_private_endpoint_service_name" {
type = string
description = "ClickHouse private endpoint 'Service name' (ends in -clickhouse-cloud)."
default = ""

validation {
condition = can(regex("-clickhouse-cloud$", var.clickhouse_private_endpoint_service_name))
error_message = "ClickHouse Service name must end in '-clickhouse-cloud'."
}
}

variable "clickhouse_region" {
type = string
description = "ClickHouse region (us-east1, us-central1, etc)."
default = ""

validation {
condition = length(var.clickhouse_region) > 0
error_message = "Clickhouse Region should always be set if the private endpoint service name is specified."
}
}
7 changes: 6 additions & 1 deletion outputs.tf
Original file line number Diff line number Diff line change
Expand Up @@ -96,4 +96,9 @@ output "private_attachement_id" {
output "sa_account_email" {
description = "This output provides the email address of the service account created for workload identity, if workload identity is enabled. Otherwise, it returns null"
value = var.create_workload_identity == true ? module.service_accounts.sa_account_role : null
}
}

output "clickhouse_private_endpoint_id" {
description = "ClickHouse Private endpoint Endpoint ID to secure access inside VPC"
value = var.clickhouse_private_endpoint_service_name != "" ? module.clickhouse[0].psc_connection_id : null
}
21 changes: 21 additions & 0 deletions variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -353,3 +353,24 @@ variable "stackdriver_sa_name" {
type = string
default = "wandb-stackdriver"
}

###########################################
# ClickHouse endpoint #
###########################################
variable "clickhouse_private_endpoint_service_name" {
type = string
description = "ClickHouse private endpoint 'Service name' (ends in -clickhouse-cloud)."
default = ""
}

variable "clickhouse_region" {
type = string
description = "ClickHouse region (us-east1, us-central1, etc)."
default = ""
}

variable "clickhouse_subnetwork_cidr" {
default = "10.50.0.0/24"
description = "ClickHouse private service connect subnetwork"
type = string
}

0 comments on commit 62dbc62

Please sign in to comment.