Skip to content

Commit

Permalink
feat!: adds availability_type for read_replicas (#329)
Browse files Browse the repository at this point in the history
This is a breaking change!

Adds support for setting availability_type at the read_replica level for mysql and postgresql
  • Loading branch information
g-awmalik committed Aug 4, 2022
1 parent 445e7ac commit e26861e
Show file tree
Hide file tree
Showing 16 changed files with 143 additions and 7 deletions.
2 changes: 1 addition & 1 deletion build/int.cloudbuild.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -192,4 +192,4 @@ tags:
substitutions:
_DOCKER_IMAGE_DEVELOPER_TOOLS: 'cft/developer-tools'
_DOCKER_TAG_VERSION_DEVELOPER_TOOLS: '1.3'
_API_ACTIVATION_SECONDS_WAIT: '450'
_API_ACTIVATION_SECONDS_WAIT: '600'
97 changes: 97 additions & 0 deletions docs/upgrading_to_sql_db_12.0.0.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
# Upgrading to SQL DB 12.0.0

The 12.0.0 release of SQL DB is a backward incompatible release. This incompatibility affects configuration of read replicas for `mysql`, `postgresql` and `safer_mysql` submodules.

## Migration Instructions

### Add support for setting availability_type

Prior to the 12.0.0 release, all read replicas were created using the default availability type set to `ZONAL`. The addition of `availability_type` allows explicit setting of availability type for each read replica.

```hcl
module "pg" {
source = "GoogleCloudPlatform/sql-db/google//modules/postgresql"
version = "~> 11.0"
project_id = var.project_id
region = "europe-west1"
zone = "europe-west1-d"
name = "test"
random_instance_name = true
availability_type = "ZONAL"
database_version = "POSTGRES_14"
disk_type = "PD_HDD"
disk_size = 10
disk_autoresize = true
create_timeout = "30m"
read_replicas = [
{
name = "0"
zone = "europe-west1-d"
tier = "db-f1-micro"
disk_type = "PD_HDD"
disk_size = 10
disk_autoresize = true
disk_autoresize_limit = 0
encryption_key_name = null
database_flags = []
user_labels = {}
ip_configuration = {
allocated_ip_range = null
authorized_networks = []
ipv4_enabled = true
private_network = null
require_ssl = false
}
},
]
}
```

With the 12.0.0 release, the `availability_type` string variable is presented which allows users to set the availability type of their read replicas as `ZONAL` or `REGIONAL`.

```diff
module "pg" {
source = "GoogleCloudPlatform/sql-db/google//modules/postgresql"
- version = "~> 11.0"
+ version = "~> 12.0"

project_id = var.project_id
region = "europe-west1"
zone = "europe-west1-d"
name = "test"
random_instance_name = true
availability_type = "ZONAL"
database_version = "POSTGRES_14"
disk_type = "PD_HDD"
disk_size = 10
disk_autoresize = true
create_timeout = "30m"

read_replicas = [
{
name = "0"
zone = "europe-west1-d"
tier = "db-f1-micro"
disk_type = "PD_HDD"
disk_size = 10
disk_autoresize = true
+ availability_type = "ZONAL"
disk_autoresize_limit = 0
encryption_key_name = null
database_flags = []
user_labels = {}

ip_configuration = {
allocated_ip_range = null
authorized_networks = []
ipv4_enabled = true
private_network = null
require_ssl = false
}
},
]
}
```
3 changes: 3 additions & 0 deletions examples/mysql-ha/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ module "mysql" {
{
name = "0"
zone = "us-central1-a"
availability_type = "ZONAL"
tier = "db-n1-standard-1"
ip_configuration = local.read_replica_ip_configuration
database_flags = [{ name = "long_query_time", value = 1 }]
Expand All @@ -97,6 +98,7 @@ module "mysql" {
{
name = "1"
zone = "us-central1-b"
availability_type = "ZONAL"
tier = "db-n1-standard-1"
ip_configuration = local.read_replica_ip_configuration
database_flags = [{ name = "long_query_time", value = 1 }]
Expand All @@ -110,6 +112,7 @@ module "mysql" {
{
name = "2"
zone = "us-central1-c"
availability_type = "ZONAL"
tier = "db-n1-standard-1"
ip_configuration = local.read_replica_ip_configuration
database_flags = [{ name = "long_query_time", value = 1 }]
Expand Down
3 changes: 3 additions & 0 deletions examples/postgresql-ha/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ module "pg" {
{
name = "0"
zone = "us-central1-a"
availability_type = "REGIONAL"
tier = "db-custom-1-3840"
ip_configuration = local.read_replica_ip_configuration
database_flags = [{ name = "autovacuum", value = "off" }]
Expand All @@ -96,6 +97,7 @@ module "pg" {
{
name = "1"
zone = "us-central1-b"
availability_type = "REGIONAL"
tier = "db-custom-1-3840"
ip_configuration = local.read_replica_ip_configuration
database_flags = [{ name = "autovacuum", value = "off" }]
Expand All @@ -109,6 +111,7 @@ module "pg" {
{
name = "2"
zone = "us-central1-c"
availability_type = "REGIONAL"
tier = "db-custom-1-3840"
ip_configuration = local.read_replica_ip_configuration
database_flags = [{ name = "autovacuum", value = "off" }]
Expand Down
2 changes: 1 addition & 1 deletion modules/mysql/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,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. 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_autoresize_limit = number<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> allocated_ip_range = string<br> })<br> encryption_key_name = string<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> availability_type = string<br> disk_type = string<br> disk_autoresize = bool<br> disk_autoresize_limit = number<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> allocated_ip_range = string<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
1 change: 1 addition & 0 deletions modules/mysql/read_replica.tf
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ resource "google_sql_database_instance" "replicas" {
settings {
tier = lookup(each.value, "tier", var.tier)
activation_policy = "ALWAYS"
availability_type = lookup(each.value, "availability_type", var.availability_type)

dynamic "ip_configuration" {
for_each = [lookup(each.value, "ip_configuration", {})]
Expand Down
1 change: 1 addition & 0 deletions modules/mysql/variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,7 @@ variable "read_replicas" {
name = string
tier = string
zone = string
availability_type = string
disk_type = string
disk_autoresize = bool
disk_autoresize_limit = number
Expand Down
2 changes: 1 addition & 1 deletion modules/postgresql/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,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. 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_autoresize_limit = number<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> allocated_ip_range = string<br> })<br> encryption_key_name = string<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> availability_type = string<br> zone = string<br> disk_type = string<br> disk_autoresize = bool<br> disk_autoresize_limit = number<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> allocated_ip_range = string<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
8 changes: 6 additions & 2 deletions modules/postgresql/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,10 @@ locals {
is_account_sa = trimsuffix(iu, "gserviceaccount.com") == iu ? false : true
}]

// HA method using REGIONAL availability_type requires point in time recovery to be enabled
point_in_time_recovery_enabled = var.availability_type == "REGIONAL" ? true : lookup(var.backup_configuration, "point_in_time_recovery_enabled", false)
backups_enabled = var.availability_type == "REGIONAL" ? true : lookup(var.backup_configuration, "enabled", false)

retained_backups = lookup(var.backup_configuration, "retained_backups", null)
retention_unit = lookup(var.backup_configuration, "retention_unit", null)
}
Expand Down Expand Up @@ -59,10 +63,10 @@ resource "google_sql_database_instance" "default" {
for_each = [var.backup_configuration]
content {
binary_log_enabled = false
enabled = lookup(backup_configuration.value, "enabled", null)
enabled = local.backups_enabled
start_time = lookup(backup_configuration.value, "start_time", null)
location = lookup(backup_configuration.value, "location", null)
point_in_time_recovery_enabled = lookup(backup_configuration.value, "point_in_time_recovery_enabled", false)
point_in_time_recovery_enabled = local.point_in_time_recovery_enabled
transaction_log_retention_days = lookup(backup_configuration.value, "transaction_log_retention_days", null)

dynamic "backup_retention_settings" {
Expand Down
1 change: 1 addition & 0 deletions modules/postgresql/read_replica.tf
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ resource "google_sql_database_instance" "replicas" {
settings {
tier = lookup(each.value, "tier", var.tier)
activation_policy = "ALWAYS"
availability_type = lookup(each.value, "availability_type", var.availability_type)

dynamic "ip_configuration" {
for_each = [lookup(each.value, "ip_configuration", {})]
Expand Down
1 change: 1 addition & 0 deletions modules/postgresql/variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,7 @@ variable "read_replicas" {
type = list(object({
name = string
tier = string
availability_type = string
zone = string
disk_type = string
disk_autoresize = bool
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 @@ -194,7 +194,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. 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_autoresize_limit = number<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> allocated_ip_range = string<br> })<br> encryption_key_name = string<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> availability_type = string<br> zone = string<br> disk_type = string<br> disk_autoresize = bool<br> disk_autoresize_limit = number<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> allocated_ip_range = string<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
1 change: 1 addition & 0 deletions modules/safer_mysql/variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,7 @@ variable "read_replicas" {
type = list(object({
name = string
tier = string
availability_type = string
zone = string
disk_type = string
disk_autoresize = bool
Expand Down
12 changes: 12 additions & 0 deletions test/fixtures/mssql-ha/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,18 @@
* limitations under the License.
*/

terraform {
required_providers {
google = {
source = "hashicorp/google"
/*
Pinning this version due to an upstream provider issue: https://github.com/hashicorp/terraform-provider-google/issues/11891
*/
version = "4.24.0"
}
}
}

provider "google" {
region = var.region
}
Expand Down
12 changes: 12 additions & 0 deletions test/fixtures/mssql-public/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,18 @@
* limitations under the License.
*/

terraform {
required_providers {
google = {
source = "hashicorp/google"
/*
Pinning this version due to an upstream provider issue: https://github.com/hashicorp/terraform-provider-google/issues/11891
*/
version = "4.24.0"
}
}
}

resource "random_id" "instance_name_suffix" {
byte_length = 5
}
Expand Down
2 changes: 1 addition & 1 deletion test/integration/postgresql-ha/postgresql_ha_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ func TestPostgreSqlHaModule(t *testing.T) {
// replica specific validation
} else {
// assert general database settings
assert.Equal("ZONAL", op.Get("settings.availabilityType").String(), "Expected ZONAL availabilityType")
assert.Equal("REGIONAL", op.Get("settings.availabilityType").String(), "Expected REGIONAL availabilityType")
assert.Equal("PD_HDD", op.Get("settings.dataDiskType").String(), "Expected PD_HDD dataDiskType")
assert.False(op.Get("settings.ipConfiguration.requireSsl").Bool(), "Expected FALSE SSL")

Expand Down

0 comments on commit e26861e

Please sign in to comment.