From 095f7499550806d79f37b273324be4c038f79711 Mon Sep 17 00:00:00 2001 From: Bryce McLeod Date: Tue, 17 May 2022 13:28:55 +0100 Subject: [PATCH 01/13] dms: allow mysql and aurora dms endpoints to load connection info from secrets --- internal/service/dms/endpoint.go | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/internal/service/dms/endpoint.go b/internal/service/dms/endpoint.go index 3341452fbde2..7d7786bc70d7 100644 --- a/internal/service/dms/endpoint.go +++ b/internal/service/dms/endpoint.go @@ -620,6 +620,13 @@ func resourceEndpointCreate(d *schema.ResourceData, meta interface{}) error { } switch d.Get("engine_name").(string) { + case engineNameAurora: + if _, ok := d.GetOk("secrets_manager_arn"); ok { + request.MySQLSettings = &dms.MySQLSettings{ + SecretsManagerAccessRoleArn: aws.String(d.Get("secrets_manager_access_role_arn").(string)), + SecretsManagerSecretId: aws.String(d.Get("secrets_manager_arn").(string)), + } + } case engineNameDynamoDB: request.DynamoDbSettings = &dms.DynamoDbSettings{ ServiceAccessRoleArn: aws.String(d.Get("service_access_role").(string)), @@ -658,6 +665,13 @@ func resourceEndpointCreate(d *schema.ResourceData, meta interface{}) error { request.ServerName = aws.String(d.Get("server_name").(string)) request.Port = aws.Int64(int64(d.Get("port").(int))) request.DatabaseName = aws.String(d.Get("database_name").(string)) + case engineNameMySQL: + if _, ok := d.GetOk("secrets_manager_arn"); ok { + request.MySQLSettings = &dms.MySQLSettings{ + SecretsManagerAccessRoleArn: aws.String(d.Get("secrets_manager_access_role_arn").(string)), + SecretsManagerSecretId: aws.String(d.Get("secrets_manager_arn").(string)), + } + } case engineNameOracle: if _, ok := d.GetOk("secrets_manager_arn"); ok { request.OracleSettings = &dms.OracleSettings{ From e1accfacd57029d1916348128bac4e718beac041 Mon Sep 17 00:00:00 2001 From: Bryce McLeod Date: Tue, 17 May 2022 13:49:13 +0100 Subject: [PATCH 02/13] dms: tests for aurora and mysql endpoint types --- internal/service/dms/endpoint.go | 30 +++ internal/service/dms/endpoint_test.go | 301 +++++++++++++++++++++++++- 2 files changed, 330 insertions(+), 1 deletion(-) diff --git a/internal/service/dms/endpoint.go b/internal/service/dms/endpoint.go index 7d7786bc70d7..d625bef70942 100644 --- a/internal/service/dms/endpoint.go +++ b/internal/service/dms/endpoint.go @@ -626,6 +626,21 @@ func resourceEndpointCreate(d *schema.ResourceData, meta interface{}) error { SecretsManagerAccessRoleArn: aws.String(d.Get("secrets_manager_access_role_arn").(string)), SecretsManagerSecretId: aws.String(d.Get("secrets_manager_arn").(string)), } + } else { + request.MySQLSettings = &dms.MySQLSettings{ + Username: aws.String(d.Get("username").(string)), + Password: aws.String(d.Get("password").(string)), + ServerName: aws.String(d.Get("server_name").(string)), + Port: aws.Int64(int64(d.Get("port").(int))), + DatabaseName: aws.String(d.Get("database_name").(string)), + } + + // Set connection info in top-level namespace as well + request.Username = aws.String(d.Get("username").(string)) + request.Password = aws.String(d.Get("password").(string)) + request.ServerName = aws.String(d.Get("server_name").(string)) + request.Port = aws.Int64(int64(d.Get("port").(int))) + request.DatabaseName = aws.String(d.Get("database_name").(string)) } case engineNameDynamoDB: request.DynamoDbSettings = &dms.DynamoDbSettings{ @@ -671,6 +686,21 @@ func resourceEndpointCreate(d *schema.ResourceData, meta interface{}) error { SecretsManagerAccessRoleArn: aws.String(d.Get("secrets_manager_access_role_arn").(string)), SecretsManagerSecretId: aws.String(d.Get("secrets_manager_arn").(string)), } + } else { + request.MySQLSettings = &dms.MySQLSettings{ + Username: aws.String(d.Get("username").(string)), + Password: aws.String(d.Get("password").(string)), + ServerName: aws.String(d.Get("server_name").(string)), + Port: aws.Int64(int64(d.Get("port").(int))), + DatabaseName: aws.String(d.Get("database_name").(string)), + } + + // Set connection info in top-level namespace as well + request.Username = aws.String(d.Get("username").(string)) + request.Password = aws.String(d.Get("password").(string)) + request.ServerName = aws.String(d.Get("server_name").(string)) + request.Port = aws.Int64(int64(d.Get("port").(int))) + request.DatabaseName = aws.String(d.Get("database_name").(string)) } case engineNameOracle: if _, ok := d.GetOk("secrets_manager_arn"); ok { diff --git a/internal/service/dms/endpoint_test.go b/internal/service/dms/endpoint_test.go index 2a4188140cbc..e07344bbd1e2 100644 --- a/internal/service/dms/endpoint_test.go +++ b/internal/service/dms/endpoint_test.go @@ -55,6 +55,99 @@ func TestAccDMSEndpoint_basic(t *testing.T) { }) } +func TestAccDMSEndpoint_Aurora_basic(t *testing.T) { + resourceName := "aws_dms_endpoint.test" + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { acctest.PreCheck(t) }, + ErrorCheck: acctest.ErrorCheck(t, dms.EndpointsID), + ProviderFactories: acctest.ProviderFactories, + CheckDestroy: testAccCheckEndpointDestroy, + Steps: []resource.TestStep{ + { + Config: testAccEndpointConfig_mySQL(rName, "aurora"), + Check: resource.ComposeTestCheckFunc( + testAccCheckEndpointExists(resourceName), + resource.TestCheckResourceAttrSet(resourceName, "endpoint_arn"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"password"}, + }, + }, + }) +} + +func TestAccDMSEndpoint_Aurora_secretID(t *testing.T) { + resourceName := "aws_dms_endpoint.test" + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { acctest.PreCheck(t) }, + ErrorCheck: acctest.ErrorCheck(t, dms.EndpointsID), + ProviderFactories: acctest.ProviderFactories, + CheckDestroy: testAccCheckEndpointDestroy, + Steps: []resource.TestStep{ + { + Config: testAccEndpointConfig_mySQLSecretID(rName, "aurora"), + Check: resource.ComposeTestCheckFunc( + testAccCheckEndpointExists(resourceName), + resource.TestCheckResourceAttrSet(resourceName, "endpoint_arn"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func TestAccDMSEndpoint_Aurora_update(t *testing.T) { + resourceName := "aws_dms_endpoint.test" + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { acctest.PreCheck(t) }, + ErrorCheck: acctest.ErrorCheck(t, dms.EndpointsID), + ProviderFactories: acctest.ProviderFactories, + CheckDestroy: testAccCheckEndpointDestroy, + Steps: []resource.TestStep{ + { + Config: testAccEndpointConfig_mySQL(rName, "aurora"), + Check: resource.ComposeTestCheckFunc( + testAccCheckEndpointExists(resourceName), + resource.TestCheckResourceAttrSet(resourceName, "endpoint_arn"), + ), + }, + { + Config: testAccEndpointConfig_mySQLUpdate(rName, "aurora"), + Check: resource.ComposeTestCheckFunc( + testAccCheckEndpointExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "server_name", "tftest-new-server_name"), + resource.TestCheckResourceAttr(resourceName, "port", "3307"), + resource.TestCheckResourceAttr(resourceName, "username", "tftest-new-username"), + resource.TestCheckResourceAttr(resourceName, "password", "tftest-new-password"), + resource.TestCheckResourceAttr(resourceName, "database_name", "tftest-new-database_name"), + resource.TestCheckResourceAttr(resourceName, "ssl_mode", "none"), + resource.TestMatchResourceAttr(resourceName, "extra_connection_attributes", regexp.MustCompile(`key=value;`)), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"password"}, + }, + }, + }) +} + func TestAccDMSEndpoint_S3_basic(t *testing.T) { resourceName := "aws_dms_endpoint.test" rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) @@ -507,6 +600,98 @@ func TestAccDMSEndpoint_MongoDB_update(t *testing.T) { }, }) } +func TestAccDMSEndpoint_MySQL_basic(t *testing.T) { + resourceName := "aws_dms_endpoint.test" + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { acctest.PreCheck(t) }, + ErrorCheck: acctest.ErrorCheck(t, dms.EndpointsID), + ProviderFactories: acctest.ProviderFactories, + CheckDestroy: testAccCheckEndpointDestroy, + Steps: []resource.TestStep{ + { + Config: testAccEndpointConfig_mySQL(rName, "mysql"), + Check: resource.ComposeTestCheckFunc( + testAccCheckEndpointExists(resourceName), + resource.TestCheckResourceAttrSet(resourceName, "endpoint_arn"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"password"}, + }, + }, + }) +} + +func TestAccDMSEndpoint_MySQL_secretID(t *testing.T) { + resourceName := "aws_dms_endpoint.test" + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { acctest.PreCheck(t) }, + ErrorCheck: acctest.ErrorCheck(t, dms.EndpointsID), + ProviderFactories: acctest.ProviderFactories, + CheckDestroy: testAccCheckEndpointDestroy, + Steps: []resource.TestStep{ + { + Config: testAccEndpointConfig_mySQLSecretID(rName, "mysql"), + Check: resource.ComposeTestCheckFunc( + testAccCheckEndpointExists(resourceName), + resource.TestCheckResourceAttrSet(resourceName, "endpoint_arn"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func TestAccDMSEndpoint_MySQL_update(t *testing.T) { + resourceName := "aws_dms_endpoint.test" + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { acctest.PreCheck(t) }, + ErrorCheck: acctest.ErrorCheck(t, dms.EndpointsID), + ProviderFactories: acctest.ProviderFactories, + CheckDestroy: testAccCheckEndpointDestroy, + Steps: []resource.TestStep{ + { + Config: testAccEndpointConfig_mySQL(rName, "mysql"), + Check: resource.ComposeTestCheckFunc( + testAccCheckEndpointExists(resourceName), + resource.TestCheckResourceAttrSet(resourceName, "endpoint_arn"), + ), + }, + { + Config: testAccEndpointConfig_mySQLUpdate(rName, "mysql"), + Check: resource.ComposeTestCheckFunc( + testAccCheckEndpointExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "server_name", "tftest-new-server_name"), + resource.TestCheckResourceAttr(resourceName, "port", "3307"), + resource.TestCheckResourceAttr(resourceName, "username", "tftest-new-username"), + resource.TestCheckResourceAttr(resourceName, "password", "tftest-new-password"), + resource.TestCheckResourceAttr(resourceName, "database_name", "tftest-new-database_name"), + resource.TestCheckResourceAttr(resourceName, "ssl_mode", "none"), + resource.TestMatchResourceAttr(resourceName, "extra_connection_attributes", regexp.MustCompile(`key=value;`)), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"password"}, + }, + }, + }) +} func TestAccDMSEndpoint_Oracle_basic(t *testing.T) { resourceName := "aws_dms_endpoint.test" @@ -1613,6 +1798,121 @@ resource "aws_dms_endpoint" "test" { `, rName) } +func testAccEndpointConfig_mySQL(rName string, engine string) string { + return fmt.Sprintf(` +resource "aws_dms_endpoint" "test" { + endpoint_id = %[1]q + endpoint_type = "source" + engine_name = "%[2]q" + server_name = "tftest" + port = 3306 + username = "tftest" + password = "tftest" + database_name = "tftest" + ssl_mode = "none" + extra_connection_attributes = "" + + tags = { + Name = %[1]q + Update = "to-update" + Remove = "to-remove" + } +} +`, rName, engine) +} + +func testAccEndpointConfig_mySQLSecretID(rName string, engine string) string { + return fmt.Sprintf(` +data "aws_kms_alias" "dms" { + name = "alias/aws/dms" +} + +data "aws_region" "current" {} +data "aws_partition" "current" {} + +resource "aws_secretsmanager_secret" "test" { + name = %[1]q + recovery_window_in_days = 0 +} + +resource "aws_iam_role" "test" { + name = %[1]q + assume_role_policy = < Date: Tue, 17 May 2022 13:56:34 +0100 Subject: [PATCH 03/13] dms: update documentation --- website/docs/r/dms_endpoint.html.markdown | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/docs/r/dms_endpoint.html.markdown b/website/docs/r/dms_endpoint.html.markdown index bfecc65a022b..2c5b5c931844 100644 --- a/website/docs/r/dms_endpoint.html.markdown +++ b/website/docs/r/dms_endpoint.html.markdown @@ -60,7 +60,7 @@ The following arguments are optional: * `port` - (Optional) Port used by the endpoint database. * `s3_settings` - (Optional) Configuration block for S3 settings. See below. * `secrets_manager_access_role_arn` - (Optional) ARN of the IAM role that specifies AWS DMS as the trusted entity and has the required permissions to access the value in SecretsManagerSecret. -* `secrets_manager_arn` - (Optional) Full ARN, partial ARN, or friendly name of the SecretsManagerSecret that contains the endpoint connection details. Supported only for `engine_name` as `oracle` and `postgres`. +* `secrets_manager_arn` - (Optional) Full ARN, partial ARN, or friendly name of the SecretsManagerSecret that contains the endpoint connection details. Supported only for `engine_name` of `aurora`, `mysql`, `oracle` or `postgres`. * `server_name` - (Optional) Host name of the server. * `service_access_role` - (Optional) ARN used by the service access IAM role for dynamodb endpoints. * `ssl_mode` - (Optional, Default: none) SSL mode to use for the connection. Valid values are `none`, `require`, `verify-ca`, `verify-full` From b0f972455188a1bc23c82f62342c31c8c2dc96eb Mon Sep 17 00:00:00 2001 From: Bryce McLeod Date: Tue, 17 May 2022 15:25:42 +0100 Subject: [PATCH 04/13] dms: fix bad quotes in test --- internal/service/dms/endpoint_test.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/internal/service/dms/endpoint_test.go b/internal/service/dms/endpoint_test.go index e07344bbd1e2..11479e61391b 100644 --- a/internal/service/dms/endpoint_test.go +++ b/internal/service/dms/endpoint_test.go @@ -1803,7 +1803,7 @@ func testAccEndpointConfig_mySQL(rName string, engine string) string { resource "aws_dms_endpoint" "test" { endpoint_id = %[1]q endpoint_type = "source" - engine_name = "%[2]q" + engine_name = %[2]q server_name = "tftest" port = 3306 username = "tftest" @@ -1873,7 +1873,7 @@ EOF resource "aws_dms_endpoint" "test" { endpoint_id = %[1]q endpoint_type = "source" - engine_name = "%[2]q" + engine_name = %[2]q secrets_manager_access_role_arn = aws_iam_role.test.arn secrets_manager_arn = aws_secretsmanager_secret.test.id @@ -1895,7 +1895,7 @@ func testAccEndpointConfig_mySQLUpdate(rName string, engine string) string { resource "aws_dms_endpoint" "test" { endpoint_id = %[1]q endpoint_type = "source" - engine_name = "%[2]q" + engine_name = %[2]q server_name = "tftest-new-server_name" port = 3307 username = "tftest-new-username" From e5b00138be45bbe95686ba83df6daa045867a096 Mon Sep 17 00:00:00 2001 From: Bryce McLeod Date: Wed, 18 May 2022 09:18:15 +0100 Subject: [PATCH 05/13] dms: removing reuse of test configuration --- internal/service/dms/endpoint_test.go | 149 ++++++++++++++++++++++---- 1 file changed, 131 insertions(+), 18 deletions(-) diff --git a/internal/service/dms/endpoint_test.go b/internal/service/dms/endpoint_test.go index 11479e61391b..1c61147d4d5c 100644 --- a/internal/service/dms/endpoint_test.go +++ b/internal/service/dms/endpoint_test.go @@ -66,7 +66,7 @@ func TestAccDMSEndpoint_Aurora_basic(t *testing.T) { CheckDestroy: testAccCheckEndpointDestroy, Steps: []resource.TestStep{ { - Config: testAccEndpointConfig_mySQL(rName, "aurora"), + Config: testAccEndpointConfig_aurora(rName), Check: resource.ComposeTestCheckFunc( testAccCheckEndpointExists(resourceName), resource.TestCheckResourceAttrSet(resourceName, "endpoint_arn"), @@ -93,7 +93,7 @@ func TestAccDMSEndpoint_Aurora_secretID(t *testing.T) { CheckDestroy: testAccCheckEndpointDestroy, Steps: []resource.TestStep{ { - Config: testAccEndpointConfig_mySQLSecretID(rName, "aurora"), + Config: testAccEndpointConfig_auroraSecretID(rName), Check: resource.ComposeTestCheckFunc( testAccCheckEndpointExists(resourceName), resource.TestCheckResourceAttrSet(resourceName, "endpoint_arn"), @@ -119,14 +119,14 @@ func TestAccDMSEndpoint_Aurora_update(t *testing.T) { CheckDestroy: testAccCheckEndpointDestroy, Steps: []resource.TestStep{ { - Config: testAccEndpointConfig_mySQL(rName, "aurora"), + Config: testAccEndpointConfig_aurora(rName), Check: resource.ComposeTestCheckFunc( testAccCheckEndpointExists(resourceName), resource.TestCheckResourceAttrSet(resourceName, "endpoint_arn"), ), }, { - Config: testAccEndpointConfig_mySQLUpdate(rName, "aurora"), + Config: testAccEndpointConfig_auroraUpdate(rName), Check: resource.ComposeTestCheckFunc( testAccCheckEndpointExists(resourceName), resource.TestCheckResourceAttr(resourceName, "server_name", "tftest-new-server_name"), @@ -611,7 +611,7 @@ func TestAccDMSEndpoint_MySQL_basic(t *testing.T) { CheckDestroy: testAccCheckEndpointDestroy, Steps: []resource.TestStep{ { - Config: testAccEndpointConfig_mySQL(rName, "mysql"), + Config: testAccEndpointConfig_mySQL(rName), Check: resource.ComposeTestCheckFunc( testAccCheckEndpointExists(resourceName), resource.TestCheckResourceAttrSet(resourceName, "endpoint_arn"), @@ -638,7 +638,7 @@ func TestAccDMSEndpoint_MySQL_secretID(t *testing.T) { CheckDestroy: testAccCheckEndpointDestroy, Steps: []resource.TestStep{ { - Config: testAccEndpointConfig_mySQLSecretID(rName, "mysql"), + Config: testAccEndpointConfig_mySQLSecretID(rName), Check: resource.ComposeTestCheckFunc( testAccCheckEndpointExists(resourceName), resource.TestCheckResourceAttrSet(resourceName, "endpoint_arn"), @@ -664,14 +664,14 @@ func TestAccDMSEndpoint_MySQL_update(t *testing.T) { CheckDestroy: testAccCheckEndpointDestroy, Steps: []resource.TestStep{ { - Config: testAccEndpointConfig_mySQL(rName, "mysql"), + Config: testAccEndpointConfig_mySQL(rName), Check: resource.ComposeTestCheckFunc( testAccCheckEndpointExists(resourceName), resource.TestCheckResourceAttrSet(resourceName, "endpoint_arn"), ), }, { - Config: testAccEndpointConfig_mySQLUpdate(rName, "mysql"), + Config: testAccEndpointConfig_mySQLUpdate(rName), Check: resource.ComposeTestCheckFunc( testAccCheckEndpointExists(resourceName), resource.TestCheckResourceAttr(resourceName, "server_name", "tftest-new-server_name"), @@ -1085,6 +1085,120 @@ resource "aws_dms_endpoint" "test" { `, rName) } +func testAccEndpointConfig_aurora(rName string) string { + return fmt.Sprintf(` +resource "aws_dms_endpoint" "test" { + endpoint_id = %[1]q + endpoint_type = "source" + engine_name = "aurora" + server_name = "tftest" + port = 3306 + username = "tftest" + password = "tftest" + database_name = "tftest" + ssl_mode = "none" + extra_connection_attributes = "" + + tags = { + Name = %[1]q + Update = "to-update" + Remove = "to-remove" + } +} +`, rName) +} + +func testAccEndpointConfig_auroraSecretID(rName string) string { + return fmt.Sprintf(` +data "aws_kms_alias" "dms" { + name = "alias/aws/dms" +} + +data "aws_region" "current" {} +data "aws_partition" "current" {} + +resource "aws_secretsmanager_secret" "test" { + name = %[1]q + recovery_window_in_days = 0 +} + +resource "aws_iam_role" "test" { + name = %[1]q + assume_role_policy = < Date: Wed, 18 May 2022 10:36:47 +0100 Subject: [PATCH 06/13] dms: add secrets attributes to ImportStateVerifyIgnore for Aurora and MySQL secretId acc tests --- internal/service/dms/endpoint_test.go | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/internal/service/dms/endpoint_test.go b/internal/service/dms/endpoint_test.go index 1c61147d4d5c..556632a5f892 100644 --- a/internal/service/dms/endpoint_test.go +++ b/internal/service/dms/endpoint_test.go @@ -97,12 +97,15 @@ func TestAccDMSEndpoint_Aurora_secretID(t *testing.T) { Check: resource.ComposeTestCheckFunc( testAccCheckEndpointExists(resourceName), resource.TestCheckResourceAttrSet(resourceName, "endpoint_arn"), + resource.TestCheckResourceAttrSet(resourceName, "secrets_manager_access_role_arn"), + resource.TestCheckResourceAttrSet(resourceName, "secrets_manager_arn"), ), }, { - ResourceName: resourceName, - ImportState: true, - ImportStateVerify: true, + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"secrets_manager_access_role_arn", "secrets_manager_arn"}, }, }, }) @@ -642,12 +645,15 @@ func TestAccDMSEndpoint_MySQL_secretID(t *testing.T) { Check: resource.ComposeTestCheckFunc( testAccCheckEndpointExists(resourceName), resource.TestCheckResourceAttrSet(resourceName, "endpoint_arn"), + resource.TestCheckResourceAttrSet(resourceName, "secrets_manager_access_role_arn"), + resource.TestCheckResourceAttrSet(resourceName, "secrets_manager_arn"), ), }, { - ResourceName: resourceName, - ImportState: true, - ImportStateVerify: true, + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"secrets_manager_access_role_arn", "secrets_manager_arn"}, }, }, }) @@ -1988,12 +1994,10 @@ resource "aws_dms_endpoint" "test" { endpoint_id = %[1]q endpoint_type = "source" engine_name = "mysql" + secrets_manager_access_role_arn = aws_iam_role.test.arn secrets_manager_arn = aws_secretsmanager_secret.test.id - ssl_mode = "none" - extra_connection_attributes = "" - tags = { Name = %[1]q Update = "to-update" From 10c3a033594162d2c20279df749f3d82103c1f5a Mon Sep 17 00:00:00 2001 From: Bryce McLeod Date: Wed, 18 May 2022 10:53:26 +0100 Subject: [PATCH 07/13] dms: add update implementation for secrets with aurora and mysql aws_dms_endpoint --- internal/service/dms/endpoint.go | 54 ++++++++++++++++----------- internal/service/dms/endpoint_test.go | 18 +++------ 2 files changed, 38 insertions(+), 34 deletions(-) diff --git a/internal/service/dms/endpoint.go b/internal/service/dms/endpoint.go index d625bef70942..9945cd307e3e 100644 --- a/internal/service/dms/endpoint.go +++ b/internal/service/dms/endpoint.go @@ -620,28 +620,6 @@ func resourceEndpointCreate(d *schema.ResourceData, meta interface{}) error { } switch d.Get("engine_name").(string) { - case engineNameAurora: - if _, ok := d.GetOk("secrets_manager_arn"); ok { - request.MySQLSettings = &dms.MySQLSettings{ - SecretsManagerAccessRoleArn: aws.String(d.Get("secrets_manager_access_role_arn").(string)), - SecretsManagerSecretId: aws.String(d.Get("secrets_manager_arn").(string)), - } - } else { - request.MySQLSettings = &dms.MySQLSettings{ - Username: aws.String(d.Get("username").(string)), - Password: aws.String(d.Get("password").(string)), - ServerName: aws.String(d.Get("server_name").(string)), - Port: aws.Int64(int64(d.Get("port").(int))), - DatabaseName: aws.String(d.Get("database_name").(string)), - } - - // Set connection info in top-level namespace as well - request.Username = aws.String(d.Get("username").(string)) - request.Password = aws.String(d.Get("password").(string)) - request.ServerName = aws.String(d.Get("server_name").(string)) - request.Port = aws.Int64(int64(d.Get("port").(int))) - request.DatabaseName = aws.String(d.Get("database_name").(string)) - } case engineNameDynamoDB: request.DynamoDbSettings = &dms.DynamoDbSettings{ ServiceAccessRoleArn: aws.String(d.Get("service_access_role").(string)), @@ -680,6 +658,8 @@ func resourceEndpointCreate(d *schema.ResourceData, meta interface{}) error { request.ServerName = aws.String(d.Get("server_name").(string)) request.Port = aws.Int64(int64(d.Get("port").(int))) request.DatabaseName = aws.String(d.Get("database_name").(string)) + case engineNameAurora: + fallthrough case engineNameMySQL: if _, ok := d.GetOk("secrets_manager_arn"); ok { request.MySQLSettings = &dms.MySQLSettings{ @@ -947,6 +927,36 @@ func resourceEndpointUpdate(d *schema.ResourceData, meta interface{}) error { request.Port = aws.Int64(int64(d.Get("port").(int))) request.DatabaseName = aws.String(d.Get("database_name").(string)) + hasChanges = true + } + case engineNameAurora: + fallthrough + case engineNameMySQL: + if d.HasChanges( + "username", "password", "server_name", "port", "database_name", "secrets_manager_access_role_arn", + "secrets_manager_arn") { + if _, ok := d.GetOk("secrets_manager_arn"); ok { + request.MySQLSettings = &dms.MySQLSettings{ + SecretsManagerAccessRoleArn: aws.String(d.Get("secrets_manager_access_role_arn").(string)), + SecretsManagerSecretId: aws.String(d.Get("secrets_manager_arn").(string)), + } + } else { + request.MySQLSettings = &dms.MySQLSettings{ + Username: aws.String(d.Get("username").(string)), + Password: aws.String(d.Get("password").(string)), + ServerName: aws.String(d.Get("server_name").(string)), + Port: aws.Int64(int64(d.Get("port").(int))), + DatabaseName: aws.String(d.Get("database_name").(string)), + } + request.EngineName = aws.String(d.Get("engine_name").(string)) + + // Update connection info in top-level namespace as well + request.Username = aws.String(d.Get("username").(string)) + request.Password = aws.String(d.Get("password").(string)) + request.ServerName = aws.String(d.Get("server_name").(string)) + request.Port = aws.Int64(int64(d.Get("port").(int))) + request.DatabaseName = aws.String(d.Get("database_name").(string)) + } hasChanges = true } case engineNameOracle: diff --git a/internal/service/dms/endpoint_test.go b/internal/service/dms/endpoint_test.go index 556632a5f892..c9e20f2590ab 100644 --- a/internal/service/dms/endpoint_test.go +++ b/internal/service/dms/endpoint_test.go @@ -97,15 +97,12 @@ func TestAccDMSEndpoint_Aurora_secretID(t *testing.T) { Check: resource.ComposeTestCheckFunc( testAccCheckEndpointExists(resourceName), resource.TestCheckResourceAttrSet(resourceName, "endpoint_arn"), - resource.TestCheckResourceAttrSet(resourceName, "secrets_manager_access_role_arn"), - resource.TestCheckResourceAttrSet(resourceName, "secrets_manager_arn"), ), }, { - ResourceName: resourceName, - ImportState: true, - ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"secrets_manager_access_role_arn", "secrets_manager_arn"}, + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, }, }, }) @@ -645,15 +642,12 @@ func TestAccDMSEndpoint_MySQL_secretID(t *testing.T) { Check: resource.ComposeTestCheckFunc( testAccCheckEndpointExists(resourceName), resource.TestCheckResourceAttrSet(resourceName, "endpoint_arn"), - resource.TestCheckResourceAttrSet(resourceName, "secrets_manager_access_role_arn"), - resource.TestCheckResourceAttrSet(resourceName, "secrets_manager_arn"), ), }, { - ResourceName: resourceName, - ImportState: true, - ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"secrets_manager_access_role_arn", "secrets_manager_arn"}, + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, }, }, }) From 095eec5e1e5f2606c0a68b60b7d7ce1a8bf2e77e Mon Sep 17 00:00:00 2001 From: Bryce McLeod Date: Wed, 18 May 2022 11:06:38 +0100 Subject: [PATCH 08/13] dms: remove extra attributes in test --- internal/service/dms/endpoint_test.go | 3 --- 1 file changed, 3 deletions(-) diff --git a/internal/service/dms/endpoint_test.go b/internal/service/dms/endpoint_test.go index c9e20f2590ab..c1115088e51f 100644 --- a/internal/service/dms/endpoint_test.go +++ b/internal/service/dms/endpoint_test.go @@ -1164,9 +1164,6 @@ resource "aws_dms_endpoint" "test" { secrets_manager_access_role_arn = aws_iam_role.test.arn secrets_manager_arn = aws_secretsmanager_secret.test.id - ssl_mode = "none" - extra_connection_attributes = "" - tags = { Name = %[1]q Update = "to-update" From f7cb55df1a65a2a25bc4f186e01fad7bc087e406 Mon Sep 17 00:00:00 2001 From: Bryce McLeod Date: Wed, 18 May 2022 11:09:41 +0100 Subject: [PATCH 09/13] dms: setstate for aurora and mysql endpoints --- internal/service/dms/endpoint.go | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/internal/service/dms/endpoint.go b/internal/service/dms/endpoint.go index 9945cd307e3e..f42940718b9c 100644 --- a/internal/service/dms/endpoint.go +++ b/internal/service/dms/endpoint.go @@ -1169,6 +1169,22 @@ func resourceEndpointSetState(d *schema.ResourceData, endpoint *dms.Endpoint) er if err := d.Set("mongodb_settings", flattenMongoDBSettings(endpoint.MongoDbSettings)); err != nil { return fmt.Errorf("Error setting mongodb_settings for DMS: %s", err) } + case engineNameAurora: + fallthrough + case engineNameMySQL: + if endpoint.MySQLSettings != nil { + d.Set("username", endpoint.MySQLSettings.Username) + d.Set("server_name", endpoint.MySQLSettings.ServerName) + d.Set("port", endpoint.MySQLSettings.Port) + d.Set("database_name", endpoint.MySQLSettings.DatabaseName) + d.Set("secrets_manager_access_role_arn", endpoint.MySQLSettings.SecretsManagerAccessRoleArn) + d.Set("secrets_manager_arn", endpoint.MySQLSettings.SecretsManagerSecretId) + } else { + d.Set("username", endpoint.Username) + d.Set("server_name", endpoint.ServerName) + d.Set("port", endpoint.Port) + d.Set("database_name", endpoint.DatabaseName) + } case engineNameOracle: if endpoint.OracleSettings != nil { d.Set("username", endpoint.OracleSettings.Username) From 01cb3dc6c9d308339a1c3b163c162d753a08cfd3 Mon Sep 17 00:00:00 2001 From: Bryce McLeod Date: Wed, 18 May 2022 11:37:09 +0100 Subject: [PATCH 10/13] whitespace --- internal/service/dms/endpoint_test.go | 1 - 1 file changed, 1 deletion(-) diff --git a/internal/service/dms/endpoint_test.go b/internal/service/dms/endpoint_test.go index c1115088e51f..fe90d9fec246 100644 --- a/internal/service/dms/endpoint_test.go +++ b/internal/service/dms/endpoint_test.go @@ -1985,7 +1985,6 @@ resource "aws_dms_endpoint" "test" { endpoint_id = %[1]q endpoint_type = "source" engine_name = "mysql" - secrets_manager_access_role_arn = aws_iam_role.test.arn secrets_manager_arn = aws_secretsmanager_secret.test.id From 895c37a642516eeda3afc08618eabe07fe6da1bf Mon Sep 17 00:00:00 2001 From: Bryce McLeod Date: Wed, 18 May 2022 11:42:52 +0100 Subject: [PATCH 11/13] changelog --- .changelog/24846.txt | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 .changelog/24846.txt diff --git a/.changelog/24846.txt b/.changelog/24846.txt new file mode 100644 index 000000000000..be94a6c98030 --- /dev/null +++ b/.changelog/24846.txt @@ -0,0 +1,3 @@ +```release-note:enhancement +resource/aws_dms_endpoint: Allow configuring secrets manager secret when engine is `aurora` or `mysql` +``` From 617c2974f6b0a789e6a587b6ea5d65557e20a51f Mon Sep 17 00:00:00 2001 From: Bryce McLeod Date: Fri, 20 May 2022 09:55:07 +0100 Subject: [PATCH 12/13] dms: allow use of secrets manager with mariadb --- .changelog/24846.txt | 2 +- internal/service/dms/endpoint.go | 6 + internal/service/dms/endpoint_test.go | 205 ++++++++++++++++++++++ website/docs/r/dms_endpoint.html.markdown | 2 +- 4 files changed, 213 insertions(+), 2 deletions(-) diff --git a/.changelog/24846.txt b/.changelog/24846.txt index be94a6c98030..3adf745cd6ce 100644 --- a/.changelog/24846.txt +++ b/.changelog/24846.txt @@ -1,3 +1,3 @@ ```release-note:enhancement -resource/aws_dms_endpoint: Allow configuring secrets manager secret when engine is `aurora` or `mysql` +resource/aws_dms_endpoint: Allow configuring secrets manager secret when engine is `aurora`, `mariadb` or `mysql` ``` diff --git a/internal/service/dms/endpoint.go b/internal/service/dms/endpoint.go index f42940718b9c..fbc773707537 100644 --- a/internal/service/dms/endpoint.go +++ b/internal/service/dms/endpoint.go @@ -660,6 +660,8 @@ func resourceEndpointCreate(d *schema.ResourceData, meta interface{}) error { request.DatabaseName = aws.String(d.Get("database_name").(string)) case engineNameAurora: fallthrough + case engineNameMariadb: + fallthrough case engineNameMySQL: if _, ok := d.GetOk("secrets_manager_arn"); ok { request.MySQLSettings = &dms.MySQLSettings{ @@ -931,6 +933,8 @@ func resourceEndpointUpdate(d *schema.ResourceData, meta interface{}) error { } case engineNameAurora: fallthrough + case engineNameMariadb: + fallthrough case engineNameMySQL: if d.HasChanges( "username", "password", "server_name", "port", "database_name", "secrets_manager_access_role_arn", @@ -1171,6 +1175,8 @@ func resourceEndpointSetState(d *schema.ResourceData, endpoint *dms.Endpoint) er } case engineNameAurora: fallthrough + case engineNameMariadb: + fallthrough case engineNameMySQL: if endpoint.MySQLSettings != nil { d.Set("username", endpoint.MySQLSettings.Username) diff --git a/internal/service/dms/endpoint_test.go b/internal/service/dms/endpoint_test.go index fe90d9fec246..71967a2396e7 100644 --- a/internal/service/dms/endpoint_test.go +++ b/internal/service/dms/endpoint_test.go @@ -600,6 +600,100 @@ func TestAccDMSEndpoint_MongoDB_update(t *testing.T) { }, }) } + +func TestAccDMSEndpoint_MariaDB_basic(t *testing.T) { + resourceName := "aws_dms_endpoint.test" + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { acctest.PreCheck(t) }, + ErrorCheck: acctest.ErrorCheck(t, dms.EndpointsID), + ProviderFactories: acctest.ProviderFactories, + CheckDestroy: testAccCheckEndpointDestroy, + Steps: []resource.TestStep{ + { + Config: testAccEndpointConfig_mariaDB(rName), + Check: resource.ComposeTestCheckFunc( + testAccCheckEndpointExists(resourceName), + resource.TestCheckResourceAttrSet(resourceName, "endpoint_arn"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"password"}, + }, + }, + }) +} + +func TestAccDMSEndpoint_MariaDB_secretID(t *testing.T) { + resourceName := "aws_dms_endpoint.test" + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { acctest.PreCheck(t) }, + ErrorCheck: acctest.ErrorCheck(t, dms.EndpointsID), + ProviderFactories: acctest.ProviderFactories, + CheckDestroy: testAccCheckEndpointDestroy, + Steps: []resource.TestStep{ + { + Config: testAccEndpointConfig_mariaDBSecretID(rName), + Check: resource.ComposeTestCheckFunc( + testAccCheckEndpointExists(resourceName), + resource.TestCheckResourceAttrSet(resourceName, "endpoint_arn"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func TestAccDMSEndpoint_MariaDB_update(t *testing.T) { + resourceName := "aws_dms_endpoint.test" + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { acctest.PreCheck(t) }, + ErrorCheck: acctest.ErrorCheck(t, dms.EndpointsID), + ProviderFactories: acctest.ProviderFactories, + CheckDestroy: testAccCheckEndpointDestroy, + Steps: []resource.TestStep{ + { + Config: testAccEndpointConfig_mariaDB(rName), + Check: resource.ComposeTestCheckFunc( + testAccCheckEndpointExists(resourceName), + resource.TestCheckResourceAttrSet(resourceName, "endpoint_arn"), + ), + }, + { + Config: testAccEndpointConfig_mariaDBUpdate(rName), + Check: resource.ComposeTestCheckFunc( + testAccCheckEndpointExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "server_name", "tftest-new-server_name"), + resource.TestCheckResourceAttr(resourceName, "port", "3307"), + resource.TestCheckResourceAttr(resourceName, "username", "tftest-new-username"), + resource.TestCheckResourceAttr(resourceName, "password", "tftest-new-password"), + resource.TestCheckResourceAttr(resourceName, "database_name", "tftest-new-database_name"), + resource.TestCheckResourceAttr(resourceName, "ssl_mode", "none"), + resource.TestMatchResourceAttr(resourceName, "extra_connection_attributes", regexp.MustCompile(`key=value;`)), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"password"}, + }, + }, + }) +} + func TestAccDMSEndpoint_MySQL_basic(t *testing.T) { resourceName := "aws_dms_endpoint.test" rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) @@ -1909,6 +2003,117 @@ resource "aws_dms_endpoint" "test" { `, rName) } +func testAccEndpointConfig_mariaDB(rName string) string { + return fmt.Sprintf(` +resource "aws_dms_endpoint" "test" { + endpoint_id = %[1]q + endpoint_type = "source" + engine_name = "mariadb" + server_name = "tftest" + port = 3306 + username = "tftest" + password = "tftest" + database_name = "tftest" + ssl_mode = "none" + extra_connection_attributes = "" + + tags = { + Name = %[1]q + Update = "to-update" + Remove = "to-remove" + } +} +`, rName) +} + +func testAccEndpointConfig_mariaDBSecretID(rName string) string { + return fmt.Sprintf(` +data "aws_kms_alias" "dms" { + name = "alias/aws/dms" +} + +data "aws_region" "current" {} +data "aws_partition" "current" {} + +resource "aws_secretsmanager_secret" "test" { + name = %[1]q + recovery_window_in_days = 0 +} + +resource "aws_iam_role" "test" { + name = %[1]q + assume_role_policy = < Date: Wed, 1 Jun 2022 11:30:44 -0400 Subject: [PATCH 13/13] Tweak CHANGELOG entry. --- .changelog/24846.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.changelog/24846.txt b/.changelog/24846.txt index 3adf745cd6ce..8e399c6db49b 100644 --- a/.changelog/24846.txt +++ b/.changelog/24846.txt @@ -1,3 +1,3 @@ ```release-note:enhancement -resource/aws_dms_endpoint: Allow configuring secrets manager secret when engine is `aurora`, `mariadb` or `mysql` +resource/aws_dms_endpoint: Add ability to use AWS Secrets Manager with the `aurora`, `mariadb` and `mysql` engines ```