Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add SQL Server Audit Config #11941

Merged
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
3 changes: 3 additions & 0 deletions .changelog/6156.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
```release-note:enhancement
sql: added `sql_server_audit_config` field in `google_sql_database_instance`
```
56 changes: 56 additions & 0 deletions google/resource_sql_database_instance.go
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,30 @@ func resourceSqlDatabaseInstance() *schema.Resource {
},
},
},
"sql_server_audit_config": {
Type: schema.TypeList,
Optional: true,
MaxItems: 1,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"bucket": {
Type: schema.TypeString,
Required: true,
Description: `The name of the destination bucket (e.g., gs://mybucket).`,
},
"retention_interval": {
Type: schema.TypeString,
Optional: true,
Description: `How long to keep generated audit files. A duration in seconds with up to nine fractional digits, terminated by 's'. Example: "3.5s"..`,
},
"upload_interval": {
Type: schema.TypeString,
Optional: true,
Description: `How often to upload generated audit files. A duration in seconds with up to nine fractional digits, terminated by 's'. Example: "3.5s".`,
},
},
},
},
"availability_type": {
Type: schema.TypeString,
Optional: true,
Expand Down Expand Up @@ -944,6 +968,7 @@ func expandSqlDatabaseInstanceSettings(configured []interface{}) *sqladmin.Setti
ForceSendFields: []string{"StorageAutoResize"},
ActivationPolicy: _settings["activation_policy"].(string),
ActiveDirectoryConfig: expandActiveDirectoryConfig(_settings["active_directory_config"].([]interface{})),
SqlServerAuditConfig: expandSqlServerAuditConfig(_settings["sql_server_audit_config"].([]interface{})),
AvailabilityType: _settings["availability_type"].(string),
Collation: _settings["collation"].(string),
DataDiskSizeGb: int64(_settings["disk_size"].(int)),
Expand Down Expand Up @@ -1118,6 +1143,20 @@ func expandActiveDirectoryConfig(configured interface{}) *sqladmin.SqlActiveDire
}
}

func expandSqlServerAuditConfig(configured interface{}) *sqladmin.SqlServerAuditConfig {
l := configured.([]interface{})
if len(l) == 0 {
return nil
}

config := l[0].(map[string]interface{})
return &sqladmin.SqlServerAuditConfig{
Bucket: config["bucket"].(string),
RetentionInterval: config["retention_interval"].(string),
UploadInterval: config["upload_interval"].(string),
}
}

func expandInsightsConfig(configured []interface{}) *sqladmin.InsightsConfig {
if len(configured) == 0 || configured[0] == nil {
return nil
Expand Down Expand Up @@ -1358,6 +1397,10 @@ func flattenSettings(settings *sqladmin.Settings) []map[string]interface{} {
data["active_directory_config"] = flattenActiveDirectoryConfig(settings.ActiveDirectoryConfig)
}

if settings.SqlServerAuditConfig != nil {
data["sql_server_audit_config"] = flattenSqlServerAuditConfig(settings.SqlServerAuditConfig)
}

if settings.BackupConfiguration != nil {
data["backup_configuration"] = flattenBackupConfiguration(settings.BackupConfiguration)
}
Expand Down Expand Up @@ -1429,6 +1472,19 @@ func flattenActiveDirectoryConfig(sqlActiveDirectoryConfig *sqladmin.SqlActiveDi
}
}

func flattenSqlServerAuditConfig(sqlServerAuditConfig *sqladmin.SqlServerAuditConfig) []map[string]interface{} {
if sqlServerAuditConfig == nil {
return nil
}
return []map[string]interface{}{
{
"bucket": sqlServerAuditConfig.Bucket,
"retention_interval": sqlServerAuditConfig.RetentionInterval,
"upload_interval": sqlServerAuditConfig.UploadInterval,
},
}
}

func flattenDatabaseFlags(databaseFlags []*sqladmin.DatabaseFlags) []map[string]interface{} {
flags := make([]map[string]interface{}, 0, len(databaseFlags))

Expand Down
89 changes: 89 additions & 0 deletions google/resource_sql_database_instance_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1053,6 +1053,46 @@ func TestAccSqlDatabaseInstance_ActiveDirectory(t *testing.T) {
})
}

