From 1128c81d71570dcfda52baa1f3c8fb761eddcbff Mon Sep 17 00:00:00 2001 From: Jimmy Huang Date: Fri, 26 Oct 2018 01:42:17 -0700 Subject: [PATCH 01/11] save point --- google-beta/resource_sql_database_instance.go | 23 +++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/google-beta/resource_sql_database_instance.go b/google-beta/resource_sql_database_instance.go index 8dcc259dea..0400f23535 100644 --- a/google-beta/resource_sql_database_instance.go +++ b/google-beta/resource_sql_database_instance.go @@ -16,6 +16,8 @@ import ( "google.golang.org/api/sqladmin/v1beta4" ) +const peerNetworkLinkRegex = "projects/(" + ProjectRegex + ")/global/networks/((?:[a-z](?:[-a-z0-9]*[a-z0-9])?))$" + var sqlDatabaseAuthorizedNetWorkSchemaElem *schema.Resource = &schema.Resource{ Schema: map[string]*schema.Schema{ "expiration_time": &schema.Schema{ @@ -180,6 +182,12 @@ func resourceSqlDatabaseInstance() *schema.Resource { Type: schema.TypeBool, Optional: true, }, + "private_network": &schema.Schema{ + Type: schema.TypeString, + Optional: true, + ValidateFunc: validateRegexp(peerNetworkLinkRegex), + DiffSuppressFunc: compareSelfLinkRelativePaths, + }, }, }, }, @@ -617,6 +625,7 @@ func expandIpConfiguration(configured []interface{}) *sqladmin.IpConfiguration { return &sqladmin.IpConfiguration{ Ipv4Enabled: _ipConfiguration["ipv4_enabled"].(bool), RequireSsl: _ipConfiguration["require_ssl"].(bool), + PrivateNetwork: _ipConfiguration["private_network"].(string), AuthorizedNetworks: expandAuthorizedNetworks(_ipConfiguration["authorized_networks"].(*schema.Set).List()), } } @@ -668,6 +677,15 @@ func expandBackupConfiguration(configured []interface{}) *sqladmin.BackupConfigu } } +func expandComputePrivateNetwork(v interface{}, d *schema.ResourceData, config *Config) (interface{}, error) { + f, err := parseGlobalFieldValue("private_network", v.(string), "project", d, config, true) + if err != nil { + return nil, fmt.Errorf("Invalid value for network: %s", err) + } + return f.RelativeLink(), nil +} + + func resourceSqlDatabaseInstanceRead(d *schema.ResourceData, meta interface{}) error { config := meta.(*Config) @@ -870,8 +888,9 @@ func flattenDatabaseFlags(databaseFlags []*sqladmin.DatabaseFlags) []map[string] func flattenIpConfiguration(ipConfiguration *sqladmin.IpConfiguration) interface{} { data := map[string]interface{}{ - "ipv4_enabled": ipConfiguration.Ipv4Enabled, - "require_ssl": ipConfiguration.RequireSsl, + "ipv4_enabled": ipConfiguration.Ipv4Enabled, + "private_network": ipConfiguration.PrivateNetwork, + "require_ssl": ipConfiguration.RequireSsl, } if ipConfiguration.AuthorizedNetworks != nil { From cdcb897ad5d2b9b11ccae8131c0caea842075806 Mon Sep 17 00:00:00 2001 From: "Jimmy Y. Huang" Date: Fri, 26 Oct 2018 04:22:46 -0700 Subject: [PATCH 02/11] now supports private_network --- google-beta/resource_sql_database_instance.go | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) diff --git a/google-beta/resource_sql_database_instance.go b/google-beta/resource_sql_database_instance.go index 0400f23535..18198a0143 100644 --- a/google-beta/resource_sql_database_instance.go +++ b/google-beta/resource_sql_database_instance.go @@ -16,7 +16,7 @@ import ( "google.golang.org/api/sqladmin/v1beta4" ) -const peerNetworkLinkRegex = "projects/(" + ProjectRegex + ")/global/networks/((?:[a-z](?:[-a-z0-9]*[a-z0-9])?))$" +const privateNetworkLinkRegex = "projects/(" + ProjectRegex + ")/global/networks/((?:[a-z](?:[-a-z0-9]*[a-z0-9])?))$" var sqlDatabaseAuthorizedNetWorkSchemaElem *schema.Resource = &schema.Resource{ Schema: map[string]*schema.Schema{ @@ -185,8 +185,8 @@ func resourceSqlDatabaseInstance() *schema.Resource { "private_network": &schema.Schema{ Type: schema.TypeString, Optional: true, - ValidateFunc: validateRegexp(peerNetworkLinkRegex), - DiffSuppressFunc: compareSelfLinkRelativePaths, + ValidateFunc: validateRegexp(privateNetworkLinkRegex), + DiffSuppressFunc: compareSelfLinkRelativePaths, }, }, }, @@ -622,6 +622,7 @@ func expandIpConfiguration(configured []interface{}) *sqladmin.IpConfiguration { } _ipConfiguration := configured[0].(map[string]interface{}) + return &sqladmin.IpConfiguration{ Ipv4Enabled: _ipConfiguration["ipv4_enabled"].(bool), RequireSsl: _ipConfiguration["require_ssl"].(bool), @@ -677,15 +678,6 @@ func expandBackupConfiguration(configured []interface{}) *sqladmin.BackupConfigu } } -func expandComputePrivateNetwork(v interface{}, d *schema.ResourceData, config *Config) (interface{}, error) { - f, err := parseGlobalFieldValue("private_network", v.(string), "project", d, config, true) - if err != nil { - return nil, fmt.Errorf("Invalid value for network: %s", err) - } - return f.RelativeLink(), nil -} - - func resourceSqlDatabaseInstanceRead(d *schema.ResourceData, meta interface{}) error { config := meta.(*Config) From 4c60d9bfb817f7b65c996adadeef597b3b6c2840 Mon Sep 17 00:00:00 2001 From: "Jimmy Y. Huang" Date: Sun, 28 Oct 2018 11:04:16 -0700 Subject: [PATCH 03/11] need to align with data model specs for v1beta4 --- google-beta/resource_sql_database_instance.go | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/google-beta/resource_sql_database_instance.go b/google-beta/resource_sql_database_instance.go index 18198a0143..076d3a4b7f 100644 --- a/google-beta/resource_sql_database_instance.go +++ b/google-beta/resource_sql_database_instance.go @@ -264,7 +264,7 @@ func resourceSqlDatabaseInstance() *schema.Resource { ForceNew: true, }, - "ip_address": &schema.Schema{ + "ip_addresses": &schema.Schema{ Type: schema.TypeList, Computed: true, Elem: &schema.Resource{ @@ -273,6 +273,10 @@ func resourceSqlDatabaseInstance() *schema.Resource { Type: schema.TypeString, Computed: true, }, + "type": &schema.Schema{ + Type: schema.TypeString, + Computed: true, + }, "time_to_retire": &schema.Schema{ Type: schema.TypeString, Optional: true, @@ -706,9 +710,8 @@ func resourceSqlDatabaseInstanceRead(d *schema.ResourceData, meta interface{}) e if err := d.Set("replica_configuration", flattenReplicaConfiguration(instance.ReplicaConfiguration, d)); err != nil { log.Printf("[WARN] Failed to set SQL Database Instance Replica Configuration") } - ipAddresses := flattenIpAddresses(instance.IpAddresses) - if err := d.Set("ip_address", ipAddresses); err != nil { + if err := d.Set("ip_addresses", ipAddresses); err != nil { log.Printf("[WARN] Failed to set SQL Database Instance IP Addresses") } @@ -961,6 +964,7 @@ func flattenIpAddresses(ipAddresses []*sqladmin.IpMapping) []map[string]interfac for _, ip := range ipAddresses { data := map[string]interface{}{ "ip_address": ip.IpAddress, + "type": ip.Type, "time_to_retire": ip.TimeToRetire, } From 88651dce9cd257846e3660f530c554436cc23ff7 Mon Sep 17 00:00:00 2001 From: "Jimmy Y. Huang" Date: Sun, 28 Oct 2018 15:59:26 -0700 Subject: [PATCH 04/11] can now create instances with private IP --- google-beta/resource_sql_database_instance.go | 1 + 1 file changed, 1 insertion(+) diff --git a/google-beta/resource_sql_database_instance.go b/google-beta/resource_sql_database_instance.go index 076d3a4b7f..1670cc9e9a 100644 --- a/google-beta/resource_sql_database_instance.go +++ b/google-beta/resource_sql_database_instance.go @@ -632,6 +632,7 @@ func expandIpConfiguration(configured []interface{}) *sqladmin.IpConfiguration { RequireSsl: _ipConfiguration["require_ssl"].(bool), PrivateNetwork: _ipConfiguration["private_network"].(string), AuthorizedNetworks: expandAuthorizedNetworks(_ipConfiguration["authorized_networks"].(*schema.Set).List()), + ForceSendFields: []string{"Ipv4Enabled"}, } } func expandAuthorizedNetworks(configured []interface{}) []*sqladmin.AclEntry { From fc1e236286b4f70ff5d98fd2cf1e2dfc5baab38d Mon Sep 17 00:00:00 2001 From: craigatgoogle Date: Fri, 16 Nov 2018 09:15:25 -0800 Subject: [PATCH 05/11] Reverted ip_addresses to ip_address in sql schema --- google-beta/resource_sql_database_instance.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/google-beta/resource_sql_database_instance.go b/google-beta/resource_sql_database_instance.go index 1670cc9e9a..aadd4e5500 100644 --- a/google-beta/resource_sql_database_instance.go +++ b/google-beta/resource_sql_database_instance.go @@ -264,7 +264,7 @@ func resourceSqlDatabaseInstance() *schema.Resource { ForceNew: true, }, - "ip_addresses": &schema.Schema{ + "ip_address": &schema.Schema{ Type: schema.TypeList, Computed: true, Elem: &schema.Resource{ @@ -712,7 +712,7 @@ func resourceSqlDatabaseInstanceRead(d *schema.ResourceData, meta interface{}) e log.Printf("[WARN] Failed to set SQL Database Instance Replica Configuration") } ipAddresses := flattenIpAddresses(instance.IpAddresses) - if err := d.Set("ip_addresses", ipAddresses); err != nil { + if err := d.Set("ip_address", ipAddresses); err != nil { log.Printf("[WARN] Failed to set SQL Database Instance IP Addresses") } From 7c79fe0027b70a7ecfb7bbca52e1bd478e4d7965 Mon Sep 17 00:00:00 2001 From: craigatgoogle Date: Tue, 20 Nov 2018 10:47:31 -0800 Subject: [PATCH 06/11] Added acctest for private sql instance --- .../resource_sql_database_instance_test.go | 60 +++++++++++++++++++ 1 file changed, 60 insertions(+) diff --git a/google-beta/resource_sql_database_instance_test.go b/google-beta/resource_sql_database_instance_test.go index 7dd072ff0d..f535d85dd0 100644 --- a/google-beta/resource_sql_database_instance_test.go +++ b/google-beta/resource_sql_database_instance_test.go @@ -594,6 +594,30 @@ func TestAccSqlDatabaseInstance_basic_with_user_labels(t *testing.T) { }) } +func TestAccSqlDatabaseInstance_with_private_network(t *testing.T) { + t.Parallel() + + databaseName := "tf-test-" + acctest.RandString(10) + networkName := "tf-test-" + acctest.RandString(10) + addressName := "tf-test-" + acctest.RandString(10) + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccSqlDatabaseInstanceDestroy, + Steps: []resource.TestStep{ + resource.TestStep{ + Config: testAccSqlDatabaseInstance_with_private_network(databaseName, networkName, addressName), + }, + resource.TestStep{ + ResourceName: "google_sql_database_instance.instance", + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + func testAccSqlDatabaseInstanceDestroy(s *terraform.State) error { for _, rs := range s.RootModule().Resources { config := testAccProvider.Meta().(*Config) @@ -714,6 +738,42 @@ resource "google_sql_database_instance" "instance-failover" { `, instanceName, failoverName) } +func testAccSqlDatabaseInstance_with_private_network(databaseName, networkName, addressRangeName string) string { + return fmt.Sprintf(` +resource "google_compute_network" "foobar" { + name = "%s" +} + +resource "google_compute_global_address" "foobar" { + name = "%s" + purpose = "VPC_PEERING" + address_type = "INTERNAL" + prefix_length = 16 + network = "${google_compute_network.foobar.self_link}" +} + +resource "google_service_networking_connection" "foobar" { + network = "${google_compute_network.foobar.self_link}" + service = "servicenetworking.googleapis.com" + reserved_peering_ranges = ["${google_compute_global_address.foobar.name}"] +} + +# TODO figure out a way to specify the dependency to the connection resource +resource "google_sql_database_instance" "instance" { + depends_on = ["google_service_networking_connection.foobar"] + name = "%s" + region = "us-central1" + settings { + tier = "db-f1-micro" + ip_configuration { + ipv4_enabled = "false" + private_network = "${google_compute_network.foobar.self_link}" + } + } +} +`, networkName, addressRangeName, databaseName) +} + var testGoogleSqlDatabaseInstance_settings = ` resource "google_sql_database_instance" "instance" { name = "tf-lw-%d" From 5a974d747b3255ba8c1d8ca5ca44315f24455116 Mon Sep 17 00:00:00 2001 From: craigatgoogle Date: Tue, 20 Nov 2018 15:04:12 -0800 Subject: [PATCH 07/11] Incorporated review feedback --- google-beta/resource_sql_database_instance_test.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/google-beta/resource_sql_database_instance_test.go b/google-beta/resource_sql_database_instance_test.go index f535d85dd0..29208e85da 100644 --- a/google-beta/resource_sql_database_instance_test.go +++ b/google-beta/resource_sql_database_instance_test.go @@ -594,7 +594,7 @@ func TestAccSqlDatabaseInstance_basic_with_user_labels(t *testing.T) { }) } -func TestAccSqlDatabaseInstance_with_private_network(t *testing.T) { +func TestAccSqlDatabaseInstance_withPrivateNetwork(t *testing.T) { t.Parallel() databaseName := "tf-test-" + acctest.RandString(10) @@ -607,7 +607,7 @@ func TestAccSqlDatabaseInstance_with_private_network(t *testing.T) { CheckDestroy: testAccSqlDatabaseInstanceDestroy, Steps: []resource.TestStep{ resource.TestStep{ - Config: testAccSqlDatabaseInstance_with_private_network(databaseName, networkName, addressName), + Config: testAccSqlDatabaseInstance_withPrivateNetwork(databaseName, networkName, addressName), }, resource.TestStep{ ResourceName: "google_sql_database_instance.instance", @@ -738,10 +738,11 @@ resource "google_sql_database_instance" "instance-failover" { `, instanceName, failoverName) } -func testAccSqlDatabaseInstance_with_private_network(databaseName, networkName, addressRangeName string) string { +func testAccSqlDatabaseInstance_withPrivateNetwork(databaseName, networkName, addressRangeName string) string { return fmt.Sprintf(` resource "google_compute_network" "foobar" { name = "%s" + auto_create_subnetworks = false } resource "google_compute_global_address" "foobar" { @@ -758,7 +759,6 @@ resource "google_service_networking_connection" "foobar" { reserved_peering_ranges = ["${google_compute_global_address.foobar.name}"] } -# TODO figure out a way to specify the dependency to the connection resource resource "google_sql_database_instance" "instance" { depends_on = ["google_service_networking_connection.foobar"] name = "%s" From af7b4f6d9a99e98634b76ac31c4c5189db8d42fd Mon Sep 17 00:00:00 2001 From: craigatgoogle Date: Tue, 20 Nov 2018 16:18:36 -0800 Subject: [PATCH 08/11] removed unnecessary schema field --- google-beta/resource_sql_database_instance.go | 4 ---- 1 file changed, 4 deletions(-) diff --git a/google-beta/resource_sql_database_instance.go b/google-beta/resource_sql_database_instance.go index aadd4e5500..16be8dbba2 100644 --- a/google-beta/resource_sql_database_instance.go +++ b/google-beta/resource_sql_database_instance.go @@ -273,10 +273,6 @@ func resourceSqlDatabaseInstance() *schema.Resource { Type: schema.TypeString, Computed: true, }, - "type": &schema.Schema{ - Type: schema.TypeString, - Computed: true, - }, "time_to_retire": &schema.Schema{ Type: schema.TypeString, Optional: true, From 2f69d29630eec80986016dd3c452269c592ea3da Mon Sep 17 00:00:00 2001 From: craigatgoogle Date: Tue, 20 Nov 2018 16:23:54 -0800 Subject: [PATCH 09/11] Added updated documentation for private cloud sql --- .../r/sql_database_instance.html.markdown | 39 +++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/website/docs/r/sql_database_instance.html.markdown b/website/docs/r/sql_database_instance.html.markdown index 7a2a2a5d9d..fed1e4d23b 100644 --- a/website/docs/r/sql_database_instance.html.markdown +++ b/website/docs/r/sql_database_instance.html.markdown @@ -108,6 +108,42 @@ resource "google_sql_database_instance" "postgres" { } ``` +### Private IP Instance + + +```hcl +resource "google_compute_network" "private_network" { + name = "private_network" +} + +resource "google_compute_global_address" "private_ip_address" { + name = "private_ip_address" + purpose = "VPC_PEERING" + address_type = "INTERNAL" + prefix_length = 16 + network = "${google_compute_network.private_network.self_link}" +} + +resource "google_service_networking_connection" "private_vpc_connection" { + network = "${google_compute_network.private_network.self_link}" + service = "servicenetworking.googleapis.com" + reserved_peering_ranges = ["${google_compute_global_address.private_ip_address.name}"] +} + +resource "google_sql_database_instance" "instance" { + depends_on = ["google_service_networking_connection.private_vpc_connection"] + name = "private_instance" + region = "us-central1" + settings { + tier = "db-f1-micro" + ip_configuration { + ipv4_enabled = "false" + private_network = "${google_compute_network.private_network.self_link}" + } + } +} +``` + ## Argument Reference The following arguments are supported: @@ -205,6 +241,9 @@ The optional `settings.ip_configuration` subblock supports: * `require_ssl` - (Optional) True if mysqld should default to `REQUIRE X509` for users connecting over IP. +* `private_network` - (Optional) The resource link for the VPC network from which + the Cloud SQL instance is accessible for private IP. + The optional `settings.ip_configuration.authorized_networks[]` sublist supports: * `expiration_time` - (Optional) The [RFC 3339](https://tools.ietf.org/html/rfc3339) From ee16a169f114c2fd626c91cc010757c6f6997354 Mon Sep 17 00:00:00 2001 From: craigatgoogle Date: Tue, 20 Nov 2018 16:36:11 -0800 Subject: [PATCH 10/11] Revert "removed unnecessary schema field" This reverts commit af7b4f6d9a99e98634b76ac31c4c5189db8d42fd. --- google-beta/resource_sql_database_instance.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/google-beta/resource_sql_database_instance.go b/google-beta/resource_sql_database_instance.go index 16be8dbba2..aadd4e5500 100644 --- a/google-beta/resource_sql_database_instance.go +++ b/google-beta/resource_sql_database_instance.go @@ -273,6 +273,10 @@ func resourceSqlDatabaseInstance() *schema.Resource { Type: schema.TypeString, Computed: true, }, + "type": &schema.Schema{ + Type: schema.TypeString, + Computed: true, + }, "time_to_retire": &schema.Schema{ Type: schema.TypeString, Optional: true, From cfa9ff0849c71b1d2a6ba8c937c380667f5770be Mon Sep 17 00:00:00 2001 From: craigatgoogle Date: Tue, 20 Nov 2018 16:47:41 -0800 Subject: [PATCH 11/11] Added documentation for ipAddress type --- website/docs/r/sql_database_instance.html.markdown | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/website/docs/r/sql_database_instance.html.markdown b/website/docs/r/sql_database_instance.html.markdown index fed1e4d23b..280dbee20b 100644 --- a/website/docs/r/sql_database_instance.html.markdown +++ b/website/docs/r/sql_database_instance.html.markdown @@ -241,8 +241,7 @@ The optional `settings.ip_configuration` subblock supports: * `require_ssl` - (Optional) True if mysqld should default to `REQUIRE X509` for users connecting over IP. -* `private_network` - (Optional) The resource link for the VPC network from which - the Cloud SQL instance is accessible for private IP. +* `private_network` - (Optional) The resource link for the VPC network from which the Cloud SQL instance is accessible for private IP. The optional `settings.ip_configuration.authorized_networks[]` sublist supports: @@ -325,6 +324,8 @@ when the resource is configured with a `count`. * `ip_address.0.time_to_retire` - The time this IP address will be retired, in RFC 3339 format. +* `ip_address.0.type` - The type of this IP address. A PRIMARY address is an address that can accept incoming connections. An OUTGOING address is the source address of connections originating from the instance, if supported. A PRIVATE address is an address for an instance which has been configured to use private networking see: [Private IP](https://cloud.google.com/sql/docs/mysql/private-ip). + * `self_link` - The URI of the created resource. * `settings.version` - Used to make sure changes to the `settings` block are