Skip to content

Commit 68b27b4

Browse files
Mark the psa_write_endpoint field as Computed and relax the constraint so that the replication cluster is set if there is a DR replica set or there is a PSA write endpoint (#15921)
Co-authored-by: Zhenhua Li <[email protected]>
1 parent 47e9bc8 commit 68b27b4

File tree

3 files changed

+310
-5
lines changed

3 files changed

+310
-5
lines changed

mmv1/third_party/terraform/services/sql/resource_sql_database_instance.go.tmpl

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1224,6 +1224,7 @@ API (for read pools, effective_availability_type may differ from availability_ty
12241224
"psa_write_endpoint": {
12251225
Type: schema.TypeString,
12261226
Optional: true,
1227+
Computed: true,
12271228
Description: fmt.Sprintf(`If set, this field indicates this instance has a private service access (PSA) DNS endpoint that is pointing to the primary instance of the cluster. If this instance is the primary, then the DNS endpoint points to this instance. After a switchover or replica failover operation, this DNS endpoint points to the promoted instance. This is a read-only field, returned to the user as information. This field can exist even if a standalone instance doesn't have a DR replica yet or the DR replica is deleted.`),
12281229
},
12291230
"failover_dr_replica_name": {
@@ -1239,7 +1240,7 @@ API (for read pools, effective_availability_type may differ from availability_ty
12391240
},
12401241
},
12411242
},
1242-
Description: "A primary instance and disaster recovery replica pair. Applicable to MySQL and PostgreSQL. This field can be set only after both the primary and replica are created.",
1243+
Description: "A primary instance and disaster recovery replica pair. Applicable to MySQL and PostgreSQL. This field can be set if the primary has psa_write_endpoint set or both the primary and replica are created.",
12431244
},
12441245
"server_ca_cert": {
12451246
Type: schema.TypeList,
@@ -2596,9 +2597,21 @@ func resourceSqlDatabaseInstanceUpdate(d *schema.ResourceData, meta interface{})
25962597
}
25972598

25982599
failoverDrReplicaName := d.Get("replication_cluster.0.failover_dr_replica_name").(string)
2599-
if failoverDrReplicaName != "" {
2600-
instance.ReplicationCluster = &sqladmin.ReplicationCluster{
2601-
FailoverDrReplicaName: failoverDrReplicaName,
2600+
psaWriteEndpoint := d.Get("replication_cluster.0.psa_write_endpoint").(string)
2601+
if failoverDrReplicaName != "" || psaWriteEndpoint != "" {
2602+
if failoverDrReplicaName != "" && psaWriteEndpoint != "" {
2603+
instance.ReplicationCluster = &sqladmin.ReplicationCluster{
2604+
FailoverDrReplicaName: failoverDrReplicaName,
2605+
PsaWriteEndpoint: psaWriteEndpoint,
2606+
}
2607+
} else if failoverDrReplicaName != "" {
2608+
instance.ReplicationCluster = &sqladmin.ReplicationCluster{
2609+
FailoverDrReplicaName: failoverDrReplicaName,
2610+
}
2611+
} else {
2612+
instance.ReplicationCluster = &sqladmin.ReplicationCluster{
2613+
PsaWriteEndpoint: psaWriteEndpoint,
2614+
}
26022615
}
26032616
}
26042617

mmv1/third_party/terraform/services/sql/resource_sql_database_instance_test.go.tmpl

Lines changed: 292 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3064,6 +3064,84 @@ func TestAccSqlDatabaseInstance_SwitchoverSuccess(t *testing.T) {
30643064
})
30653065
}
30663066