func TestAccSqlDatabaseInstance_SqlServerAuditConfig(t *testing.T) {
t.Parallel()
databaseName := "tf-test-" + randString(t, 10)
rootPassword := randString(t, 15)
addressName := "tf-test-" + randString(t, 10)
networkName := BootstrapSharedTestNetwork(t, "sql-instance-private-allocated-ip-range")
bucketName := fmt.Sprintf("%s-%d", "tf-test-bucket", randInt(t))
uploadInterval := "900s"
retentionInterval := "86400s"
bucketNameUpdate := fmt.Sprintf("%s-%d", "tf-test-bucket", randInt(t)) + "update"
uploadIntervalUpdate := "1200s"
retentionIntervalUpdate := "172800s"

vcrTest(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testAccSqlDatabaseInstanceDestroyProducer(t),
Steps: []resource.TestStep{
{
Config: testGoogleSqlDatabaseInstance_SqlServerAuditConfig(networkName, addressName, databaseName, rootPassword, bucketName, uploadInterval, retentionInterval),
},
{
ResourceName: "google_sql_database_instance.instance",
ImportState: true,
ImportStateVerify: true,
ImportStateVerifyIgnore: []string{"root_password", "deletion_protection"},
},
{
Config: testGoogleSqlDatabaseInstance_SqlServerAuditConfig(networkName, addressName, databaseName, rootPassword, bucketNameUpdate, uploadIntervalUpdate, retentionIntervalUpdate),
},
{
ResourceName: "google_sql_database_instance.instance",
ImportState: true,
ImportStateVerify: true,
ImportStateVerifyIgnore: []string{"root_password", "deletion_protection"},
},
},
})
}

var testGoogleSqlDatabaseInstance_basic2 = `
resource "google_sql_database_instance" "instance" {
region = "us-central1"
Expand Down Expand Up @@ -1130,6 +1170,55 @@ resource "google_sql_database_instance" "instance-with-ad" {
}`, networkName, addressRangeName, databaseName, rootPassword, adDomainName)
}

func testGoogleSqlDatabaseInstance_SqlServerAuditConfig(networkName, addressName, databaseName, rootPassword, bucketName, uploadInterval, retentionInterval string) string {
return fmt.Sprintf(`
resource "google_storage_bucket" "gs-bucket" {
name = "%s"
location = "US"
uniform_bucket_level_access = true
}

data "google_compute_network" "servicenet" {
name = "%s"
}

resource "google_compute_global_address" "foobar" {
name = "%s"
purpose = "VPC_PEERING"
address_type = "INTERNAL"
prefix_length = 16
network = data.google_compute_network.servicenet.self_link
}

resource "google_service_networking_connection" "foobar" {
network = data.google_compute_network.servicenet.self_link
service = "servicenetworking.googleapis.com"
reserved_peering_ranges = [google_compute_global_address.foobar.name]
}

resource "google_sql_database_instance" "instance" {
depends_on = [google_service_networking_connection.foobar]
name = "%s"
region = "us-central1"
database_version = "SQLSERVER_2017_STANDARD"
root_password = "%s"
deletion_protection = false
settings {
tier = "db-custom-1-3840"
ip_configuration {
ipv4_enabled = "false"
private_network = data.google_compute_network.servicenet.self_link
}
sql_server_audit_config {
bucket = "gs://%s"
retention_interval = "%s"
upload_interval = "%s"
}
}
}
`, bucketName, networkName, addressName, databaseName, rootPassword, bucketName, retentionInterval, uploadInterval)
}

func testGoogleSqlDatabaseInstanceConfig_withoutReplica(instanceName string) string {
return fmt.Sprintf(`
resource "google_sql_database_instance" "instance" {
Expand Down
8 changes: 8 additions & 0 deletions website/docs/r/sql_database_instance.html.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -259,6 +259,14 @@ The optional `settings.active_directory_config` subblock supports:
* `domain` - (Required) The domain name for the active directory (e.g., mydomain.com).
Can only be used with SQL Server.

The optional `settings.sql_server_audit_config` subblock supports:

* `bucket` - (Required) The name of the destination bucket (e.g., gs://mybucket).

* `upload_interval` - (Optional) How often to upload generated audit files. A duration in seconds with up to nine fractional digits, terminated by 's'. Example: "3.5s".

* `retention_interval` - (Optional) How long to keep generated audit files. A duration in seconds with up to nine fractional digits, terminated by 's'. Example: "3.5s".

The optional `settings.backup_configuration` subblock supports:

* `binary_log_enabled` - (Optional) True if binary logging is enabled.
Expand Down