Skip to content

Commit

Permalink
Add ssl_mode option to google_sql_database_instance.
Browse files Browse the repository at this point in the history
  • Loading branch information
feng-zhe committed Oct 20, 2023
1 parent b7e0a8c commit 6f9dc72
Show file tree
Hide file tree
Showing 5 changed files with 249 additions and 5 deletions.
2 changes: 1 addition & 1 deletion mmv1/third_party/terraform/go.mod.erb
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ require (
github.com/sirupsen/logrus v1.8.1
golang.org/x/net v0.16.0
golang.org/x/oauth2 v0.13.0
google.golang.org/api v0.143.0
google.golang.org/api v0.148.0
google.golang.org/genproto/googleapis/rpc v0.0.0-20230920204549-e6e6cdab5c13
google.golang.org/grpc v1.57.0
google.golang.org/protobuf v1.31.0
Expand Down
4 changes: 2 additions & 2 deletions mmv1/third_party/terraform/go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -371,8 +371,8 @@ golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8T
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 h1:H2TDz8ibqkAF6YGhCdN3jS9O0/s90v0rJh3X/OLHEUk=
golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8=
google.golang.org/api v0.143.0 h1:o8cekTkqhywkbZT6p1UHJPZ9+9uuCAJs/KYomxZB8fA=
google.golang.org/api v0.143.0/go.mod h1:FoX9DO9hT7DLNn97OuoZAGSDuNAXdJRuGK98rSUgurk=
google.golang.org/api v0.148.0 h1:HBq4TZlN4/1pNcu0geJZ/Q50vIwIXT532UIMYoo0vOs=
google.golang.org/api v0.148.0/go.mod h1:8/TBgwaKjfqTdacOJrOv2+2Q6fBDU1uHKK06oGSkxzU=
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ var (
"settings.0.ip_configuration.0.allocated_ip_range",
"settings.0.ip_configuration.0.enable_private_path_for_google_cloud_services",
"settings.0.ip_configuration.0.psc_config",
"settings.0.ip_configuration.0.ssl_mode",
}

maintenanceWindowKeys = []string{
Expand Down Expand Up @@ -480,6 +481,13 @@ is set to true. Defaults to ZONAL.`,
},
},
},
"ssl_mode": {
Type: schema.TypeString,
Optional: true,
ValidateFunc: validation.StringInSlice([]string{"SSL_MODE_UNSPECIFIED", "ALLOW_UNENCRYPTED_AND_ENCRYPTED", "ENCRYPTED_ONLY", "TRUSTED_CLIENT_CERTIFICATE_REQUIRED"}, false),
Description: `Specify how SSL connection should be enforced in DB connections.`,
AtLeastOneOf: ipConfigurationKeys,
},
},
},
},
Expand Down Expand Up @@ -1382,6 +1390,7 @@ func expandIpConfiguration(configured []interface{}, databaseVersion string) *sq
EnablePrivatePathForGoogleCloudServices: _ipConfiguration["enable_private_path_for_google_cloud_services"].(bool),
ForceSendFields: forceSendFields,
PscConfig: expandPscConfig(_ipConfiguration["psc_config"].(*schema.Set).List()),
SslMode: _ipConfiguration["ssl_mode"].(string),
}
}

Expand Down Expand Up @@ -2189,6 +2198,7 @@ func flattenIpConfiguration(ipConfiguration *sqladmin.IpConfiguration) interface
"allocated_ip_range": ipConfiguration.AllocatedIpRange,
"require_ssl": ipConfiguration.RequireSsl,
"enable_private_path_for_google_cloud_services": ipConfiguration.EnablePrivatePathForGoogleCloudServices,
"ssl_mode": ipConfiguration.SslMode,
}

if ipConfiguration.AuthorizedNetworks != nil {
Expand Down Expand Up @@ -2487,4 +2497,4 @@ func validatePromoteConfigurations(masterInstanceName cty.Value, replicaConfigur
return fmt.Errorf("Replica promote configuration check failed. Please remove replica_configuration and try again.")
}
return nil
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2128,6 +2128,235 @@ func TestAccSqlDatabaseInstance_ReplicaPromoteSkippedWithNoMasterInstanceNameAnd
})
}

func TestAccSqlDatabaseInstance_updateSslOptionsForPostgreSQL(t *testing.T) {
t.Parallel()

databaseName := "tf-test-" + acctest.RandString(t, 10)
databaseVersion := "POSTGRES_14"
resourceName := "google_sql_database_instance.instance"

acctest.VcrTest(t, resource.TestCase{
PreCheck: func() { acctest.AccTestPreCheck(t) },
ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories(t),
CheckDestroy: testAccSqlDatabaseInstanceDestroyProducer(t),
Steps: []resource.TestStep{
{
Config: testGoogleSqlDatabaseInstance_setSslOptions(databaseName, databaseVersion, false, "ALLOW_UNENCRYPTED_AND_ENCRYPTED"),
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttr(resourceName, "settings.0.ip_configuration.0.require_ssl", "false"),
resource.TestCheckResourceAttr(resourceName, "settings.0.ip_configuration.0.ssl_mode", "ALLOW_UNENCRYPTED_AND_ENCRYPTED"),
),
},
{
ResourceName: resourceName,
ImportState: true,
ImportStateVerify: true,
ImportStateVerifyIgnore: []string{"deletion_protection"},
},
{
Config: testGoogleSqlDatabaseInstance_setSslOptions(databaseName, databaseVersion, false, "ENCRYPTED_ONLY"),
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttr(resourceName, "settings.0.ip_configuration.0.require_ssl", "false"),
resource.TestCheckResourceAttr(resourceName, "settings.0.ip_configuration.0.ssl_mode", "ENCRYPTED_ONLY"),
),
},
{
ResourceName: resourceName,
ImportState: true,
ImportStateVerify: true,
ImportStateVerifyIgnore: []string{"deletion_protection"},
},
{
Config: testGoogleSqlDatabaseInstance_setSslOptions(databaseName, databaseVersion, true, "TRUSTED_CLIENT_CERTIFICATE_REQUIRED"),
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttr(resourceName, "settings.0.ip_configuration.0.require_ssl", "true"),
resource.TestCheckResourceAttr(resourceName, "settings.0.ip_configuration.0.ssl_mode", "TRUSTED_CLIENT_CERTIFICATE_REQUIRED"),
),
},
{
ResourceName: resourceName,
ImportState: true,
ImportStateVerify: true,
ImportStateVerifyIgnore: []string{"deletion_protection"},
},
{
Config: testGoogleSqlDatabaseInstance_setSslOptions(databaseName, databaseVersion, false, "ALLOW_UNENCRYPTED_AND_ENCRYPTED"),
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttr(resourceName, "settings.0.ip_configuration.0.require_ssl", "false"),
resource.TestCheckResourceAttr(resourceName, "settings.0.ip_configuration.0.ssl_mode", "ALLOW_UNENCRYPTED_AND_ENCRYPTED"),
),
},
{
ResourceName: resourceName,
ImportState: true,
ImportStateVerify: true,
ImportStateVerifyIgnore: []string{"deletion_protection"},
},
},
})
}

func TestAccSqlDatabaseInstance_updateSslOptionsForMySQL(t *testing.T) {
t.Parallel()

databaseName := "tf-test-" + acctest.RandString(t, 10)
databaseVersion := "MYSQL_8_0"
resourceName := "google_sql_database_instance.instance"

acctest.VcrTest(t, resource.TestCase{
PreCheck: func() { acctest.AccTestPreCheck(t) },
ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories(t),
CheckDestroy: testAccSqlDatabaseInstanceDestroyProducer(t),
Steps: []resource.TestStep{
{
Config: testGoogleSqlDatabaseInstance_setSslOptions(databaseName, databaseVersion, false, "ALLOW_UNENCRYPTED_AND_ENCRYPTED"),
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttr(resourceName, "settings.0.ip_configuration.0.require_ssl", "false"),
resource.TestCheckResourceAttr(resourceName, "settings.0.ip_configuration.0.ssl_mode", "ALLOW_UNENCRYPTED_AND_ENCRYPTED"),
),
},
{
ResourceName: resourceName,
ImportState: true,
ImportStateVerify: true,
ImportStateVerifyIgnore: []string{"deletion_protection"},
},
{
Config: testGoogleSqlDatabaseInstance_setSslOptions(databaseName, databaseVersion, false, "ENCRYPTED_ONLY"),
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttr(resourceName, "settings.0.ip_configuration.0.require_ssl", "false"),
resource.TestCheckResourceAttr(resourceName, "settings.0.ip_configuration.0.ssl_mode", "ENCRYPTED_ONLY"),
),
},
{
ResourceName: resourceName,
ImportState: true,
ImportStateVerify: true,
ImportStateVerifyIgnore: []string{"deletion_protection"},
},
{
Config: testGoogleSqlDatabaseInstance_setSslOptions(databaseName, databaseVersion, true, "TRUSTED_CLIENT_CERTIFICATE_REQUIRED"),
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttr(resourceName, "settings.0.ip_configuration.0.require_ssl", "true"),
resource.TestCheckResourceAttr(resourceName, "settings.0.ip_configuration.0.ssl_mode", "TRUSTED_CLIENT_CERTIFICATE_REQUIRED"),
),
},
{
ResourceName: resourceName,
ImportState: true,
ImportStateVerify: true,
ImportStateVerifyIgnore: []string{"deletion_protection"},
},
{
Config: testGoogleSqlDatabaseInstance_setSslOptions(databaseName, databaseVersion, false, "ALLOW_UNENCRYPTED_AND_ENCRYPTED"),
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttr(resourceName, "settings.0.ip_configuration.0.require_ssl", "false"),
resource.TestCheckResourceAttr(resourceName, "settings.0.ip_configuration.0.ssl_mode", "ALLOW_UNENCRYPTED_AND_ENCRYPTED"),
),
},
{
ResourceName: resourceName,
ImportState: true,
ImportStateVerify: true,
ImportStateVerifyIgnore: []string{"deletion_protection"},
},
},
})
}

func TestAccSqlDatabaseInstance_updateSslOptionsForSqlServer(t *testing.T) {
t.Parallel()

databaseName := "tf-test-" + acctest.RandString(t, 10)
databaseVersion := "SQLSERVER_2019_STANDARD"
resourceName := "google_sql_database_instance.instance"

acctest.VcrTest(t, resource.TestCase{
PreCheck: func() { acctest.AccTestPreCheck(t) },
ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories(t),
CheckDestroy: testAccSqlDatabaseInstanceDestroyProducer(t),
Steps: []resource.TestStep{
{
Config: testGoogleSqlDatabaseInstance_setSslOptionsForSqlServer(databaseName, databaseVersion, false, "ALLOW_UNENCRYPTED_AND_ENCRYPTED"),
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttr(resourceName, "settings.0.ip_configuration.0.require_ssl", "false"),
resource.TestCheckResourceAttr(resourceName, "settings.0.ip_configuration.0.ssl_mode", "ALLOW_UNENCRYPTED_AND_ENCRYPTED"),
),
},
{
ResourceName: resourceName,
ImportState: true,
ImportStateVerify: true,
ImportStateVerifyIgnore: []string{"root_password", "deletion_protection"},
},
{
Config: testGoogleSqlDatabaseInstance_setSslOptionsForSqlServer(databaseName, databaseVersion, true, "ENCRYPTED_ONLY"),
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttr(resourceName, "settings.0.ip_configuration.0.require_ssl", "true"),
resource.TestCheckResourceAttr(resourceName, "settings.0.ip_configuration.0.ssl_mode", "ENCRYPTED_ONLY"),
),
},
{
ResourceName: resourceName,
ImportState: true,
ImportStateVerify: true,
ImportStateVerifyIgnore: []string{"root_password", "deletion_protection"},
},
{
Config: testGoogleSqlDatabaseInstance_setSslOptionsForSqlServer(databaseName, databaseVersion, false, "ALLOW_UNENCRYPTED_AND_ENCRYPTED"),
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttr(resourceName, "settings.0.ip_configuration.0.require_ssl", "false"),
resource.TestCheckResourceAttr(resourceName, "settings.0.ip_configuration.0.ssl_mode", "ALLOW_UNENCRYPTED_AND_ENCRYPTED"),
),
},
{
ResourceName: resourceName,
ImportState: true,
ImportStateVerify: true,
ImportStateVerifyIgnore: []string{"root_password", "deletion_protection"},
},
},
})
}

func testGoogleSqlDatabaseInstance_setSslOptions(databaseName string, databaseVersion string, requireSsl bool, sslMode string) string {
return fmt.Sprintf(`
resource "google_sql_database_instance" "instance" {
name = "%s"
region = "us-east1"
database_version = "%s"
deletion_protection = false
settings {
tier = "db-f1-micro"
ip_configuration {
ipv4_enabled = true
require_ssl = %t
ssl_mode = "%s"
}
}
}`, databaseName, databaseVersion, requireSsl, sslMode)
}

func testGoogleSqlDatabaseInstance_setSslOptionsForSqlServer(databaseName string, databaseVersion string, requireSsl bool, sslMode string) string {
return fmt.Sprintf(`
resource "google_sql_database_instance" "instance" {
name = "%s"
region = "us-east1"
database_version = "%s"
deletion_protection = false
root_password = "rand-pwd"
settings {
tier = "db-custom-1-3840"
collation = "Polish_CI_AS"
ip_configuration {
ipv4_enabled = true
require_ssl = %t
ssl_mode = "%s"
}
}
}`, databaseName, databaseVersion, requireSsl, sslMode)
}

func testAccSqlDatabaseInstance_sqlMysqlInstancePvpExample(context map[string]interface{}) string {
return acctest.Nprintf(`
resource "google_sql_database_instance" "mysql_pvp_instance_name" {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -372,7 +372,12 @@ Specifying a network enables private IP.
At least `ipv4_enabled` must be enabled or a `private_network` must be configured.
This setting can be updated, but it cannot be removed after it is set.

* `require_ssl` - (Optional) Whether SSL connections over IP are enforced or not.
* `require_ssl` - (Optional) Whether SSL connections over IP are enforced or not. Please also populate `ssl_mode`.

* `ssl_mode` - (Optional) Specify how SSL connection should be enforced in DB connections. This field provides more SSL enforcment options compared to `require_ssl`. To change this field, please also set the correspoding value in `require_ssl`.
* For PostgreSQL instances, the value pairs are listed in the [API reference doc](https://cloud.google.com/sql/docs/mysql/admin-api/rest/v1beta4/instances#ipconfiguration) for `ssl_mode` field.
* For MySQL instances, use the same value pairs as the PostgreSQL instances.
* For SQL Server instances, set it to `ALLOW_UNENCRYPTED_AND_ENCRYPTED` when `require_ssl=false` and `ENCRYPTED_ONLY` otherwise.

* `allocated_ip_range` - (Optional) The name of the allocated ip range for the private ip CloudSQL instance. For example: "google-managed-services-default". If set, the instance ip will be created in the allocated range. The range name must comply with [RFC 1035](https://datatracker.ietf.org/doc/html/rfc1035). Specifically, the name must be 1-63 characters long and match the regular expression [a-z]([-a-z0-9]*[a-z0-9])?.

Expand Down

0 comments on commit 6f9dc72

Please sign in to comment.