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
14 changes: 14 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,20 @@ Please review the README.md in the examples for all Pre-deployment and Post-Depl

The default configuration is a large production-sized deployment. Please consider that when testing and adjust the configuration to use smaller sized resources.

## Cloud SQL machine types

The module supports only Cloud SQL Enterprise Plus.
It selects the disk type from `postgres_machine_type`.
The default remains `db-perf-optimized-N-8`
A change to the database machine type causes downtime.

| Machine type | Disk |
| --- | --- |
| `db-perf-optimized-N-*` | SSD |
| `db-c4a-highmem-*` | Hyperdisk Balanced |
| `db-perf-optimized-C4-*` | Hyperdisk Balanced |


## Development Setup

This section is only relevant if you are a contributor who wants to make changes to this module. All others can skip this section.
Expand Down
5 changes: 3 additions & 2 deletions examples/braintrust-data-plane/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -57,8 +57,9 @@ module "braintrust-data-plane" {
# postgres_machine_type = "db-perf-optimized-N-8"
# postgres_availability_type = "REGIONAL"
# postgres_disk_size = 1000
# Does this auto expand? how do we handle that?
# How do we control disk perf IOPS/etc
# Optional Hyperdisk performance values when using C4A or C4 machine types. Null uses Cloud SQL defaults.
# postgres_disk_provisioned_iops = 12000
# postgres_disk_provisioned_throughput = 500

### Redis configuration
# redis_version = "REDIS_7_2"
Expand Down
4 changes: 2 additions & 2 deletions examples/braintrust-data-plane/versions.tf
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@ terraform {
required_providers {
google = {
source = "hashicorp/google"
version = "~> 6.45"
version = ">= 8.2.0, < 9.0.0"
}
google-beta = {
source = "hashicorp/google-beta"
version = "~> 6.45"
version = ">= 8.2.0, < 9.0.0"
}
}
}
26 changes: 14 additions & 12 deletions main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -25,18 +25,20 @@ module "kms" {
module "database" {
source = "./modules/database"

deployment_name = var.deployment_name
custom_labels = var.custom_labels
postgres_network = var.create_vpc ? module.vpc[0].network_self_link : var.existing_network_self_link
postgres_kms_cmek_id = module.kms.kms_key_id
postgres_version = var.postgres_version
postgres_availability_type = var.postgres_availability_type
postgres_machine_type = var.postgres_machine_type
postgres_disk_size = var.postgres_disk_size
postgres_enable_seqscan = var.postgres_enable_seqscan
postgres_backup_start_time = var.postgres_backup_start_time
postgres_maintenance_window = var.postgres_maintenance_window
postgres_deletion_protection = var.postgres_deletion_protection
deployment_name = var.deployment_name
custom_labels = var.custom_labels
postgres_network = var.create_vpc ? module.vpc[0].network_self_link : var.existing_network_self_link
postgres_kms_cmek_id = module.kms.kms_key_id
postgres_version = var.postgres_version
postgres_availability_type = var.postgres_availability_type
postgres_machine_type = var.postgres_machine_type
postgres_disk_provisioned_iops = var.postgres_disk_provisioned_iops
postgres_disk_provisioned_throughput = var.postgres_disk_provisioned_throughput
postgres_disk_size = var.postgres_disk_size
postgres_enable_seqscan = var.postgres_enable_seqscan
postgres_backup_start_time = var.postgres_backup_start_time
postgres_maintenance_window = var.postgres_maintenance_window
postgres_deletion_protection = var.postgres_deletion_protection

depends_on = [module.vpc]
}
Expand Down
16 changes: 11 additions & 5 deletions modules/database/main.tf
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
locals {
postgres_uses_hyperdisk = can(regex("^db-(c4a-highmem|perf-optimized-C4)-[0-9]+$", var.postgres_machine_type))

common_labels = merge(var.custom_labels, {
braintrustdeploymentname = var.deployment_name
})
Expand Down Expand Up @@ -53,11 +55,15 @@ resource "google_sql_database_instance" "braintrust" {
deletion_protection = var.postgres_deletion_protection

settings {
availability_type = var.postgres_availability_type
tier = var.postgres_machine_type
disk_type = "PD_SSD"
disk_size = var.postgres_disk_size
disk_autoresize = true
availability_type = var.postgres_availability_type
tier = var.postgres_machine_type
edition = "ENTERPRISE_PLUS"
disk_type = local.postgres_uses_hyperdisk ? "HYPERDISK_BALANCED" : "PD_SSD"
data_disk_provisioned_iops = var.postgres_disk_provisioned_iops
data_disk_provisioned_throughput = var.postgres_disk_provisioned_throughput
disk_size = var.postgres_disk_size
disk_autoresize = true
disk_autoresize_limit = 0

# Braintrust will create a high number of connections to the database. Setting this to an extremely high amount of connections as changing this requires a DB restart.
database_flags {
Expand Down
57 changes: 55 additions & 2 deletions modules/database/variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -35,14 +35,67 @@ variable "postgres_availability_type" {

variable "postgres_machine_type" {
type = string
description = "Machine size of Cloud SQL for PostgreSQL instance."
description = "Enterprise Plus machine type from the N2, C4A, or C4 series. The machine type selects compatible storage settings."
default = "db-perf-optimized-N-8"

validation {
condition = can(regex("^db-(perf-optimized-(N|C4)|c4a-highmem)-[0-9]+$", var.postgres_machine_type))
Comment thread
jeffmccollum marked this conversation as resolved.
error_message = "Use an Enterprise Plus machine type from the N2, C4A, or C4 series."
}

validation {
condition = !contains(["db-c4a-highmem-2", "db-perf-optimized-C4-2"], var.postgres_machine_type)
error_message = "C4A and C4 machine types require at least four vCPUs."
}
}

variable "postgres_disk_provisioned_iops" {
type = number
description = "Hyperdisk IOPS. Null uses the Cloud SQL default for the disk size and machine type."
default = null

validation {
condition = var.postgres_disk_provisioned_iops == null ? true : var.postgres_disk_provisioned_iops >= 3000 && floor(var.postgres_disk_provisioned_iops) == var.postgres_disk_provisioned_iops
error_message = "Hyperdisk IOPS must be an integer of at least 3000."
}

validation {
condition = var.postgres_disk_provisioned_iops == null || can(regex("^db-(c4a-highmem|perf-optimized-C4)-[0-9]+$", var.postgres_machine_type))
error_message = "Custom IOPS require a C4A or C4 machine type with Hyperdisk Balanced."
}
}

variable "postgres_disk_provisioned_throughput" {
type = number
description = "Hyperdisk throughput in MiB/s. Null uses the Cloud SQL default for the disk size and machine type."
default = null

validation {
condition = var.postgres_disk_provisioned_throughput == null ? true : var.postgres_disk_provisioned_throughput >= 140 && floor(var.postgres_disk_provisioned_throughput) == var.postgres_disk_provisioned_throughput
error_message = "Hyperdisk throughput must be an integer of at least 140 MiB/s."
}

validation {
condition = var.postgres_disk_provisioned_throughput == null || can(regex("^db-(c4a-highmem|perf-optimized-C4)-[0-9]+$", var.postgres_machine_type))
error_message = "Custom throughput requires a C4A or C4 machine type with Hyperdisk Balanced."
}
}

variable "postgres_disk_size" {
type = number
description = "Size in GB of PostgreSQL disk."
description = "Initial PostgreSQL disk size in GB. Terraform ignores later changes to this value."
default = 1000
nullable = false

validation {
condition = var.postgres_disk_size >= 10 && floor(var.postgres_disk_size) == var.postgres_disk_size
error_message = "The initial disk size must be an integer of at least 10 GB."
}

validation {
condition = !can(regex("^db-(c4a-highmem|perf-optimized-C4)-[0-9]+$", var.postgres_machine_type)) || var.postgres_disk_size >= 20
error_message = "Hyperdisk Balanced requires a disk size of at least 20 GB."
}
}

variable "postgres_enable_seqscan" {
Expand Down
4 changes: 2 additions & 2 deletions modules/database/versions.tf
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@ terraform {
required_providers {
google = {
source = "hashicorp/google"
version = "~> 6.45"
version = ">= 8.2.0, < 9.0.0"
}
google-beta = {
source = "hashicorp/google-beta"
version = "~> 6.45"
version = ">= 8.2.0, < 9.0.0"
}
random = {
source = "hashicorp/random"
Expand Down
7 changes: 0 additions & 7 deletions modules/gke-cluster/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -123,13 +123,6 @@ resource "google_container_cluster" "braintrust_autopilot" {
google_kms_crypto_key_iam_member.gke_compute_cmek
]

lifecycle {
# GKE Autopilot may report ALL_OBJECTS_ENCRYPTION_ENABLED after create, but
# the Terraform provider currently accepts only ENCRYPTED/DECRYPTED as input.
ignore_changes = [
database_encryption[0].state,
]
}
}

#----------------------------------------------------------------------------------------------
Expand Down
6 changes: 1 addition & 5 deletions modules/gke-cluster/versions.tf
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,7 @@ terraform {
required_providers {
google = {
source = "hashicorp/google"
version = "~> 6.45"
}
random = {
source = "hashicorp/random"
version = ">= 3.7.2"
version = ">= 8.2.0, < 9.0.0"
}
}
}
10 changes: 1 addition & 9 deletions modules/gke-iam/versions.tf
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,7 @@ terraform {
required_providers {
google = {
source = "hashicorp/google"
version = "~> 6.45"
}
google-beta = {
source = "hashicorp/google-beta"
version = "~> 6.45"
}
random = {
source = "hashicorp/random"
version = ">= 3.7.2"
version = ">= 8.2.0, < 9.0.0"
}
}
}
2 changes: 1 addition & 1 deletion modules/kms/versions.tf
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ terraform {
required_providers {
google = {
source = "hashicorp/google"
version = "~> 6.45"
version = ">= 8.2.0, < 9.0.0"
}
random = {
source = "hashicorp/random"
Expand Down
6 changes: 1 addition & 5 deletions modules/redis/versions.tf
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,7 @@ terraform {
required_providers {
google = {
source = "hashicorp/google"
version = "~> 6.45"
}
random = {
source = "hashicorp/random"
version = ">= 3.7.2"
version = ">= 8.2.0, < 9.0.0"
}
}
}
2 changes: 1 addition & 1 deletion modules/storage/versions.tf
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ terraform {
required_providers {
google = {
source = "hashicorp/google"
version = "~> 6.45"
version = ">= 8.2.0, < 9.0.0"
}
random = {
source = "hashicorp/random"
Expand Down
10 changes: 1 addition & 9 deletions modules/vpc/versions.tf
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,7 @@ terraform {
required_providers {
google = {
source = "hashicorp/google"
version = "~> 6.45"
}
google-beta = {
source = "hashicorp/google-beta"
version = "~> 6.45"
}
random = {
source = "hashicorp/random"
version = ">= 3.7.2"
version = ">= 8.2.0, < 9.0.0"
}
}
}
50 changes: 50 additions & 0 deletions tests/sql_disk_options.tftest.hcl
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
mock_provider "google" {}
mock_provider "google-beta" {}
mock_provider "random" {}

variables {
deployment_name = "sql-disk-test"
postgres_network = "projects/test/global/networks/test"
postgres_kms_cmek_id = "projects/test/locations/us-central1/keyRings/test/cryptoKeys/test"
}

run "default_growth" {
command = plan
module { source = "./modules/database" }
assert {
condition = google_sql_database_instance.braintrust.settings[0].disk_autoresize && google_sql_database_instance.braintrust.settings[0].disk_autoresize_limit == 0
error_message = "Automatic disk growth must remain enabled without a custom limit."
}
}

run "reject_small_disk" {
command = plan
module { source = "./modules/database" }
variables {
postgres_disk_size = 9
}
expect_failures = [var.postgres_disk_size]
}

run "n2_accepts_ten_gb_disk" {
command = plan
module { source = "./modules/database" }
variables { postgres_disk_size = 10 }
assert {
condition = google_sql_database_instance.braintrust.settings[0].disk_size == 10
error_message = "N2 must retain support for a 10 GB SSD."
}
}

run "c4a_accepts_twenty_gb_disk" {
command = plan
module { source = "./modules/database" }
variables {
postgres_machine_type = "db-c4a-highmem-8"
postgres_disk_size = 20
}
assert {
condition = google_sql_database_instance.braintrust.settings[0].disk_size == 20
error_message = "C4A must accept the 20 GB Hyperdisk minimum."
}
}
Loading
Loading