Skip to content
Draft
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
Original file line number Diff line number Diff line change
Expand Up @@ -1429,6 +1429,11 @@ API (for read pools, effective_availability_type may differ from availability_ty
Optional: true,
Description: `The name of the target instance to restore to.`,
},
"region": {
Type: schema.TypeString,
Optional: true,
Description: `The region of the target instance to restore to.`,
},
},
},
},
Expand Down Expand Up @@ -3417,6 +3422,7 @@ func expandPointInTimeRestoreContext(configured []interface{}) *sqladmin.PointIn
Datasource: _pitrc["datasource"].(string),
AllocatedIpRange: _pitrc["allocated_ip_range"].(string),
TargetInstance: _pitrc["target_instance"].(string),
Region: _pitrc["region"].(string),
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1694,6 +1694,44 @@ func TestAccSqlDatabaseInstance_pointInTimeRestore(t *testing.T) {
})
}

func TestAccSqlDatabaseInstance_pointInTimeRestoreInMultiRegion(t *testing.T) {
// Skipped due to randomness
acctest.SkipIfVcr(t)
t.Parallel()

backupVaultID := "bv-test-mr"
location := "us"
project := envvar.GetTestProjectFromEnv()
backupVault := acctest.BootstrapBackupDRVault(t, backupVaultID, location)

context := map[string]interface{}{
"random_suffix": acctest.RandString(t, 10),
"project": project,
"backup_vault_id": backupVaultID,
"backup_vault": backupVault,
}

acctest.VcrTest(t, resource.TestCase{
PreCheck: func() { acctest.AccTestPreCheck(t) },
ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories(t),
CheckDestroy: testAccSqlDatabaseInstanceDestroyProducer(t),
ExternalProviders: map[string]resource.ExternalProvider{
"time": {},
},
Steps: []resource.TestStep{
{
Config: testAccSqlDatabaseInstance_pointInTimeRestoreContextMultiRegion(context),
},
{
ResourceName: "google_sql_database_instance.instance",
ImportState: true,
ImportStateVerify: true,
ImportStateVerifyIgnore: []string{"deletion_protection", "point_in_time_restore_context"},
},
},
})
}

func TestAccSqlDatabaseInstance_pointInTimeRestoreWithSettings(t *testing.T) {
// Skipped due to randomness
acctest.SkipIfVcr(t)
Expand Down Expand Up @@ -8076,6 +8114,117 @@ data "google_sql_backup_run" "backup" {
`, context)
}

func testAccSqlDatabaseInstance_pointInTimeRestoreContextMultiRegion(context map[string]interface{}) string {
return acctest.Nprintf(`

// Create a backup plan
resource "google_backup_dr_backup_plan" "plan" {
location = "us-central1"
backup_plan_id = "tf-test-bp-test-%{random_suffix}"
resource_type = "sqladmin.googleapis.com/Instance"
backup_vault = "%{backup_vault}"
log_retention_days = 2

backup_rules {
rule_id = "rule-1"
backup_retention_days = 7

standard_schedule {
recurrence_type = "DAILY"
hourly_frequency = 6
time_zone = "UTC"

backup_window {
start_hour_of_day = 0
end_hour_of_day = 23
}
}
}
}

// Create source SQL instance to backup
resource "google_sql_database_instance" "source" {
name = "tf-test-source-%{random_suffix}"
database_version = "MYSQL_8_0_41"
region = "us-central1"
project = "%{project}"
settings {
tier = "db-f1-micro"
backup_configuration {
enabled = true
}
}
lifecycle {
ignore_changes = [
settings[0].backup_configuration[0].enabled,
]
}
deletion_protection = false
}

// Associate backup plan with SQL instance
resource "google_backup_dr_backup_plan_association" "association" {
location = "us-central1"
backup_plan_association_id = "tf-test-bpa-test-%{random_suffix}"
resource = "projects/${google_sql_database_instance.source.project}/instances/${google_sql_database_instance.source.name}"
resource_type = "sqladmin.googleapis.com/Instance"
backup_plan = google_backup_dr_backup_plan.plan.name
}

// Wait for the first backup to be created
resource "time_sleep" "wait_10_mins" {
depends_on = [google_backup_dr_backup_plan_association.association]

create_duration = "600s"
}

data "google_backup_dr_backup" "sql_backups" {
project = "%{project}"
location = "us"
backup_vault_id = "%{backup_vault_id}"
data_source_id = element(split("/", google_backup_dr_backup_plan_association.association.data_source), length(split("/", google_backup_dr_backup_plan_association.association.data_source)) - 1)

depends_on = [time_sleep.wait_10_mins]
}

// for a point in time restore operation to succeed, the source instance must be in active state and have logs
resource "google_sql_database" "database" {
name = "tf-test-db-%{random_suffix}"
instance = google_sql_database_instance.source.name
project = "%{project}"
depends_on = [data.google_backup_dr_backup.sql_backups]
}

// Wait for the ten minutes (RPO is 5 minutes)
resource "time_sleep" "wait_for_binlog" {
depends_on = [google_sql_database.database]

create_duration = "600s"
}

resource "google_sql_database_instance" "instance" {
name = "tf-test-%{random_suffix}"
database_version = "MYSQL_8_0_41"
region = "us-central1"

point_in_time_restore_context {
datasource = google_backup_dr_backup_plan_association.association.data_source
target_instance = "%{project}:tf-test-%{random_suffix}"
point_in_time = timestamp()
region = "us-central1"
}

lifecycle {
ignore_changes = [point_in_time_restore_context[0].point_in_time]
}

depends_on = [time_sleep.wait_for_binlog]

deletion_protection = false
}
`, context)
}

func testAccSqlDatabaseInstance_pointInTimeRestoreContext(context map[string]interface{}) string {
return acctest.Nprintf(`
// Create service account
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -310,6 +310,29 @@ resource "google_sql_database_instance" "instance" {
}
```

### Cloud SQL Instance created using point_in_time_restore using multiregion datasource
~> **NOTE:** Replace `backupdr_datasource` with the full datasource path, `time_stamp` should be in the format of `YYYY-MM-DDTHH:MM:SSZ` and `region` with the target instance region.

```hcl
resource "google_sql_database_instance" "instance" {
name = "main-instance"
database_version = "MYSQL_8_0"
settings {
tier = "db-f1-micro"
backup_configuration {
enabled = true
binary_log_enabled = true
}
}
point_in_time_restore_context {
datasource = "backupdr_datasource"
target_instance = "target_instance_name"
point_in_time = "time_stamp"
region = "region"
}
}
```

## Argument Reference

The following arguments are supported:
Expand Down Expand Up @@ -689,6 +712,8 @@ The optional `point_in_time_restore_context` block supports:

* `target_instance` - The name of the target instance.

* `region` - The region of the target instance where the datasource will be restored. For example: "us-central1".

* `private_network` - (Optional) The resource link for the VPC network from which the Cloud SQL instance is accessible for private IP. For example, "/projects/myProject/global/networks/default".

* `preferred_zone` - (Optional) Point-in-time recovery of an instance to the specified zone. If no zone is specified, then clone to the same primary zone as the source instance.
Expand Down
Loading