3067+
func TestAccSqlDatabaseInstance_MysqlEplusWithFailoverReplicaSetupWithPrivateNetwork(t *testing.T) {
3068+
t.Parallel()
3069+
3070+
primaryName := "tf-test-mysql-primary-" + acctest.RandString(t, 10)
3071+
replicaName := "tf-test-mysql-replica-" + acctest.RandString(t, 10)
3072+
networkName := acctest.BootstrapSharedServiceNetworkingConnection(t, "endpoint")
3073+
projectId := envvar.GetTestProjectFromEnv()
3074+
3075+
acctest.VcrTest(t, resource.TestCase{
3076+
PreCheck: func() { acctest.AccTestPreCheck(t) },
3077+
ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories(t),
3078+
CheckDestroy: testAccSqlDatabaseInstanceDestroyProducer(t),
3079+
Steps: []resource.TestStep{
3080+
{
3081+
Config: testGoogleSqlDatabaseInstance_mySqlEplusPrimaryReplicaSetupWithPrivateNetwork(projectId, primaryName, replicaName, networkName, "MYSQL_8_0"),
3082+
Check: resource.ComposeTestCheckFunc(verifyCreateOperationOnEplusWithPrivateNetwork("google_sql_database_instance.primary")),
3083+
},
3084+
{
3085+
ResourceName: "google_sql_database_instance.primary",
3086+
ImportState: true,
3087+
ImportStateVerify: true,
3088+
ImportStateIdPrefix: fmt.Sprintf("%s/", projectId),
3089+
ImportStateVerifyIgnore: []string{"deletion_protection"},
3090+
},
3091+
{
3092+
ResourceName: "google_sql_database_instance.replica",
3093+
ImportState: true,
3094+
ImportStateVerify: true,
3095+
ImportStateIdPrefix: fmt.Sprintf("%s/", projectId),
3096+
ImportStateVerifyIgnore: []string{"deletion_protection"},
3097+
},
3098+
{
3099+
Config: testGoogleSqlDatabaseInstance_setMySqlFailoverReplicaEplusWithPrivateNetwork(projectId, primaryName, replicaName, networkName, "MYSQL_8_0"),
3100+
Check: resource.ComposeTestCheckFunc(verifyCreateOperationOnEplusWithPrivateNetwork("google_sql_database_instance.primary")),
3101+
},
3102+
},
3103+
})
3104+
}
3105+
3106+
func TestAccSqlDatabaseInstance_PostgresEplusWithFailoverReplicaSetupWithPrivateNetwork(t *testing.T) {
3107+
t.Parallel()
3108+
3109+
primaryName := "tf-test-postgres-primary-" + acctest.RandString(t, 10)
3110+
replicaName := "tf-test-postgres-replica-" + acctest.RandString(t, 10)
3111+
networkName := acctest.BootstrapSharedServiceNetworkingConnection(t, "endpoint")
3112+
projectId := envvar.GetTestProjectFromEnv()
3113+
3114+
acctest.VcrTest(t, resource.TestCase{
3115+
PreCheck: func() { acctest.AccTestPreCheck(t) },
3116+
ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories(t),
3117+
CheckDestroy: testAccSqlDatabaseInstanceDestroyProducer(t),
3118+
Steps: []resource.TestStep{
3119+
{
3120+
Config: testGoogleSqlDatabaseInstance_postgresEplusPrimaryReplicaSetupWithPrivateNetwork(projectId, primaryName, replicaName, networkName, "POSTGRES_12"),
3121+
Check: resource.ComposeTestCheckFunc(verifyCreateOperationOnEplusWithPrivateNetwork("google_sql_database_instance.primary")),
3122+
},
3123+
{
3124+
ResourceName: "google_sql_database_instance.primary",
3125+
ImportState: true,
3126+
ImportStateVerify: true,
3127+
ImportStateIdPrefix: fmt.Sprintf("%s/", projectId),
3128+
ImportStateVerifyIgnore: []string{"deletion_protection"},
3129+
},
3130+
{
3131+
ResourceName: "google_sql_database_instance.replica",
3132+
ImportState: true,
3133+
ImportStateVerify: true,
3134+
ImportStateIdPrefix: fmt.Sprintf("%s/", projectId),
3135+
ImportStateVerifyIgnore: []string{"deletion_protection"},
3136+
},
3137+
{
3138+
Config: testGoogleSqlDatabaseInstance_setPostgresFailoverReplicaEplusWithPrivateNetwork(projectId, primaryName, replicaName, networkName, "POSTGRES_12"),
3139+
Check: resource.ComposeTestCheckFunc(verifyCreateOperationOnEplusWithPrivateNetwork("google_sql_database_instance.primary")),
3140+
},
3141+
},
3142+
})
3143+
}
3144+
30673145
func TestAccSqlDatabaseInstance_MysqlEplusWithPrivateNetwork(t *testing.T) {
30683146
t.Parallel()
30693147

@@ -5220,6 +5298,220 @@ resource "google_sql_database_instance" "original-replica" {
52205298
`, project, primaryName, project, replicaName)
52215299
}
52225300

5301+
func testGoogleSqlDatabaseInstance_setMySqlFailoverReplicaEplusWithPrivateNetwork(project, primaryName, replicaName, networkName, databaseVersion string) string {
5302+
5303+
return fmt.Sprintf(`
5304+
data "google_compute_network" "servicenet" {
5305+
name = "%s"
5306+
}
5307+
5308+
resource "google_sql_database_instance" "primary" {
5309+
project = "%s"
5310+
name = "%s"
5311+
region = "us-east1"
5312+
database_version = "%s"
5313+
instance_type = "CLOUD_SQL_INSTANCE"
5314+
deletion_protection = false
5315+
5316+
replication_cluster {
5317+
failover_dr_replica_name = "%s"
5318+
}
5319+
5320+
settings {
5321+
tier = "db-perf-optimized-N-2"
5322+
edition = "ENTERPRISE_PLUS"
5323+
ip_configuration {
5324+
ipv4_enabled = false
5325+
private_network = data.google_compute_network.servicenet.self_link
5326+
}
5327+
backup_configuration {
5328+
enabled = true
5329+
binary_log_enabled = true
5330+
}
5331+
}
5332+
}
5333+
5334+
resource "google_sql_database_instance" "replica" {
5335+
project = "%s"
5336+
name = "%s"
5337+
region = "us-west2"
5338+
database_version = "%s"
5339+
instance_type = "READ_REPLICA_INSTANCE"
5340+
master_instance_name = google_sql_database_instance.primary.name
5341+
deletion_protection = false
5342+
5343+
settings {
5344+
tier = "db-perf-optimized-N-2"
5345+
edition = "ENTERPRISE_PLUS"
5346+
ip_configuration {
5347+
ipv4_enabled = false
5348+
private_network = data.google_compute_network.servicenet.self_link
5349+
}
5350+
backup_configuration {
5351+
binary_log_enabled = true
5352+
}
5353+
}
5354+
}
5355+
`, networkName, project, primaryName, databaseVersion, replicaName, project, replicaName, databaseVersion)
5356+
}
5357+
5358+
func testGoogleSqlDatabaseInstance_setPostgresFailoverReplicaEplusWithPrivateNetwork(project, primaryName, replicaName, networkName, databaseVersion string) string {
5359+
5360+
return fmt.Sprintf(`
5361+
data "google_compute_network" "servicenet" {
5362+
name = "%s"
5363+
}
5364+
5365+
resource "google_sql_database_instance" "primary" {
5366+
project = "%s"
5367+
name = "%s"
5368+
region = "us-east1"
5369+
database_version = "%s"
5370+
instance_type = "CLOUD_SQL_INSTANCE"
5371+
deletion_protection = false
5372+
5373+
replication_cluster {
5374+
failover_dr_replica_name = "%s"
5375+
}
5376+
5377+
settings {
5378+
tier = "db-perf-optimized-N-2"
5379+
edition = "ENTERPRISE_PLUS"
5380+
ip_configuration {
5381+
ipv4_enabled = false
5382+
private_network = data.google_compute_network.servicenet.self_link
5383+
}
5384+
backup_configuration {
5385+
enabled = true
5386+
point_in_time_recovery_enabled = true
5387+
}
5388+
}
5389+
}
5390+
5391+
resource "google_sql_database_instance" "replica" {
5392+
project = "%s"
5393+
name = "%s"
5394+
region = "us-west2"
5395+
database_version = "%s"
5396+
instance_type = "READ_REPLICA_INSTANCE"
5397+
master_instance_name = google_sql_database_instance.primary.name
5398+
deletion_protection = false
5399+
5400+
settings {
5401+
tier = "db-perf-optimized-N-2"
5402+
edition = "ENTERPRISE_PLUS"
5403+
ip_configuration {
5404+
ipv4_enabled = false
5405+
private_network = data.google_compute_network.servicenet.self_link
5406+
}
5407+
}
5408+
}
5409+
`, networkName, project, primaryName, databaseVersion, replicaName, project, replicaName, databaseVersion)
5410+
}
5411+
5412+
func testGoogleSqlDatabaseInstance_mySqlEplusPrimaryReplicaSetupWithPrivateNetwork(project, primaryName, replicaName, networkName, databaseVersion string) string {
5413+
5414+
return fmt.Sprintf(`
5415+
data "google_compute_network" "servicenet" {
5416+
name = "%s"
5417+
}
5418+
5419+
resource "google_sql_database_instance" "primary" {
5420+
project = "%s"
5421+
name = "%s"
5422+
region = "us-east1"
5423+
database_version = "%s"
5424+
instance_type = "CLOUD_SQL_INSTANCE"
5425+
deletion_protection = false
5426+
5427+
settings {
5428+
tier = "db-perf-optimized-N-2"
5429+
edition = "ENTERPRISE_PLUS"
5430+
ip_configuration {
5431+
ipv4_enabled = false
5432+
private_network = data.google_compute_network.servicenet.self_link
5433+
}
5434+
backup_configuration {
5435+
enabled = true
5436+
binary_log_enabled = true
5437+
}
5438+
}
5439+
}
5440+
5441+
resource "google_sql_database_instance" "replica" {
5442+
project = "%s"
5443+
name = "%s"
5444+
region = "us-west2"
5445+
database_version = "%s"
5446+
instance_type = "READ_REPLICA_INSTANCE"
5447+
master_instance_name = google_sql_database_instance.primary.name
5448+
deletion_protection = false
5449+
5450+
settings {
5451+
tier = "db-perf-optimized-N-2"
5452+
edition = "ENTERPRISE_PLUS"
5453+
ip_configuration {
5454+
ipv4_enabled = false
5455+
private_network = data.google_compute_network.servicenet.self_link
5456+
}
5457+
backup_configuration {
5458+
binary_log_enabled = true
5459+
}
5460+
}
5461+
}
5462+
`, networkName, project, primaryName, databaseVersion, project, replicaName, databaseVersion)
5463+
}
5464+
5465+
func testGoogleSqlDatabaseInstance_postgresEplusPrimaryReplicaSetupWithPrivateNetwork(project, primaryName, replicaName, networkName, databaseVersion string) string {
5466+
5467+
return fmt.Sprintf(`
5468+
data "google_compute_network" "servicenet" {
5469+
name = "%s"
5470+
}
5471+
5472+
resource "google_sql_database_instance" "primary" {
5473+
project = "%s"
5474+
name = "%s"
5475+
region = "us-east1"
5476+
database_version = "%s"
5477+
instance_type = "CLOUD_SQL_INSTANCE"
5478+
deletion_protection = false
5479+
5480+
settings {
5481+
tier = "db-perf-optimized-N-2"
5482+
edition = "ENTERPRISE_PLUS"
5483+
ip_configuration {
5484+
ipv4_enabled = false
5485+
private_network = data.google_compute_network.servicenet.self_link
5486+
}
5487+
backup_configuration {
5488+
enabled = true
5489+
point_in_time_recovery_enabled = true
5490+
}
5491+
}
5492+
}
5493+
5494+
resource "google_sql_database_instance" "replica" {
5495+
project = "%s"
5496+
name = "%s"
5497+
region = "us-west2"
5498+
database_version = "%s"
5499+
instance_type = "READ_REPLICA_INSTANCE"
5500+
master_instance_name = google_sql_database_instance.primary.name
5501+
deletion_protection = false
5502+
5503+
settings {
5504+
tier = "db-perf-optimized-N-2"
5505+
edition = "ENTERPRISE_PLUS"
5506+
ip_configuration {
5507+
ipv4_enabled = false
5508+
private_network = data.google_compute_network.servicenet.self_link
5509+
}
5510+
}
5511+
}
5512+
`, networkName, project, primaryName, databaseVersion, project, replicaName, databaseVersion)
5513+
}
5514+
52235515
func googleSqlDatabaseInstance_mysqlSetFailoverReplica(project, primaryName, replicaName string, useNormalizedDrReplicaName bool) string {
52245516
drReplicaName := fmt.Sprintf("%s:%s", project, replicaName)
52255517
if !useNormalizedDrReplicaName {

mmv1/third_party/terraform/website/docs/r/sql_database_instance.html.markdown

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -690,7 +690,7 @@ block during resource creation/update will trigger the restore action after the
690690

691691
* `project` - (Optional) The full project ID of the source instance.`
692692

693-
The optional, computed `replication_cluster` block represents a primary instance and disaster recovery replica pair. Applicable to MySQL and PostgreSQL. This field can be set only after both the primary and replica are created. This block supports:
693+
The optional, computed `replication_cluster` block represents a primary instance and disaster recovery replica pair. Applicable to MySQL and PostgreSQL. This field can be set if the primary has psa_write_endpoint set or both the primary and replica are created. This block supports:
694694

695695
* `psa_write_endpoint`: Read-only field which if set, indicates this instance has a private service access (PSA) DNS endpoint that is pointing to the primary instance of the cluster. If this instance is the primary, then the DNS endpoint points to this instance. After a switchover or replica failover operation, this DNS endpoint points to the promoted instance. This is a read-only field, returned to the user as information. This field can exist even if a standalone instance doesn't have a DR replica yet or the DR replica is deleted.
696696

0 commit comments

Comments
 (0)