Skip to content

Commit

Permalink
feat: Add CMEK support for cross-region read replicas (#251)
Browse files Browse the repository at this point in the history
BREAKING CHANGE: `var.read_replicas` now requires an encryption key name. Set `encryption_key_name = null` to preserve the old behavior.
  • Loading branch information
imrannayer committed Oct 13, 2021
1 parent e1a6fc7 commit 426724a
Show file tree
Hide file tree
Showing 10 changed files with 73 additions and 60 deletions.
57 changes: 30 additions & 27 deletions examples/mysql-ha/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -80,37 +80,40 @@ module "mysql" {
read_replica_name_suffix = "-test"
read_replicas = [
{
name = "0"
zone = "us-central1-a"
tier = "db-n1-standard-1"
ip_configuration = local.read_replica_ip_configuration
database_flags = [{ name = "long_query_time", value = 1 }]
disk_autoresize = null
disk_size = null
disk_type = "PD_HDD"
user_labels = { bar = "baz" }
name = "0"
zone = "us-central1-a"
tier = "db-n1-standard-1"
ip_configuration = local.read_replica_ip_configuration
database_flags = [{ name = "long_query_time", value = 1 }]
disk_autoresize = null
disk_size = null
disk_type = "PD_HDD"
user_labels = { bar = "baz" }
encryption_key_name = null
},
{
name = "1"
zone = "us-central1-b"
tier = "db-n1-standard-1"
ip_configuration = local.read_replica_ip_configuration
database_flags = [{ name = "long_query_time", value = 1 }]
disk_autoresize = null
disk_size = null
disk_type = "PD_HDD"
user_labels = { bar = "baz" }
name = "1"
zone = "us-central1-b"
tier = "db-n1-standard-1"
ip_configuration = local.read_replica_ip_configuration
database_flags = [{ name = "long_query_time", value = 1 }]
disk_autoresize = null
disk_size = null
disk_type = "PD_HDD"
user_labels = { bar = "baz" }
encryption_key_name = null
},
{
name = "2"
zone = "us-central1-c"
tier = "db-n1-standard-1"
ip_configuration = local.read_replica_ip_configuration
database_flags = [{ name = "long_query_time", value = 1 }]
disk_autoresize = null
disk_size = null
disk_type = "PD_HDD"
user_labels = { bar = "baz" }
name = "2"
zone = "us-central1-c"
tier = "db-n1-standard-1"
ip_configuration = local.read_replica_ip_configuration
database_flags = [{ name = "long_query_time", value = 1 }]
disk_autoresize = null
disk_size = null
disk_type = "PD_HDD"
user_labels = { bar = "baz" }
encryption_key_name = null
},
]

Expand Down
57 changes: 30 additions & 27 deletions examples/postgresql-ha/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -79,37 +79,40 @@ module "pg" {
read_replica_name_suffix = "-test"
read_replicas = [
{
name = "0"
zone = "us-central1-a"
tier = "db-custom-2-13312"
ip_configuration = local.read_replica_ip_configuration
database_flags = [{ name = "autovacuum", value = "off" }]
disk_autoresize = null
disk_size = null
disk_type = "PD_HDD"
user_labels = { bar = "baz" }
name = "0"
zone = "us-central1-a"
tier = "db-custom-2-13312"
ip_configuration = local.read_replica_ip_configuration
database_flags = [{ name = "autovacuum", value = "off" }]
disk_autoresize = null
disk_size = null
disk_type = "PD_HDD"
user_labels = { bar = "baz" }
encryption_key_name = null
},
{
name = "1"
zone = "us-central1-b"
tier = "db-custom-2-13312"
ip_configuration = local.read_replica_ip_configuration
database_flags = [{ name = "autovacuum", value = "off" }]
disk_autoresize = null
disk_size = null
disk_type = "PD_HDD"
user_labels = { bar = "baz" }
name = "1"
zone = "us-central1-b"
tier = "db-custom-2-13312"
ip_configuration = local.read_replica_ip_configuration
database_flags = [{ name = "autovacuum", value = "off" }]
disk_autoresize = null
disk_size = null
disk_type = "PD_HDD"
user_labels = { bar = "baz" }
encryption_key_name = null
},
{
name = "2"
zone = "us-central1-c"
tier = "db-custom-2-13312"
ip_configuration = local.read_replica_ip_configuration
database_flags = [{ name = "autovacuum", value = "off" }]
disk_autoresize = null
disk_size = null
disk_type = "PD_HDD"
user_labels = { bar = "baz" }
name = "2"
zone = "us-central1-c"
tier = "db-custom-2-13312"
ip_configuration = local.read_replica_ip_configuration
database_flags = [{ name = "autovacuum", value = "off" }]
disk_autoresize = null
disk_size = null
disk_type = "PD_HDD"
user_labels = { bar = "baz" }
encryption_key_name = null
},
]

Expand Down
2 changes: 1 addition & 1 deletion modules/mysql/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ Note: CloudSQL provides [disk autoresize](https://cloud.google.com/sql/docs/mysq
| random\_instance\_name | Sets random suffix at the end of the Cloud SQL resource name | `bool` | `false` | no |
| read\_replica\_deletion\_protection | Used to block Terraform from deleting replica SQL Instances. | `bool` | `false` | no |
| read\_replica\_name\_suffix | The optional suffix to add to the read instance name | `string` | `""` | no |
| read\_replicas | List of read replicas to create | <pre>list(object({<br> name = string<br> tier = string<br> zone = string<br> disk_type = string<br> disk_autoresize = bool<br> disk_size = string<br> user_labels = map(string)<br> database_flags = list(object({<br> name = string<br> value = string<br> }))<br> ip_configuration = object({<br> authorized_networks = list(map(string))<br> ipv4_enabled = bool<br> private_network = string<br> require_ssl = bool<br> })<br> }))</pre> | `[]` | no |
| read\_replicas | List of read replicas to create. Encryption key is required for replica in different region. For replica in same region as master set encryption\_key\_name = null | <pre>list(object({<br> name = string<br> tier = string<br> zone = string<br> disk_type = string<br> disk_autoresize = bool<br> disk_size = string<br> user_labels = map(string)<br> database_flags = list(object({<br> name = string<br> value = string<br> }))<br> ip_configuration = object({<br> authorized_networks = list(map(string))<br> ipv4_enabled = bool<br> private_network = string<br> require_ssl = bool<br> })<br> encryption_key_name = string<br> }))</pre> | `[]` | no |
| region | The region of the Cloud SQL resources | `string` | `"us-central1"` | no |
| tier | The tier for the master instance. | `string` | `"db-n1-standard-1"` | no |
| update\_timeout | The optional timout that is applied to limit long database updates. | `string` | `"10m"` | no |
Expand Down
2 changes: 2 additions & 0 deletions modules/mysql/read_replica.tf
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,15 @@ locals {
}

resource "google_sql_database_instance" "replicas" {
provider = google-beta
for_each = local.replicas
project = var.project_id
name = "${local.master_instance_name}-replica${var.read_replica_name_suffix}${each.value.name}"
database_version = var.database_version
region = join("-", slice(split("-", lookup(each.value, "zone", var.zone)), 0, 2))
master_instance_name = google_sql_database_instance.default.name
deletion_protection = var.read_replica_deletion_protection
encryption_key_name = (join("-", slice(split("-", lookup(each.value, "zone", var.zone)), 0, 2))) == var.region ? null : each.value.encryption_key_name

replica_configuration {
failover_target = false
Expand Down
3 changes: 2 additions & 1 deletion modules/mysql/variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,7 @@ variable "ip_configuration" {

// Read Replicas
variable "read_replicas" {
description = "List of read replicas to create"
description = "List of read replicas to create. Encryption key is required for replica in different region. For replica in same region as master set encryption_key_name = null"
type = list(object({
name = string
tier = string
Expand All @@ -184,6 +184,7 @@ variable "read_replicas" {
private_network = string
require_ssl = bool
})
encryption_key_name = string
}))
default = []
}
Expand Down
2 changes: 1 addition & 1 deletion modules/postgresql/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ Note: CloudSQL provides [disk autoresize](https://cloud.google.com/sql/docs/mysq
| random\_instance\_name | Sets random suffix at the end of the Cloud SQL resource name | `bool` | `false` | no |
| read\_replica\_deletion\_protection | Used to block Terraform from deleting replica SQL Instances. | `bool` | `false` | no |
| read\_replica\_name\_suffix | The optional suffix to add to the read instance name | `string` | `""` | no |
| read\_replicas | List of read replicas to create | <pre>list(object({<br> name = string<br> tier = string<br> zone = string<br> disk_type = string<br> disk_autoresize = bool<br> disk_size = string<br> user_labels = map(string)<br> database_flags = list(object({<br> name = string<br> value = string<br> }))<br> ip_configuration = object({<br> authorized_networks = list(map(string))<br> ipv4_enabled = bool<br> private_network = string<br> require_ssl = bool<br> })<br> }))</pre> | `[]` | no |
| read\_replicas | List of read replicas to create. Encryption key is required for replica in different region. For replica in same region as master set encryption\_key\_name = null | <pre>list(object({<br> name = string<br> tier = string<br> zone = string<br> disk_type = string<br> disk_autoresize = bool<br> disk_size = string<br> user_labels = map(string)<br> database_flags = list(object({<br> name = string<br> value = string<br> }))<br> ip_configuration = object({<br> authorized_networks = list(map(string))<br> ipv4_enabled = bool<br> private_network = string<br> require_ssl = bool<br> })<br> encryption_key_name = string<br> }))</pre> | `[]` | no |
| region | The region of the Cloud SQL resources | `string` | `"us-central1"` | no |
| tier | The tier for the master instance. | `string` | `"db-f1-micro"` | no |
| update\_timeout | The optional timout that is applied to limit long database updates. | `string` | `"15m"` | no |
Expand Down
2 changes: 2 additions & 0 deletions modules/postgresql/read_replica.tf
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,15 @@ locals {
}

resource "google_sql_database_instance" "replicas" {
provider = google-beta
for_each = local.replicas
project = var.project_id
name = "${local.master_instance_name}-replica${var.read_replica_name_suffix}${each.value.name}"
database_version = var.database_version
region = join("-", slice(split("-", lookup(each.value, "zone", var.zone)), 0, 2))
master_instance_name = google_sql_database_instance.default.name
deletion_protection = var.read_replica_deletion_protection
encryption_key_name = (join("-", slice(split("-", lookup(each.value, "zone", var.zone)), 0, 2))) == var.region ? null : each.value.encryption_key_name

replica_configuration {
failover_target = false
Expand Down
3 changes: 2 additions & 1 deletion modules/postgresql/variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,7 @@ variable "ip_configuration" {

// Read Replicas
variable "read_replicas" {
description = "List of read replicas to create"
description = "List of read replicas to create. Encryption key is required for replica in different region. For replica in same region as master set encryption_key_name = null"
type = list(object({
name = string
tier = string
Expand All @@ -191,6 +191,7 @@ variable "read_replicas" {
private_network = string
require_ssl = bool
})
encryption_key_name = string
}))
default = []
}
Expand Down
2 changes: 1 addition & 1 deletion modules/safer_mysql/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,7 @@ mysql -S $HOME/mysql_sockets/myproject:region:instance -u user -p
| random\_instance\_name | Sets random suffix at the end of the Cloud SQL resource name | `bool` | `false` | no |
| read\_replica\_deletion\_protection | Used to block Terraform from deleting replica SQL Instances. | `bool` | `false` | no |
| read\_replica\_name\_suffix | The optional suffix to add to the read instance name | `string` | `""` | no |
| read\_replicas | List of read replicas to create | <pre>list(object({<br> name = string<br> tier = string<br> zone = string<br> disk_type = string<br> disk_autoresize = bool<br> disk_size = string<br> user_labels = map(string)<br> database_flags = list(object({<br> name = string<br> value = string<br> }))<br> ip_configuration = object({<br> authorized_networks = list(map(string))<br> ipv4_enabled = bool<br> private_network = string<br> require_ssl = bool<br> })<br> }))</pre> | `[]` | no |
| read\_replicas | List of read replicas to create. Encryption key is required for replica in different region. For replica in same region as master set encryption\_key\_name = null | <pre>list(object({<br> name = string<br> tier = string<br> zone = string<br> disk_type = string<br> disk_autoresize = bool<br> disk_size = string<br> user_labels = map(string)<br> database_flags = list(object({<br> name = string<br> value = string<br> }))<br> ip_configuration = object({<br> authorized_networks = list(map(string))<br> ipv4_enabled = bool<br> private_network = string<br> require_ssl = bool<br> })<br> encryption_key_name = string<br> }))</pre> | `[]` | no |
| region | The region of the Cloud SQL resources | `string` | n/a | yes |
| tier | The tier for the master instance. | `string` | `"db-n1-standard-1"` | no |
| update\_timeout | The optional timout that is applied to limit long database updates. | `string` | `"15m"` | no |
Expand Down
3 changes: 2 additions & 1 deletion modules/safer_mysql/variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,7 @@ variable "read_replica_name_suffix" {
}

variable "read_replicas" {
description = "List of read replicas to create"
description = "List of read replicas to create. Encryption key is required for replica in different region. For replica in same region as master set encryption_key_name = null"
type = list(object({
name = string
tier = string
Expand All @@ -184,6 +184,7 @@ variable "read_replicas" {
private_network = string
require_ssl = bool
})
encryption_key_name = string
}))
default = []
}
Expand Down

0 comments on commit 426724a

Please sign in to comment.