Skip to content

Commit c4a8bee

Browse files
committed
Define private-service-access module for peering
The module defines a network peering between a given VPC and the service networks where Cloud SQL instances are created. Added tests and modified the example.
1 parent 5b0b285 commit c4a8bee

File tree

18 files changed

+357
-64
lines changed

18 files changed

+357
-64
lines changed

README.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,14 @@ In order to operate with the Service Account you must activate the following API
2929

3030
- Cloud SQL API
3131

32+
In order to use Private Service Access, required for using Private IPs, you must activate
33+
the following APIs on the project where your VPC resides:
34+
35+
- Cloud SQL Admin API
36+
- Compute Engine API
37+
- Service Networking API
38+
- Cloud Resource Manager API
39+
3240
#### Service Account Credentials
3341

3442
You can pass the service account credentials into this module by setting the following environment variables:

examples/mysql-and-postgres/main.tf

Lines changed: 8 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -110,32 +110,19 @@ module "postgresql-db" {
110110
}]
111111
}
112112

113-
# We define a VPC peering subnet that will be peered with the
114-
# Cloud SQL instance network. The Cloud SQL instance will
115-
# have a private IP within the provided range.
116-
resource "google_compute_global_address" "google-managed-services-default" {
117-
provider = "google-beta"
118-
project = "${var.project_id}"
119-
name = "private-ip-address"
120-
purpose = "VPC_PEERING"
121-
address_type = "INTERNAL"
122-
prefix_length = 16
123-
network = "${google_compute_network.default.self_link}"
124-
}
125-
126-
# Creates the peering with the producer network.
127-
resource "google_service_networking_connection" "private_vpc_connection" {
128-
provider = "google-beta"
129-
network = "${google_compute_network.default.self_link}"
130-
service = "servicenetworking.googleapis.com"
131-
reserved_peering_ranges = ["${google_compute_global_address.google-managed-services-default.name}"]
113+
// We define a connection with the VPC of the Cloud SQL instance.
114+
module "private-service-access" {
115+
source = "../../modules/private_service_access"
116+
project_id = "${var.project_id}"
117+
vpc_network = "${google_compute_network.default.self_link}"
132118
}
133119

134120
module "safer-mysql-db" {
135121
source = "../../modules/safer_mysql"
136122
name = "example-safer-mysql-${random_id.name.hex}"
137123
database_version = "${var.mysql_version}"
138124
project_id = "${var.project_id}"
125+
region = "${var.region}"
139126
zone = "c"
140127

141128
# By default, all users will be permitted to connect only via the
@@ -151,8 +138,8 @@ module "safer-mysql-db" {
151138
assign_public_ip = true
152139
vpc_network = "${google_compute_network.default.self_link}"
153140

154-
# Optional, but used to enforce ordering in the creation of resources.
155-
vpc_peering = "${google_service_networking_connection.private_vpc_connection.self_link}"
141+
// Used to enforce ordering in the creation of resources.
142+
peering_completed = "${module.private-service-access.peering_completed}"
156143
}
157144

158145
output "mysql_conn" {

kitchen.yml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,3 +42,8 @@ suites:
4242
name: terraform
4343
root_module_directory: test/fixtures/safer-mysql-simple
4444
command_timeout: 1800
45+
- name: private-service-access
46+
driver:
47+
name: terraform
48+
root_module_directory: test/fixtures/private-service-access
49+
command_timeout: 1800
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
# Submodule for VPC peering Cloud SQL services
2+
3+
MySQL [Private IP](https://cloud.google.com/sql/docs/mysql/private-ip)
4+
configurations require a special peering between your VPC network and a
5+
VPC managed by Google. The module supports creating such a peering.
6+
7+
It is sufficient to instantiate this module once for all MySQL instances
8+
that are connected to the same VPC.
9+
10+
> NOTE: See the linked [documentation](https://cloud.google.com/sql/docs/mysql/private-ip)
11+
> for all requirements for accessing a MySQL instance via its Private IP.
12+
13+
[^]: (autogen_docs_start)
14+
15+
## Inputs
16+
17+
| Name | Description | Type | Default | Required |
18+
|------|-------------|:----:|:-----:|:-----:|
19+
| address | First IP address of the IP range to allocate to CLoud SQL instances and other Private Service Access services. If not set, GCP will pick a valid one for you. | string | `""` | no |
20+
| ip\_version | IP Version for the allocation. Can be IPV4 or IPV6. | string | `""` | no |
21+
| labels | The key/value labels for the IP range allocated to the peered network. | map | `<map>` | no |
22+
| prefix\_length | Prefix length of the IP range reserved for Cloud SQL instances and other Private Service Access services. Defaults to /16. | string | `"16"` | no |
23+
| project\_id | The project ID of the VPC network to peer. This can be a shared VPC host projec. | string | n/a | yes |
24+
| vpc\_network | Name of the VPC network to peer. | string | n/a | yes |
25+
26+
## Outputs
27+
28+
| Name | Description |
29+
|------|-------------|
30+
| address | First IP of the reserved range. |
31+
| google\_compute\_global\_address\_name | URL of the reserved range. |
32+
| peering\_completed | Use for enforce ordering between resource creation |
33+
34+
[^]: (autogen_docs_end)
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
/**
2+
* Copyright 2018 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+
// We define a VPC peering subnet that will be peered with the
18+
// Cloud SQL instance network. The Cloud SQL instance will
19+
// have a private IP within the provided range.
20+
// https://cloud.google.com/vpc/docs/configure-private-services-access
21+
resource "google_compute_global_address" "google-managed-services-range" {
22+
provider = "google-beta"
23+
project = "${var.project_id}"
24+
name = "google-managed-services-${var.vpc_network}"
25+
purpose = "VPC_PEERING"
26+
address = "${var.address}"
27+
prefix_length = "${var.prefix_length}"
28+
ip_version = "${var.ip_version}"
29+
labels = "${var.labels}"
30+
address_type = "INTERNAL"
31+
network = "${var.vpc_network}"
32+
}
33+
34+
# Creates the peering with the producer network.
35+
resource "google_service_networking_connection" "private_service_access" {
36+
provider = "google-beta"
37+
network = "${google_compute_global_address.google-managed-services-range.network}"
38+
service = "servicenetworking.googleapis.com"
39+
reserved_peering_ranges = ["${google_compute_global_address.google-managed-services-range.name}"]
40+
}
41+
42+
resource "null_resource" "dependency_setter" {
43+
depends_on = [
44+
"google_service_networking_connection.private_service_access",
45+
]
46+
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
/**
2+
* Copyright 2018 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 "address" {
18+
value = "${google_compute_global_address.google-managed-services-range.address}"
19+
description = "First IP of the reserved range."
20+
}
21+
22+
output "google_compute_global_address_name" {
23+
value = "${google_compute_global_address.google-managed-services-range.name}"
24+
description = "URL of the reserved range."
25+
}
26+
27+
output "peering_completed" {
28+
value = "${null_resource.dependency_setter.id}"
29+
description = "Use for enforce ordering between resource creation"
30+
}
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
/**
2+
* Copyright 2018 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 project ID of the VPC network to peer. This can be a shared VPC host projec."
19+
}
20+
21+
variable "vpc_network" {
22+
description = "Name of the VPC network to peer."
23+
}
24+
25+
variable "address" {
26+
description = "First IP address of the IP range to allocate to CLoud SQL instances and other Private Service Access services. If not set, GCP will pick a valid one for you."
27+
default = ""
28+
}
29+
30+
variable "prefix_length" {
31+
description = "Prefix length of the IP range reserved for Cloud SQL instances and other Private Service Access services. Defaults to /16."
32+
default = "16"
33+
}
34+
35+
variable "ip_version" {
36+
description = "IP Version for the allocation. Can be IPV4 or IPV6."
37+
default = ""
38+
}
39+
40+
variable "labels" {
41+
description = "The key/value labels for the IP range allocated to the peered network."
42+
default = {}
43+
}

modules/safer_mysql/README.md

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -168,7 +168,7 @@ mysql -S $HOME/mysql_sockets/myproject:region:instance -u user -p
168168
| activation\_policy | The activation policy for the master instance. Can be either `ALWAYS`, `NEVER` or `ON_DEMAND`. | string | `"ALWAYS"` | no |
169169
| additional\_databases | A list of databases to be created in your cluster | list | `<list>` | no |
170170
| additional\_users | A list of users to be created in your cluster | list | `<list>` | no |
171-
| assign\_public\_ip | Set tp true if the master instance should also have a public IP. | string | `"false"` | no |
171+
| assign\_public\_ip | Set to true if the master instance should also have a public IP (less secure). | string | `"false"` | no |
172172
| authorized\_gae\_applications | The list of authorized App Engine project names | list | `<list>` | no |
173173
| backup\_configuration | The backup configuration block of the Cloud SQL resources This argument will be passed through the master instance directrly.<br><br>See [more details](https://www.terraform.io/docs/providers/google/r/sql_database_instance.html). | map | `<map>` | no |
174174
| create\_timeout | The optional timout that is applied to limit long database creates. | string | `"15m"` | no |
@@ -199,8 +199,9 @@ mysql -S $HOME/mysql_sockets/myproject:region:instance -u user -p
199199
| failover\_replica\_zone | The zone for the failover replica instance, it should be something like: `a`, `c`. | string | `""` | no |
200200
| maintenance\_window\_day | The day of week (1-7) for the master instance maintenance. | string | `"1"` | no |
201201
| maintenance\_window\_hour | The hour of day (0-23) maintenance window for the master instance maintenance. | string | `"23"` | no |
202-
| maintenance\_window\_update\_track | The update track of maintenance window for the master instance maintenance. Can be either `canary` or `stable`. | string | `"canary"` | no |
202+
| maintenance\_window\_update\_track | The update track of maintenance window for the master instance maintenance. Can be either `canary` or `stable`. | string | `"stable"` | no |
203203
| name | The name of the Cloud SQL resources | string | n/a | yes |
204+
| peering\_completed | Optional. This is used to ensure that resources are created in the proper order when using private IPs and service network peering. | string | `""` | no |
204205
| pricing\_plan | The pricing plan for the master instance. | string | `"PER_USE"` | no |
205206
| project\_id | The project ID to manage the Cloud SQL resources | string | n/a | yes |
206207
| read\_replica\_activation\_policy | The activation policy for the read replica instances. Can be either `ALWAYS`, `NEVER` or `ON_DEMAND`. | string | `"ALWAYS"` | no |
@@ -219,14 +220,13 @@ mysql -S $HOME/mysql_sockets/myproject:region:instance -u user -p
219220
| read\_replica\_tier | The tier for the read replica instances. | string | `""` | no |
220221
| read\_replica\_user\_labels | The key/value labels for the read replica instances. | map | `<map>` | no |
221222
| read\_replica\_zones | The zones for the read replica instancess, it should be something like: `a,b,c`. Given zones are used rotationally for creating read replicas. | string | `""` | no |
222-
| region | The region of the Cloud SQL resources | string | `"us-central1"` | no |
223+
| region | The region of the Cloud SQL resources | string | n/a | yes |
223224
| tier | The tier for the master instance. | string | `"db-n1-standard-1"` | no |
224225
| update\_timeout | The optional timout that is applied to limit long database updates. | string | `"15m"` | no |
225226
| user\_labels | The key/value labels for the master instances. | map | `<map>` | no |
226227
| user\_name | The name of the default user | string | `"default"` | no |
227228
| user\_password | The password for the default user. If not set, a random one will be generated and available in the generated_user_password output variable. | string | `""` | no |
228229
| vpc\_network | Existing VPC network to which instances are connected. The networks needs to be configured with https://cloud.google.com/vpc/docs/configure-private-services-access. | string | n/a | yes |
229-
| vpc\_peering | google_service_networking_connection object identifying the peering between the producer network and the project subnet. This is not used, but needed to ensure that elements are created in the proper order | string | n/a | yes |
230230
| zone | The zone for the master instance, it should be something like: `a`, `c`. | string | n/a | yes |
231231

232232
## Outputs
@@ -247,4 +247,4 @@ mysql -S $HOME/mysql_sockets/myproject:region:instance -u user -p
247247
| replicas\_instance\_self\_links | The URIs of the replica instances |
248248
| replicas\_instance\_service\_account\_email\_addresses | The service account email addresses assigned to the replica instances |
249249

250-
[^]: (autogen_docs_end)
250+
[^]: (autogen_docs_end)

modules/safer_mysql/main.tf

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,15 @@ module "safer_mysql" {
3232
maintenance_window_hour = "${var.maintenance_window_hour}"
3333
maintenance_window_update_track = "${var.maintenance_window_update_track}"
3434
database_flags = "${var.database_flags}"
35-
user_labels = "${var.user_labels}"
36-
backup_configuration = "${var.backup_configuration}"
35+
36+
// Define a label to force a dependency to the creation of the network peering.
37+
// Substitute this with a module dependency once the module is migrated to
38+
// Terraform 0.12
39+
user_labels = "${merge(
40+
map("tf_dependency", var.peering_completed),
41+
var.user_labels)}"
42+
43+
backup_configuration = "${var.backup_configuration}"
3744

3845
ip_configuration = [
3946
{

modules/safer_mysql/variables.tf

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,9 @@ variable "vpc_network" {
3737
description = "Existing VPC network to which instances are connected. The networks needs to be configured with https://cloud.google.com/vpc/docs/configure-private-services-access."
3838
}
3939

40-
variable "vpc_peering" {
41-
description = "google_service_networking_connection object identifying the peering between the producer network and the project subnet. This is not used, but needed to ensure that elements are created in the proper order"
40+
variable "peering_completed" {
41+
description = "Optional. This is used to ensure that resources are created in the proper order when using private IPs and service network peering."
42+
default = ""
4243
}
4344

4445
// Master

0 commit comments

Comments
 (0)