From 5c491b36570fd4aeb0ae4f1560fadb41ee4b68f2 Mon Sep 17 00:00:00 2001 From: Wayne Nugent Date: Sat, 3 May 2025 10:44:11 +0100 Subject: [PATCH 1/4] feat: Adding new variables to define failover dr replica --- modules/mysql/README.md | 1 + modules/mysql/main.tf | 7 +++++++ modules/mysql/metadata.yaml | 5 ++++- modules/mysql/variables.tf | 7 +++++++ modules/postgresql/README.md | 1 + modules/postgresql/main.tf | 7 +++++++ modules/postgresql/metadata.yaml | 5 ++++- modules/postgresql/variables.tf | 6 ++++++ 8 files changed, 37 insertions(+), 2 deletions(-) diff --git a/modules/mysql/README.md b/modules/mysql/README.md index fd04ca34..c1422e23 100644 --- a/modules/mysql/README.md +++ b/modules/mysql/README.md @@ -74,6 +74,7 @@ module "mysql-db" { | enable\_google\_ml\_integration | Enable database ML integration | `bool` | `false` | no | | enable\_random\_password\_special | Enable special characters in generated random passwords. | `bool` | `false` | no | | encryption\_key\_name | The full path to the encryption key used for the CMEK disk encryption | `string` | `null` | no | +| failover\_dr\_replica\_name | If the instance is a primary instance, then this field identifies the disaster recovery (DR) replica. The standard format of this field is "your-project:your-instance". You can also set this field to "your-instance", but cloud SQL backend will convert it to the aforementioned standard format. | `string` | `null` | no | | follow\_gae\_application | A Google App Engine application whose zone to remain in. Must be in the same region as this instance. | `string` | `null` | no | | iam\_users | A list of IAM users to be created in your CloudSQL instance. iam.users.type can be CLOUD\_IAM\_USER, CLOUD\_IAM\_SERVICE\_ACCOUNT, CLOUD\_IAM\_GROUP and is required for type CLOUD\_IAM\_GROUP (IAM groups) |
list(object({
id = string,
email = string,
type = optional(string)
}))
| `[]` | no | | insights\_config | The insights\_config settings for the database. |
object({
query_plans_per_minute = number
query_string_length = number
record_application_tags = bool
record_client_address = bool
})
| `null` | no | diff --git a/modules/mysql/main.tf b/modules/mysql/main.tf index 5e5fb841..bd14dbd8 100644 --- a/modules/mysql/main.tf +++ b/modules/mysql/main.tf @@ -64,6 +64,13 @@ resource "google_sql_database_instance" "default" { deletion_protection = var.deletion_protection root_password = var.root_password == "" ? null : var.root_password + dynamic "replication_cluster" { + for_each = var.failover_dr_replica_name != null ? [var.failover_dr_replica_name] : [] + content { + failover_dr_replica_name = var.failover_dr_replica_name + } + } + settings { tier = var.tier edition = var.edition diff --git a/modules/mysql/metadata.yaml b/modules/mysql/metadata.yaml index 22cd2856..2157d8f1 100644 --- a/modules/mysql/metadata.yaml +++ b/modules/mysql/metadata.yaml @@ -182,6 +182,9 @@ spec: - name: master_instance_name description: The name of the existing instance that will act as the master in the replication setup. varType: string + - name: failover_dr_replica_name + description: If the instance is a primary instance, then this field identifies the disaster recovery (DR) replica. The standard format of this field is "your-project:your-instance". You can also set this field to "your-instance", but cloud SQL backend will convert it to the aforementioned standard format. + varType: string - name: instance_type description: Users can upgrade a read replica instance to a stand-alone Cloud SQL instance with the help of instance_type. To promote, users have to set the instance_type property as CLOUD_SQL_INSTANCE and remove/unset master_instance_name and replica_configuration from instance configuration. This operation might cause your instance to restart. varType: string @@ -943,4 +946,4 @@ spec: - source: hashicorp/null version: ~> 3.1 - source: hashicorp/random - version: ~> 3.1 + version: ~> 3.1 \ No newline at end of file diff --git a/modules/mysql/variables.tf b/modules/mysql/variables.tf index 500cff56..2be0451e 100644 --- a/modules/mysql/variables.tf +++ b/modules/mysql/variables.tf @@ -169,6 +169,13 @@ variable "master_instance_name" { default = null } +//optional +variable "failover_dr_replica_name" { + type = string + description = "If the instance is a primary instance, then this field identifies the disaster recovery (DR) replica. The standard format of this field is \"your-project:your-instance\". You can also set this field to \"your-instance\", but cloud SQL backend will convert it to the aforementioned standard format." + default = null +} + // optional variable "instance_type" { description = "Users can upgrade a read replica instance to a stand-alone Cloud SQL instance with the help of instance_type. To promote, users have to set the instance_type property as CLOUD_SQL_INSTANCE and remove/unset master_instance_name and replica_configuration from instance configuration. This operation might cause your instance to restart." diff --git a/modules/postgresql/README.md b/modules/postgresql/README.md index e9b83d3d..9b9a7859 100644 --- a/modules/postgresql/README.md +++ b/modules/postgresql/README.md @@ -146,6 +146,7 @@ module "pg" { | enable\_google\_ml\_integration | Enable database ML integration | `bool` | `false` | no | | enable\_random\_password\_special | Enable special characters in generated random passwords. | `bool` | `false` | no | | encryption\_key\_name | The full path to the encryption key used for the CMEK disk encryption | `string` | `null` | no | +| failover\_dr\_replica\_name | If the instance is a primary instance, then this field identifies the disaster recovery (DR) replica. The standard format of this field is "your-project:your-instance". You can also set this field to "your-instance", but cloud SQL backend will convert it to the aforementioned standard format. | `string` | `null` | no | | follow\_gae\_application | A Google App Engine application whose zone to remain in. Must be in the same region as this instance. | `string` | `null` | no | | iam\_users | A list of IAM users to be created in your CloudSQL instance. iam.users.type can be CLOUD\_IAM\_USER, CLOUD\_IAM\_SERVICE\_ACCOUNT, CLOUD\_IAM\_GROUP and is required for type CLOUD\_IAM\_GROUP (IAM groups) |
list(object({
id = string,
email = string,
type = optional(string)
}))
| `[]` | no | | insights\_config | The insights\_config settings for the database. |
object({
query_plans_per_minute = optional(number, 5)
query_string_length = optional(number, 1024)
record_application_tags = optional(bool, false)
record_client_address = optional(bool, false)
})
| `null` | no | diff --git a/modules/postgresql/main.tf b/modules/postgresql/main.tf index bb9d4629..4b4fd2aa 100644 --- a/modules/postgresql/main.tf +++ b/modules/postgresql/main.tf @@ -69,6 +69,13 @@ resource "google_sql_database_instance" "default" { master_instance_name = var.master_instance_name instance_type = local.is_secondary_instance ? "READ_REPLICA_INSTANCE" : var.instance_type + dynamic "replication_cluster" { + for_each = var.failover_dr_replica_name != null ? [var.failover_dr_replica_name] : [] + content { + failover_dr_replica_name = var.failover_dr_replica_name + } + } + settings { tier = var.tier edition = var.edition diff --git a/modules/postgresql/metadata.yaml b/modules/postgresql/metadata.yaml index e9572116..8afb22b4 100644 --- a/modules/postgresql/metadata.yaml +++ b/modules/postgresql/metadata.yaml @@ -154,6 +154,9 @@ spec: - name: master_instance_name description: Name of the master instance if this is a failover replica. Required for creating failover replica instance. Not needed for master instance. When removed, next terraform apply will promote this failover failover replica instance as master instance varType: string + - name: failover_dr_replica_name + description: If the instance is a primary instance, then this field identifies the disaster recovery (DR) replica. The standard format of this field is "your-project:your-instance". You can also set this field to "your-instance", but cloud SQL backend will convert it to the aforementioned standard format. + varType: string - name: instance_type description: The type of the instance. The supported values are SQL_INSTANCE_TYPE_UNSPECIFIED, CLOUD_SQL_INSTANCE, ON_PREMISES_INSTANCE and READ_REPLICA_INSTANCE. Set to READ_REPLICA_INSTANCE if master_instance_name value is provided varType: string @@ -939,4 +942,4 @@ spec: - source: hashicorp/null version: ~> 3.1 - source: hashicorp/random - version: ~> 3.1 + version: ~> 3.1 \ No newline at end of file diff --git a/modules/postgresql/variables.tf b/modules/postgresql/variables.tf index c7172a8d..e05b5844 100644 --- a/modules/postgresql/variables.tf +++ b/modules/postgresql/variables.tf @@ -158,6 +158,12 @@ variable "master_instance_name" { default = null } +variable "failover_dr_replica_name" { + type = string + description = "If the instance is a primary instance, then this field identifies the disaster recovery (DR) replica. The standard format of this field is \"your-project:your-instance\". You can also set this field to \"your-instance\", but cloud SQL backend will convert it to the aforementioned standard format." + default = null +} + variable "instance_type" { type = string description = "The type of the instance. The supported values are SQL_INSTANCE_TYPE_UNSPECIFIED, CLOUD_SQL_INSTANCE, ON_PREMISES_INSTANCE and READ_REPLICA_INSTANCE. Set to READ_REPLICA_INSTANCE if master_instance_name value is provided" From 977c8c5c4fe77e26a1cf3224ec27b09f4cef7b79 Mon Sep 17 00:00:00 2001 From: Wayne Nugent Date: Fri, 16 May 2025 15:14:56 +0100 Subject: [PATCH 2/4] feat: dr replica fixing whitespace issue with linting --- modules/mysql/metadata.yaml | 2 +- modules/postgresql/metadata.yaml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/mysql/metadata.yaml b/modules/mysql/metadata.yaml index 2157d8f1..8acaf37c 100644 --- a/modules/mysql/metadata.yaml +++ b/modules/mysql/metadata.yaml @@ -946,4 +946,4 @@ spec: - source: hashicorp/null version: ~> 3.1 - source: hashicorp/random - version: ~> 3.1 \ No newline at end of file + version: ~> 3.1 diff --git a/modules/postgresql/metadata.yaml b/modules/postgresql/metadata.yaml index 8afb22b4..a9bd516c 100644 --- a/modules/postgresql/metadata.yaml +++ b/modules/postgresql/metadata.yaml @@ -942,4 +942,4 @@ spec: - source: hashicorp/null version: ~> 3.1 - source: hashicorp/random - version: ~> 3.1 \ No newline at end of file + version: ~> 3.1 From 0375fa807c34dea30ccf103851f968ad5a314ded Mon Sep 17 00:00:00 2001 From: Wayne Nugent Date: Mon, 19 May 2025 20:34:50 +0100 Subject: [PATCH 3/4] feat: dr replica updating minimum version for google providers --- docs/upgrading_to_sql_db_26.0.md | 5 +++++ modules/mysql/versions.tf | 4 ++-- modules/postgresql/versions.tf | 4 ++-- 3 files changed, 9 insertions(+), 4 deletions(-) create mode 100644 docs/upgrading_to_sql_db_26.0.md diff --git a/docs/upgrading_to_sql_db_26.0.md b/docs/upgrading_to_sql_db_26.0.md new file mode 100644 index 00000000..957021a0 --- /dev/null +++ b/docs/upgrading_to_sql_db_26.0.md @@ -0,0 +1,5 @@ +# Upgrading to v26.0 + +The v26.0 release contains backwards-incompatible changes. + +This update requires upgrading the minimum provider version from `6.1` to `6.17` diff --git a/modules/mysql/versions.tf b/modules/mysql/versions.tf index d81c8469..ab1c32bd 100644 --- a/modules/mysql/versions.tf +++ b/modules/mysql/versions.tf @@ -27,11 +27,11 @@ terraform { } google = { source = "hashicorp/google" - version = ">= 6.1, < 7" + version = ">= 6.17, < 7" } google-beta = { source = "hashicorp/google-beta" - version = ">= 6.1, < 7" + version = ">= 6.17, < 7" } } diff --git a/modules/postgresql/versions.tf b/modules/postgresql/versions.tf index 820655c0..5700838a 100644 --- a/modules/postgresql/versions.tf +++ b/modules/postgresql/versions.tf @@ -27,11 +27,11 @@ terraform { } google = { source = "hashicorp/google" - version = ">= 6.1, < 7" + version = ">= 6.17, < 7" } google-beta = { source = "hashicorp/google-beta" - version = ">= 6.1, < 7" + version = ">= 6.17, < 7" } } From d7e751f913b6286f8e33c28cd525d2fd2693819b Mon Sep 17 00:00:00 2001 From: Wayne Nugent Date: Mon, 19 May 2025 20:36:34 +0100 Subject: [PATCH 4/4] feat: dr replica adding dr failover to safer_mysql module --- modules/safer_mysql/README.md | 3 +++ modules/safer_mysql/main.tf | 3 +++ modules/safer_mysql/metadata.yaml | 9 +++++++++ modules/safer_mysql/variables.tf | 21 +++++++++++++++++++++ modules/safer_mysql/versions.tf | 2 +- 5 files changed, 37 insertions(+), 1 deletion(-) diff --git a/modules/safer_mysql/README.md b/modules/safer_mysql/README.md index 0fb9b364..a64f2486 100644 --- a/modules/safer_mysql/README.md +++ b/modules/safer_mysql/README.md @@ -264,13 +264,16 @@ module "safer-mysql-db" { | enable\_default\_db | Enable or disable the creation of the default database | `bool` | `true` | no | | enable\_default\_user | Enable or disable the creation of the default user | `bool` | `true` | no | | encryption\_key\_name | The full path to the encryption key used for the CMEK disk encryption | `string` | `null` | no | +| failover\_dr\_replica\_name | If the instance is a primary instance, then this field identifies the disaster recovery (DR) replica. The standard format of this field is "your-project:your-instance". You can also set this field to "your-instance", but cloud SQL backend will convert it to the aforementioned standard format. | `string` | `null` | no | | follow\_gae\_application | A Google App Engine application whose zone to remain in. Must be in the same region as this instance. | `string` | `null` | no | | iam\_users | A list of IAM users to be created in your CloudSQL instance. iam.users.type can be CLOUD\_IAM\_USER, CLOUD\_IAM\_SERVICE\_ACCOUNT, CLOUD\_IAM\_GROUP and is required for type CLOUD\_IAM\_GROUP (IAM groups) |
list(object({
id = string,
email = string,
type = optional(string)
}))
| `[]` | no | | insights\_config | The insights\_config settings for the database. |
object({
query_plans_per_minute = number
query_string_length = number
record_application_tags = bool
record_client_address = bool
})
| `null` | no | +| instance\_type | Users can upgrade a read replica instance to a stand-alone Cloud SQL instance with the help of instance\_type. To promote, users have to set the instance\_type property as CLOUD\_SQL\_INSTANCE and remove/unset master\_instance\_name and replica\_configuration from instance configuration. This operation might cause your instance to restart. | `string` | `null` | no | | maintenance\_version | The current software version on the instance. This attribute can not be set during creation. Refer to available\_maintenance\_versions attribute to see what maintenance\_version are available for upgrade. When this attribute gets updated, it will cause an instance restart. Setting a maintenance\_version value that is older than the current one on the instance will be ignored | `string` | `null` | no | | maintenance\_window\_day | The day of week (1-7) for the master instance maintenance. | `number` | `1` | no | | maintenance\_window\_hour | The hour of day (0-23) maintenance window for the master instance maintenance. | `number` | `23` | no | | maintenance\_window\_update\_track | The update track of maintenance window for the master instance maintenance. Can be either `canary` or `stable`. | `string` | `"stable"` | no | +| master\_instance\_name | The name of the existing instance that will act as the master in the replication setup. | `string` | `null` | no | | module\_depends\_on | List of modules or resources this module depends on. | `list(any)` | `[]` | no | | name | The name of the Cloud SQL resources | `string` | n/a | yes | | pricing\_plan | The pricing plan for the master instance. | `string` | `"PER_USE"` | no | diff --git a/modules/safer_mysql/main.tf b/modules/safer_mysql/main.tf index 974556ff..d3e784cf 100644 --- a/modules/safer_mysql/main.tf +++ b/modules/safer_mysql/main.tf @@ -24,6 +24,9 @@ module "safer_mysql" { region = var.region zone = var.zone secondary_zone = var.secondary_zone + master_instance_name = var.master_instance_name + failover_dr_replica_name = var.failover_dr_replica_name + instance_type = var.instance_type follow_gae_application = var.follow_gae_application tier = var.tier edition = var.edition diff --git a/modules/safer_mysql/metadata.yaml b/modules/safer_mysql/metadata.yaml index f5494ae8..26e0b6e5 100644 --- a/modules/safer_mysql/metadata.yaml +++ b/modules/safer_mysql/metadata.yaml @@ -192,6 +192,9 @@ spec: - name: encryption_key_name description: The full path to the encryption key used for the CMEK disk encryption varType: string + - name: failover_dr_replica_name + description: If the instance is a primary instance, then this field identifies the disaster recovery (DR) replica. The standard format of this field is "your-project:your-instance". You can also set this field to "your-instance", but cloud SQL backend will convert it to the aforementioned standard format. + varType: string - name: follow_gae_application description: A Google App Engine application whose zone to remain in. Must be in the same region as this instance. varType: string @@ -212,6 +215,9 @@ spec: record_application_tags = bool record_client_address = bool }) + - name: instance_type + description: Users can upgrade a read replica instance to a stand-alone Cloud SQL instance with the help of instance_type. To promote, users have to set the instance_type property as CLOUD_SQL_INSTANCE and remove/unset master_instance_name and replica_configuration from instance configuration. This operation might cause your instance to restart. + varType: string - name: maintenance_window_day description: The day of week (1-7) for the master instance maintenance. varType: number @@ -224,6 +230,9 @@ spec: description: The update track of maintenance window for the master instance maintenance. Can be either `canary` or `stable`. varType: string defaultValue: stable + - name: master_instance_name + description: The name of the existing instance that will act as the master in the replication setup. + varType: string - name: module_depends_on description: List of modules or resources this module depends on. varType: list(any) diff --git a/modules/safer_mysql/variables.tf b/modules/safer_mysql/variables.tf index 3cf1f886..33e37357 100644 --- a/modules/safer_mysql/variables.tf +++ b/modules/safer_mysql/variables.tf @@ -85,6 +85,27 @@ variable "secondary_zone" { default = null } +// optional +variable "master_instance_name" { + description = "The name of the existing instance that will act as the master in the replication setup." + type = string + default = null +} + +//optional +variable "failover_dr_replica_name" { + type = string + description = "If the instance is a primary instance, then this field identifies the disaster recovery (DR) replica. The standard format of this field is \"your-project:your-instance\". You can also set this field to \"your-instance\", but cloud SQL backend will convert it to the aforementioned standard format." + default = null +} + +// optional +variable "instance_type" { + description = "Users can upgrade a read replica instance to a stand-alone Cloud SQL instance with the help of instance_type. To promote, users have to set the instance_type property as CLOUD_SQL_INSTANCE and remove/unset master_instance_name and replica_configuration from instance configuration. This operation might cause your instance to restart." + type = string + default = null +} + variable "follow_gae_application" { type = string description = "A Google App Engine application whose zone to remain in. Must be in the same region as this instance." diff --git a/modules/safer_mysql/versions.tf b/modules/safer_mysql/versions.tf index bc5f2f40..d20bdb38 100644 --- a/modules/safer_mysql/versions.tf +++ b/modules/safer_mysql/versions.tf @@ -20,7 +20,7 @@ terraform { google = { source = "hashicorp/google" - version = ">= 6.1, < 7" + version = ">= 6.17, < 7" } }