Skip to content

Commit c51bf29

Browse files
authored
feat: Create SQL Backup and export module (#296)
* Create SQL Backup and export module * Findings from codereview by @bharathkkb * Add tests for CloudSQL backup module * Add wait time to allow API activation * Increase API Wait time to 7.5 minutes * Reduce outputs for examples and add region as output for backup module * Use default docker image for waiting * Update gcloud go package and use gcloud.Runf
1 parent fe91aa5 commit c51bf29

File tree

24 files changed

+1218
-256
lines changed

24 files changed

+1218
-256
lines changed

build/int.cloudbuild.yaml

Lines changed: 48 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -21,15 +21,23 @@ steps:
2121
- 'TF_VAR_org_id=$_ORG_ID'
2222
- 'TF_VAR_folder_id=$_FOLDER_ID'
2323
- 'TF_VAR_billing_account=$_BILLING_ACCOUNT'
24+
25+
# Sometimes API activation can be bit flaky therefor ensure that at least 3 mins (180s) are passed between
26+
# prepare_environment and the first terraform apply (init-all runs parallel to reduce waste of time)
27+
- id: wait for api activation
28+
waitFor:
29+
- prepare
30+
name: 'gcr.io/cloud-foundation-cicd/$_DOCKER_IMAGE_DEVELOPER_TOOLS:$_DOCKER_TAG_VERSION_DEVELOPER_TOOLS'
31+
args: ['sleep', '$_API_ACTIVATION_SECONDS_WAIT']
32+
2433
- id: init-all
2534
waitFor:
2635
- prepare
2736
name: 'gcr.io/cloud-foundation-cicd/$_DOCKER_IMAGE_DEVELOPER_TOOLS:$_DOCKER_TAG_VERSION_DEVELOPER_TOOLS'
2837
args: ['/bin/bash', '-c', 'cft test run all --stage init --verbose']
2938

3039
- id: apply mssql-ha-local
31-
waitFor:
32-
- init-all
40+
waitFor: ["init-all", "wait for api activation"]
3341
name: 'gcr.io/cloud-foundation-cicd/$_DOCKER_IMAGE_DEVELOPER_TOOLS:$_DOCKER_TAG_VERSION_DEVELOPER_TOOLS'
3442
args: ['/bin/bash', '-c', 'cft test run TestMsSqlHaModule --stage apply --verbose']
3543
- id: verify mssql-ha-local
@@ -44,8 +52,7 @@ steps:
4452
args: ['/bin/bash', '-c', 'cft test run TestMsSqlHaModule --stage teardown --verbose']
4553

4654
- id: apply mssql-public-local
47-
waitFor:
48-
- init-all
55+
waitFor: ["init-all", "wait for api activation"]
4956
name: 'gcr.io/cloud-foundation-cicd/$_DOCKER_IMAGE_DEVELOPER_TOOLS:$_DOCKER_TAG_VERSION_DEVELOPER_TOOLS'
5057
args: ['/bin/bash', '-c', 'cft test run TestMsSqlPublicModule --stage apply --verbose']
5158
- id: verify mssql-public-local
@@ -60,8 +67,7 @@ steps:
6067
args: ['/bin/bash', '-c', 'cft test run TestMsSqlPublicModule --stage teardown --verbose']
6168

6269
- id: apply mysql-ha-local
63-
waitFor:
64-
- init-all
70+
waitFor: ["init-all", "wait for api activation"]
6571
name: 'gcr.io/cloud-foundation-cicd/$_DOCKER_IMAGE_DEVELOPER_TOOLS:$_DOCKER_TAG_VERSION_DEVELOPER_TOOLS'
6672
args: ['/bin/bash', '-c', 'cft test run TestMySqlHaModule --stage apply --verbose']
6773
- id: verify mysql-ha-local
@@ -76,8 +82,7 @@ steps:
7682
args: ['/bin/bash', '-c', 'cft test run TestMySqlHaModule --stage teardown --verbose']
7783

7884
- id: apply mysql-private-local
79-
waitFor:
80-
- init-all
85+
waitFor: ["init-all", "wait for api activation"]
8186
name: 'gcr.io/cloud-foundation-cicd/$_DOCKER_IMAGE_DEVELOPER_TOOLS:$_DOCKER_TAG_VERSION_DEVELOPER_TOOLS'
8287
args: ['/bin/bash', '-c', 'cft test run TestMySqlPrivateModule --stage apply --verbose']
8388
- id: verify mysql-private-local
@@ -92,8 +97,7 @@ steps:
9297
args: ['/bin/bash', '-c', 'cft test run TestMySqlPrivateModule --stage teardown --verbose']
9398

9499
- id: apply mysql-public-local
95-
waitFor:
96-
- init-all
100+
waitFor: ["init-all", "wait for api activation"]
97101
name: 'gcr.io/cloud-foundation-cicd/$_DOCKER_IMAGE_DEVELOPER_TOOLS:$_DOCKER_TAG_VERSION_DEVELOPER_TOOLS'
98102
args: ['/bin/bash', '-c', 'cft test run TestMySqlPublicModule --stage apply --verbose']
99103
- id: verify mysql-public-local
@@ -108,8 +112,7 @@ steps:
108112
args: ['/bin/bash', '-c', 'cft test run TestMySqlPublicModule --stage teardown --verbose']
109113

110114
- id: apply postgresql-ha-local
111-
waitFor:
112-
- init-all
115+
waitFor: ["init-all", "wait for api activation"]
113116
name: 'gcr.io/cloud-foundation-cicd/$_DOCKER_IMAGE_DEVELOPER_TOOLS:$_DOCKER_TAG_VERSION_DEVELOPER_TOOLS'
114117
args: ['/bin/bash', '-c', 'cft test run TestPostgreSqlHaModule --stage apply --verbose']
115118
- id: verify postgresql-ha-local
@@ -124,8 +127,7 @@ steps:
124127
args: ['/bin/bash', '-c', 'cft test run TestPostgreSqlHaModule --stage teardown --verbose']
125128

126129
- id: apply postgresql-public-local
127-
waitFor:
128-
- init-all
130+
waitFor: ["init-all", "wait for api activation"]
129131
name: 'gcr.io/cloud-foundation-cicd/$_DOCKER_IMAGE_DEVELOPER_TOOLS:$_DOCKER_TAG_VERSION_DEVELOPER_TOOLS'
130132
args: ['/bin/bash', '-c', 'cft test run TestPostgreSqlPublicModule --stage apply --verbose']
131133
- id: verify postgresql-public-local
@@ -140,8 +142,7 @@ steps:
140142
args: ['/bin/bash', '-c', 'cft test run TestPostgreSqlPublicModule --stage teardown --verbose']
141143

142144
- id: apply postgresql-public-iam-local
143-
waitFor:
144-
- init-all
145+
waitFor: ["init-all", "wait for api activation"]
145146
name: 'gcr.io/cloud-foundation-cicd/$_DOCKER_IMAGE_DEVELOPER_TOOLS:$_DOCKER_TAG_VERSION_DEVELOPER_TOOLS'
146147
args: ['/bin/bash', '-c', 'cft test run TestPostgreSqlPublicIamModule --stage apply --verbose']
147148
- id: verify postgresql-public-iam-local
@@ -155,9 +156,40 @@ steps:
155156
name: 'gcr.io/cloud-foundation-cicd/$_DOCKER_IMAGE_DEVELOPER_TOOLS:$_DOCKER_TAG_VERSION_DEVELOPER_TOOLS'
156157
args: ['/bin/bash', '-c', 'cft test run TestPostgreSqlPublicIamModule --stage teardown --verbose']
157158

159+
- id: apply mysql-backup-local
160+
waitFor: ["init-all", "wait for api activation"]
161+
name: 'gcr.io/cloud-foundation-cicd/$_DOCKER_IMAGE_DEVELOPER_TOOLS:$_DOCKER_TAG_VERSION_DEVELOPER_TOOLS'
162+
args: ['/bin/bash', '-c', 'cft test run TestMySqlBackupModuleCreateServiceAccount --stage apply --verbose']
163+
- id: verify mysql-backup-local
164+
waitFor:
165+
- apply mysql-backup-local
166+
name: 'gcr.io/cloud-foundation-cicd/$_DOCKER_IMAGE_DEVELOPER_TOOLS:$_DOCKER_TAG_VERSION_DEVELOPER_TOOLS'
167+
args: ['/bin/bash', '-c', 'cft test run TestMySqlBackupModuleCreateServiceAccount --stage verify --verbose']
168+
- id: teardown mysql-backup-local
169+
waitFor:
170+
- verify mysql-backup-local
171+
name: 'gcr.io/cloud-foundation-cicd/$_DOCKER_IMAGE_DEVELOPER_TOOLS:$_DOCKER_TAG_VERSION_DEVELOPER_TOOLS'
172+
args: ['/bin/bash', '-c', 'cft test run TestMySqlBackupModuleCreateServiceAccount --stage teardown --verbose']
173+
174+
- id: apply postgresql-backup-local
175+
waitFor: ["init-all", "wait for api activation"]
176+
name: 'gcr.io/cloud-foundation-cicd/$_DOCKER_IMAGE_DEVELOPER_TOOLS:$_DOCKER_TAG_VERSION_DEVELOPER_TOOLS'
177+
args: ['/bin/bash', '-c', 'cft test run TestPostgresqlBackupModuleProvidedServiceAccount --stage apply --verbose']
178+
- id: verify postgresql-backup-local
179+
waitFor:
180+
- apply postgresql-backup-local
181+
name: 'gcr.io/cloud-foundation-cicd/$_DOCKER_IMAGE_DEVELOPER_TOOLS:$_DOCKER_TAG_VERSION_DEVELOPER_TOOLS'
182+
args: ['/bin/bash', '-c', 'cft test run TestPostgresqlBackupModuleProvidedServiceAccount --stage verify --verbose']
183+
- id: teardown postgresql-backup-local
184+
waitFor:
185+
- verify postgresql-backup-local
186+
name: 'gcr.io/cloud-foundation-cicd/$_DOCKER_IMAGE_DEVELOPER_TOOLS:$_DOCKER_TAG_VERSION_DEVELOPER_TOOLS'
187+
args: ['/bin/bash', '-c', 'cft test run TestPostgresqlBackupModuleProvidedServiceAccount --stage teardown --verbose']
188+
158189
tags:
159190
- 'ci'
160191
- 'integration'
161192
substitutions:
162193
_DOCKER_IMAGE_DEVELOPER_TOOLS: 'cft/developer-tools'
163194
_DOCKER_TAG_VERSION_DEVELOPER_TOOLS: '1.3'
195+
_API_ACTIVATION_SECONDS_WAIT: '450'
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
# Cloud SQL Database Backup Example
2+
3+
This example shows how to create:
4+
5+
- a MySQL CloudSQL Instance
6+
- A GCS Bucket for storing the Backup
7+
- The Workflows for exports (external backups) and (internal) backups
8+
9+
## Run Terraform
10+
11+
Create resources with terraform:
12+
13+
```bash
14+
terraform init
15+
terraform plan
16+
terraform apply
17+
```
18+
19+
To remove all resources created by terraform:
20+
21+
```bash
22+
terraform destroy
23+
```
24+
25+
## Inputs
26+
27+
| Name | Description | Type | Default | Required |
28+
|------|-------------|------|---------|:--------:|
29+
| <a name="input_authorized_networks"></a> [authorized\_networks](#input\_authorized\_networks) | List of mapped public networks authorized to access to the instances. Default - short range of GCP health-checkers IPs | `list(map(string))` | <pre>[<br> {<br> "name": "sample-gcp-health-checkers-range",<br> "value": "130.211.0.0/28"<br> }<br>]</pre> | no |
30+
| <a name="input_db_name"></a> [db\_name](#input\_db\_name) | The name of the SQL Database instance | `string` | `"example-mysql-public"` | no |
31+
| <a name="input_project_id"></a> [project\_id](#input\_project\_id) | The ID of the project in which resources will be provisioned. | `string` | n/a | yes |
32+
| <a name="input_region"></a> [region](#input\_region) | The region of the Cloud SQL resources | `string` | `"us-central1"` | no |
33+
34+
## Outputs
35+
36+
| Name | Description |
37+
|------|-------------|
38+
| <a name="output_backup_workflow_name"></a> [backup\_workflow\_name](#output\_backup\_workflow\_name) | The name for internal backup workflow |
39+
| <a name="output_export_workflow_name"></a> [export\_workflow\_name](#output\_export\_workflow\_name) | The name for export workflow |
40+
| <a name="output_instance_name"></a> [instance\_name](#output\_instance\_name) | The name of the SQL instance |
41+
| <a name="output_project_id"></a> [project\_id](#output\_project\_id) | The project ID used |
42+
| <a name="output_service_account"></a> [service\_account](#output\_service\_account) | The service account email running the scheduler and workflow |
43+
| <a name="output_workflow_location"></a> [workflow\_location](#output\_workflow\_location) | The location where the workflows run |
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
/**
2+
* Copyright 2022 Google LLC
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
module "mysql" {
18+
source = "../../modules/mysql"
19+
name = "example-mysql-public"
20+
database_version = "MYSQL_8_0"
21+
random_instance_name = true
22+
project_id = var.project_id
23+
zone = "us-central1-a"
24+
region = "us-central1"
25+
deletion_protection = false
26+
27+
ip_configuration = {
28+
ipv4_enabled = true
29+
private_network = null
30+
require_ssl = true
31+
allocated_ip_range = null
32+
authorized_networks = []
33+
}
34+
}
35+
36+
resource "google_storage_bucket" "backup" {
37+
name = "${module.mysql.instance_name}-backup"
38+
location = "us-central1"
39+
# TODO: don't use force_destroy for production this is just required for testing
40+
force_destroy = true
41+
project = var.project_id
42+
}
43+
44+
module "backup" {
45+
source = "../../modules/backup"
46+
region = "us-central1"
47+
project_id = var.project_id
48+
sql_instance = module.mysql.instance_name
49+
export_databases = []
50+
export_uri = google_storage_bucket.backup.url
51+
backup_retention_time = 1
52+
backup_schedule = "5 * * * *"
53+
export_schedule = "10 * * * *"
54+
}
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
/**
2+
* Copyright 2022 Google LLC
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
output "backup_workflow_name" {
18+
value = module.backup.backup_workflow_name
19+
description = "The name for internal backup workflow"
20+
}
21+
22+
output "export_workflow_name" {
23+
value = module.backup.export_workflow_name
24+
description = "The name for export workflow"
25+
}
26+
27+
output "project_id" {
28+
value = var.project_id
29+
description = "The project ID used"
30+
}
31+
32+
output "service_account" {
33+
value = module.backup.service_account
34+
description = "The service account email running the scheduler and workflow"
35+
}
36+
37+
output "workflow_location" {
38+
value = module.backup.region
39+
description = "The location where the workflows run"
40+
}
41+
42+
output "instance_name" {
43+
value = module.mysql.instance_name
44+
description = "The name of the SQL instance"
45+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
/**
2+
* Copyright 2022 Google LLC
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
variable "project_id" {
18+
description = "The ID of the project in which resources will be provisioned."
19+
type = string
20+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
/**
2+
* Copyright 2022 Google LLC
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
terraform {
18+
required_version = ">= 0.13"
19+
}
20+
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
# Cloud SQL Database Backup Example
2+
3+
This example shows how to create:
4+
5+
- a PostgreSQL Cloud SQL Instance
6+
- A GCS Bucket for storing the Backup
7+
- The Workflows for exports (external backups) and (internal) backups
8+
9+
## Run Terraform
10+
11+
Create resources with terraform:
12+
13+
```bash
14+
terraform init
15+
terraform plan
16+
terraform apply
17+
```
18+
19+
To remove all resources created by terraform:
20+
21+
```bash
22+
terraform destroy
23+
```
24+
25+
## Inputs
26+
27+
| Name | Description | Type | Default | Required |
28+
|------|-------------|------|---------|:--------:|
29+
| <a name="input_authorized_networks"></a> [authorized\_networks](#input\_authorized\_networks) | List of mapped public networks authorized to access to the instances. Default - short range of GCP health-checkers IPs | `list(map(string))` | <pre>[<br> {<br> "name": "sample-gcp-health-checkers-range",<br> "value": "130.211.0.0/28"<br> }<br>]</pre> | no |
30+
| <a name="input_db_name"></a> [db\_name](#input\_db\_name) | The name of the SQL Database instance | `string` | `"example-mysql-public"` | no |
31+
| <a name="input_project_id"></a> [project\_id](#input\_project\_id) | The ID of the project in which resources will be provisioned. | `string` | n/a | yes |
32+
| <a name="input_region"></a> [region](#input\_region) | The region of the Cloud SQL resources | `string` | `"us-central1"` | no |
33+
34+
## Outputs
35+
36+
| Name | Description |
37+
|------|-------------|
38+
| <a name="output_backup_workflow_name"></a> [backup\_workflow\_name](#output\_backup\_workflow\_name) | The name for internal backup workflow |
39+
| <a name="output_export_workflow_name"></a> [export\_workflow\_name](#output\_export\_workflow\_name) | The name for export workflow |
40+
| <a name="output_instance_name"></a> [instance\_name](#output\_instance\_name) | The name of the SQL instance |
41+
| <a name="output_project_id"></a> [project\_id](#output\_project\_id) | The project ID used |
42+
| <a name="output_service_account"></a> [service\_account](#output\_service\_account) | The service account email running the scheduler and workflow |
43+
| <a name="output_workflow_location"></a> [workflow\_location](#output\_workflow\_location) | The location where the workflows run |

0 commit comments

Comments
 (0)