From 6a6c996cae8d404acb1761558ad32795045bc1ca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lucas=20T=C3=A9treault?= Date: Tue, 17 Nov 2020 09:50:48 -0800 Subject: [PATCH 01/10] Updated Amazon MQ functionality - Add support for RabbitMQ - Add support for LDAP Authentication - Add support for EBS storage type - Make security groups optional since it will use the default one if omitted --- aws/resource_aws_mq_broker_test.go | 200 +++++++++++++++++++++++++++++ 1 file changed, 200 insertions(+) diff --git a/aws/resource_aws_mq_broker_test.go b/aws/resource_aws_mq_broker_test.go index 1a605c5c87fc..74bfacf1512a 100644 --- a/aws/resource_aws_mq_broker_test.go +++ b/aws/resource_aws_mq_broker_test.go @@ -1007,6 +1007,142 @@ func TestAccAWSMqBroker_rabbitmq(t *testing.T) { }) } +func TestAccAWSMqBroker_clusterRabbitMQ(t *testing.T) { + var broker mq.DescribeBrokerResponse + rName := fmt.Sprintf("tf-acc-test-%s", acctest.RandString(5)) + resourceName := "aws_mq_broker.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t); testAccPreCheckAWSMq(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckAwsMqBrokerDestroy, + Steps: []resource.TestStep{ + { + Config: testAccRabbitMqClusterBrokerConfig(rName), + Check: resource.ComposeTestCheckFunc( + testAccCheckAwsMqBrokerExists(resourceName, &broker), + resource.TestCheckResourceAttr(resourceName, "auto_minor_version_upgrade", "false"), + resource.TestCheckResourceAttr(resourceName, "broker_name", rName), + resource.TestCheckResourceAttr(resourceName, "deployment_mode", "CLUSTER_MULTI_AZ"), + resource.TestCheckResourceAttr(resourceName, "encryption_options.#", "1"), + resource.TestCheckResourceAttr(resourceName, "encryption_options.0.use_aws_owned_key", "true"), + resource.TestCheckResourceAttr(resourceName, "engine_type", "RabbitMQ"), + resource.TestCheckResourceAttr(resourceName, "engine_version", "3.8.6"), + resource.TestCheckResourceAttr(resourceName, "host_instance_type", "mq.m5.large"), + resource.TestCheckResourceAttr(resourceName, "maintenance_window_start_time.#", "1"), + resource.TestCheckResourceAttrSet(resourceName, "maintenance_window_start_time.0.day_of_week"), + resource.TestCheckResourceAttrSet(resourceName, "maintenance_window_start_time.0.time_of_day"), + resource.TestCheckResourceAttr(resourceName, "logs.#", "1"), + resource.TestCheckResourceAttr(resourceName, "logs.0.general", "false"), + resource.TestCheckResourceAttr(resourceName, "maintenance_window_start_time.0.time_zone", "UTC"), + resource.TestCheckResourceAttr(resourceName, "publicly_accessible", "false"), + resource.TestCheckResourceAttr(resourceName, "security_groups.#", "1"), + resource.TestCheckResourceAttr(resourceName, "subnet_ids.#", "4"), + resource.TestCheckResourceAttr(resourceName, "user.#", "1"), + resource.TestCheckTypeSetElemNestedAttrs(resourceName, "user.*", map[string]string{ + "console_access": "false", + "groups.#": "0", + "username": "Test", + "password": "TestTest1234", + }), + testAccMatchResourceAttrRegionalARN(resourceName, "arn", "mq", regexp.MustCompile(`broker:+.`)), + resource.TestCheckResourceAttr(resourceName, "instances.#", "1"), + resource.TestMatchResourceAttr(resourceName, "instances.0.console_url", + regexp.MustCompile(`^https://[a-f0-9-]+\.mq.[a-z0-9-]+.amazonaws.com$`)), + resource.TestCheckResourceAttr(resourceName, "instances.0.endpoints.#", "1"), + resource.TestMatchResourceAttr(resourceName, "instances.0.endpoints.0", regexp.MustCompile(`^amqps://[a-z0-9-\.]+:5671$`)), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"apply_immediately", "user"}, + }, + }, + }) +} + +func TestAccAWSMqBroker_ldap(t *testing.T) { + var broker mq.DescribeBrokerResponse + rName := fmt.Sprintf("tf-acc-test-%s", acctest.RandString(5)) + resourceName := "aws_mq_broker.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t); testAccPreCheckAWSMq(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckAwsMqBrokerDestroy, + Steps: []resource.TestStep{ + { + Config: testAccMqBrokerConfig_ldap(rName), + Check: resource.ComposeTestCheckFunc( + testAccCheckAwsMqBrokerExists(resourceName, &broker), + resource.TestCheckResourceAttr(resourceName, "auto_minor_version_upgrade", "false"), + resource.TestCheckResourceAttr(resourceName, "broker_name", rName), + resource.TestCheckResourceAttr(resourceName, "configuration.#", "1"), + resource.TestMatchResourceAttr(resourceName, "configuration.0.id", regexp.MustCompile(`^c-[a-z0-9-]+$`)), + resource.TestMatchResourceAttr(resourceName, "configuration.0.revision", regexp.MustCompile(`^[0-9]+$`)), + resource.TestCheckResourceAttr(resourceName, "deployment_mode", "SINGLE_INSTANCE"), + resource.TestCheckResourceAttr(resourceName, "encryption_options.#", "1"), + resource.TestCheckResourceAttr(resourceName, "encryption_options.0.use_aws_owned_key", "true"), + resource.TestCheckResourceAttr(resourceName, "engine_type", "ActiveMQ"), + resource.TestCheckResourceAttr(resourceName, "engine_version", "5.15.0"), + resource.TestCheckResourceAttr(resourceName, "host_instance_type", "mq.t2.micro"), + resource.TestCheckResourceAttr(resourceName, "maintenance_window_start_time.#", "1"), + resource.TestCheckResourceAttrSet(resourceName, "maintenance_window_start_time.0.day_of_week"), + resource.TestCheckResourceAttrSet(resourceName, "maintenance_window_start_time.0.time_of_day"), + resource.TestCheckResourceAttr(resourceName, "logs.#", "1"), + resource.TestCheckResourceAttr(resourceName, "logs.0.general", "true"), + resource.TestCheckResourceAttr(resourceName, "logs.0.audit", "false"), + resource.TestCheckResourceAttr(resourceName, "maintenance_window_start_time.0.time_zone", "UTC"), + resource.TestCheckResourceAttr(resourceName, "publicly_accessible", "false"), + resource.TestCheckResourceAttr(resourceName, "security_groups.#", "1"), + resource.TestCheckResourceAttr(resourceName, "subnet_ids.#", "1"), + resource.TestCheckResourceAttr(resourceName, "user.#", "1"), + resource.TestCheckTypeSetElemNestedAttrs(resourceName, "user.*", map[string]string{ + "console_access": "false", + "groups.#": "0", + "username": "Test", + "password": "TestTest1234", + }), + testAccMatchResourceAttrRegionalARN(resourceName, "arn", "mq", regexp.MustCompile(`broker:+.`)), + resource.TestCheckResourceAttr(resourceName, "instances.#", "1"), + resource.TestMatchResourceAttr(resourceName, "instances.0.console_url", + regexp.MustCompile(`^https://[a-f0-9-]+\.mq.[a-z0-9-]+.amazonaws.com:8162$`)), + resource.TestMatchResourceAttr(resourceName, "instances.0.ip_address", + regexp.MustCompile(`^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$`)), + resource.TestCheckResourceAttr(resourceName, "instances.0.endpoints.#", "5"), + resource.TestMatchResourceAttr(resourceName, "instances.0.endpoints.0", regexp.MustCompile(`^ssl://[a-z0-9-\.]+:61617$`)), + resource.TestMatchResourceAttr(resourceName, "instances.0.endpoints.1", regexp.MustCompile(`^amqp\+ssl://[a-z0-9-\.]+:5671$`)), + resource.TestMatchResourceAttr(resourceName, "instances.0.endpoints.2", regexp.MustCompile(`^stomp\+ssl://[a-z0-9-\.]+:61614$`)), + resource.TestMatchResourceAttr(resourceName, "instances.0.endpoints.3", regexp.MustCompile(`^mqtt\+ssl://[a-z0-9-\.]+:8883$`)), + resource.TestMatchResourceAttr(resourceName, "instances.0.endpoints.4", regexp.MustCompile(`^wss://[a-z0-9-\.]+:61619$`)), + resource.TestCheckResourceAttr(resourceName, "authentication_strategy", "ldap"), + resource.TestCheckResourceAttr(resourceName, "ldap_server_metadata.0.hosts.#", "2"), + resource.TestCheckResourceAttr(resourceName, "ldap_server_metadata.0.hosts.0", "my.ldap.server-1.com"), + resource.TestCheckResourceAttr(resourceName, "ldap_server_metadata.0.hosts.1", "my.ldap.server-2.com"), + resource.TestCheckResourceAttr(resourceName, "ldap_server_metadata.0.role_base", "role.base"), + resource.TestCheckResourceAttr(resourceName, "ldap_server_metadata.0.role_name", "role.name"), + resource.TestCheckResourceAttr(resourceName, "ldap_server_metadata.0.role_search_matching", "role.search.matching"), + resource.TestCheckResourceAttr(resourceName, "ldap_server_metadata.0.role_search_subtree", "true"), + resource.TestCheckResourceAttr(resourceName, "ldap_server_metadata.0.service_account_password", "supersecret"), + resource.TestCheckResourceAttr(resourceName, "ldap_server_metadata.0.service_account_username", "admin"), + resource.TestCheckResourceAttr(resourceName, "ldap_server_metadata.0.user_base", "user.base"), + resource.TestCheckResourceAttr(resourceName, "ldap_server_metadata.0.user_role_name", "user.role.name"), + resource.TestCheckResourceAttr(resourceName, "ldap_server_metadata.0.user_search_matching", "user.search.matching"), + resource.TestCheckResourceAttr(resourceName, "ldap_server_metadata.0.user_search_subtree", "true"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"apply_immediately", "user", "ldap_server_metadata"}, + }, + }, + }) +} + func testAccCheckAwsMqBrokerDestroy(s *terraform.State) error { conn := testAccProvider.Meta().(*AWSClient).mqconn @@ -1617,3 +1753,67 @@ resource "aws_mq_broker" "test" { } `, rName) } + +func testAccRabbitMqClusterBrokerConfig(rName string) string { + return fmt.Sprintf(` +resource "aws_security_group" "test" { + name = %[1]q +} + +resource "aws_mq_broker" "test" { + broker_name = %[1]q + engine_type = "RabbitMQ" + engine_version = "3.8.6" + host_instance_type = "mq.m5.large" + security_groups = [aws_security_group.test.id] + storage_type = "ebs" + deployment_mode = "CLUSTER_MULTI_AZ" + + user { + username = "Test" + password = "TestTest1234" + } +} +`, rName) +} + +func testAccMqBrokerConfig_ldap(rName string) string { + return fmt.Sprintf(` +resource "aws_security_group" "test" { + name = %[1]q +} + +resource "aws_mq_broker" "test" { + broker_name = %[1]q + engine_type = "ActiveMQ" + engine_version = "5.15.0" + host_instance_type = "mq.t2.micro" + security_groups = [aws_security_group.test.id] + + logs { + general = true + } + + user { + username = "Test" + password = "TestTest1234" + } + + authentication_strategy = "ldap" + + ldap_server_metadata { + hosts = ["my.ldap.server-1.com", "my.ldap.server-2.com"] + role_base = "role.base" + role_name = "role.name" + role_search_matching = "role.search.matching" + role_search_subtree = true + service_account_password = "supersecret" + service_account_username = "admin" + user_base = "user.base" + user_role_name = "user.role.name" + user_search_matching = "user.search.matching" + user_search_subtree = true + } +} +`, rName) +} From fb7342d8b8b0cb95248121c241ca37a61e1576e7 Mon Sep 17 00:00:00 2001 From: Dirk Avery Date: Wed, 10 Mar 2021 16:08:51 -0500 Subject: [PATCH 02/10] tests/mq_broker: Lint, precheck --- aws/resource_aws_mq_broker_test.go | 34 ++++++++++++++++++------------ 1 file changed, 21 insertions(+), 13 deletions(-) diff --git a/aws/resource_aws_mq_broker_test.go b/aws/resource_aws_mq_broker_test.go index 74bfacf1512a..3f434fafb7c3 100644 --- a/aws/resource_aws_mq_broker_test.go +++ b/aws/resource_aws_mq_broker_test.go @@ -1009,11 +1009,15 @@ func TestAccAWSMqBroker_rabbitmq(t *testing.T) { func TestAccAWSMqBroker_clusterRabbitMQ(t *testing.T) { var broker mq.DescribeBrokerResponse - rName := fmt.Sprintf("tf-acc-test-%s", acctest.RandString(5)) + rName := acctest.RandomWithPrefix("tf-acc-test") resourceName := "aws_mq_broker.test" resource.ParallelTest(t, resource.TestCase{ - PreCheck: func() { testAccPreCheck(t); testAccPreCheckAWSMq(t) }, + PreCheck: func() { + testAccPreCheck(t) + testAccPartitionHasServicePreCheck(mq.EndpointsID, t) + testAccPreCheckAWSMq(t) + }, Providers: testAccProviders, CheckDestroy: testAccCheckAwsMqBrokerDestroy, Steps: []resource.TestStep{ @@ -1065,11 +1069,15 @@ func TestAccAWSMqBroker_clusterRabbitMQ(t *testing.T) { func TestAccAWSMqBroker_ldap(t *testing.T) { var broker mq.DescribeBrokerResponse - rName := fmt.Sprintf("tf-acc-test-%s", acctest.RandString(5)) + rName := acctest.RandomWithPrefix("tf-acc-test") resourceName := "aws_mq_broker.test" resource.ParallelTest(t, resource.TestCase{ - PreCheck: func() { testAccPreCheck(t); testAccPreCheckAWSMq(t) }, + PreCheck: func() { + testAccPreCheck(t) + testAccPartitionHasServicePreCheck(mq.EndpointsID, t) + testAccPreCheckAWSMq(t) + }, Providers: testAccProviders, CheckDestroy: testAccCheckAwsMqBrokerDestroy, Steps: []resource.TestStep{ @@ -1802,17 +1810,17 @@ resource "aws_mq_broker" "test" { authentication_strategy = "ldap" ldap_server_metadata { - hosts = ["my.ldap.server-1.com", "my.ldap.server-2.com"] - role_base = "role.base" - role_name = "role.name" - role_search_matching = "role.search.matching" - role_search_subtree = true + hosts = ["my.ldap.server-1.com", "my.ldap.server-2.com"] + role_base = "role.base" + role_name = "role.name" + role_search_matching = "role.search.matching" + role_search_subtree = true service_account_password = "supersecret" service_account_username = "admin" - user_base = "user.base" - user_role_name = "user.role.name" - user_search_matching = "user.search.matching" - user_search_subtree = true + user_base = "user.base" + user_role_name = "user.role.name" + user_search_matching = "user.search.matching" + user_search_subtree = true } } `, rName) From 1c58ebfcbd036cdaba6bccc6d8dc6a05e805dac1 Mon Sep 17 00:00:00 2001 From: Dirk Avery Date: Wed, 10 Mar 2021 17:25:51 -0500 Subject: [PATCH 03/10] r/mq_broker: Rework ldap --- aws/resource_aws_mq_broker.go | 16 +++---- aws/resource_aws_mq_broker_test.go | 72 ++++++++++-------------------- 2 files changed, 31 insertions(+), 57 deletions(-) diff --git a/aws/resource_aws_mq_broker.go b/aws/resource_aws_mq_broker.go index 9ba3f17dc688..ff1b4416ac5a 100644 --- a/aws/resource_aws_mq_broker.go +++ b/aws/resource_aws_mq_broker.go @@ -348,7 +348,7 @@ func resourceAwsMqBrokerCreate(d *schema.ResourceData, meta interface{}) error { input.Logs = expandMqLogs(v.([]interface{})) } if v, ok := d.GetOk("ldap_server_metadata"); ok && len(v.([]interface{})) > 0 && v.([]interface{})[0] != nil { - input.LdapServerMetadata = expandMQLDAPServerMetadata(v.([]interface{})[0].(map[string]interface{})) + input.LdapServerMetadata = expandMQLDAPServerMetadata(v.([]interface{})) } if v, ok := d.GetOk("maintenance_window_start_time"); ok { input.MaintenanceWindowStartTime = expandMqWeeklyStartTime(v.([]interface{})) @@ -498,7 +498,7 @@ func resourceAwsMqBrokerUpdate(d *schema.ResourceData, meta interface{}) error { } if v, ok := d.GetOk("ldap_server_metadata"); ok && len(v.([]interface{})) > 0 && v.([]interface{})[0] != nil { - input.LdapServerMetadata = expandMQLDAPServerMetadata(v.([]interface{})[0].(map[string]interface{})) + input.LdapServerMetadata = expandMQLDAPServerMetadata(v.([]interface{})) } if _, err := conn.UpdateBroker(input); err != nil { @@ -947,7 +947,7 @@ func expandMqLogs(l []interface{}) *mq.Logs { return logs } -func flattenMQLDAPServerMetadata(apiObject *mq.LdapServerMetadataOutput) map[string]interface{} { +func flattenMQLDAPServerMetadata(apiObject *mq.LdapServerMetadataOutput) []interface{} { if apiObject == nil { return nil } @@ -985,16 +985,14 @@ func flattenMQLDAPServerMetadata(apiObject *mq.LdapServerMetadataOutput) map[str tfMap["user_search_subtree"] = aws.BoolValue(v) } - return tfMap + return []interface{}{tfMap} } -func expandMQLDAPServerMetadata(tfMap map[string]interface{}) *mq.LdapServerMetadataInput { - if tfMap == nil { - return nil - } - +func expandMQLDAPServerMetadata(tfList []interface{}) *mq.LdapServerMetadataInput { apiObject := &mq.LdapServerMetadataInput{} + tfMap := tfList[0].(map[string]interface{}) + if v, ok := tfMap["hosts"]; ok && len(v.([]interface{})) > 0 { apiObject.Hosts = expandStringList(v.([]interface{})) } diff --git a/aws/resource_aws_mq_broker_test.go b/aws/resource_aws_mq_broker_test.go index 3f434fafb7c3..c723f66913a1 100644 --- a/aws/resource_aws_mq_broker_test.go +++ b/aws/resource_aws_mq_broker_test.go @@ -1082,49 +1082,11 @@ func TestAccAWSMqBroker_ldap(t *testing.T) { CheckDestroy: testAccCheckAwsMqBrokerDestroy, Steps: []resource.TestStep{ { - Config: testAccMqBrokerConfig_ldap(rName), + Config: testAccMqBrokerConfig_ldap(rName, "anyusername"), Check: resource.ComposeTestCheckFunc( testAccCheckAwsMqBrokerExists(resourceName, &broker), resource.TestCheckResourceAttr(resourceName, "auto_minor_version_upgrade", "false"), resource.TestCheckResourceAttr(resourceName, "broker_name", rName), - resource.TestCheckResourceAttr(resourceName, "configuration.#", "1"), - resource.TestMatchResourceAttr(resourceName, "configuration.0.id", regexp.MustCompile(`^c-[a-z0-9-]+$`)), - resource.TestMatchResourceAttr(resourceName, "configuration.0.revision", regexp.MustCompile(`^[0-9]+$`)), - resource.TestCheckResourceAttr(resourceName, "deployment_mode", "SINGLE_INSTANCE"), - resource.TestCheckResourceAttr(resourceName, "encryption_options.#", "1"), - resource.TestCheckResourceAttr(resourceName, "encryption_options.0.use_aws_owned_key", "true"), - resource.TestCheckResourceAttr(resourceName, "engine_type", "ActiveMQ"), - resource.TestCheckResourceAttr(resourceName, "engine_version", "5.15.0"), - resource.TestCheckResourceAttr(resourceName, "host_instance_type", "mq.t2.micro"), - resource.TestCheckResourceAttr(resourceName, "maintenance_window_start_time.#", "1"), - resource.TestCheckResourceAttrSet(resourceName, "maintenance_window_start_time.0.day_of_week"), - resource.TestCheckResourceAttrSet(resourceName, "maintenance_window_start_time.0.time_of_day"), - resource.TestCheckResourceAttr(resourceName, "logs.#", "1"), - resource.TestCheckResourceAttr(resourceName, "logs.0.general", "true"), - resource.TestCheckResourceAttr(resourceName, "logs.0.audit", "false"), - resource.TestCheckResourceAttr(resourceName, "maintenance_window_start_time.0.time_zone", "UTC"), - resource.TestCheckResourceAttr(resourceName, "publicly_accessible", "false"), - resource.TestCheckResourceAttr(resourceName, "security_groups.#", "1"), - resource.TestCheckResourceAttr(resourceName, "subnet_ids.#", "1"), - resource.TestCheckResourceAttr(resourceName, "user.#", "1"), - resource.TestCheckTypeSetElemNestedAttrs(resourceName, "user.*", map[string]string{ - "console_access": "false", - "groups.#": "0", - "username": "Test", - "password": "TestTest1234", - }), - testAccMatchResourceAttrRegionalARN(resourceName, "arn", "mq", regexp.MustCompile(`broker:+.`)), - resource.TestCheckResourceAttr(resourceName, "instances.#", "1"), - resource.TestMatchResourceAttr(resourceName, "instances.0.console_url", - regexp.MustCompile(`^https://[a-f0-9-]+\.mq.[a-z0-9-]+.amazonaws.com:8162$`)), - resource.TestMatchResourceAttr(resourceName, "instances.0.ip_address", - regexp.MustCompile(`^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$`)), - resource.TestCheckResourceAttr(resourceName, "instances.0.endpoints.#", "5"), - resource.TestMatchResourceAttr(resourceName, "instances.0.endpoints.0", regexp.MustCompile(`^ssl://[a-z0-9-\.]+:61617$`)), - resource.TestMatchResourceAttr(resourceName, "instances.0.endpoints.1", regexp.MustCompile(`^amqp\+ssl://[a-z0-9-\.]+:5671$`)), - resource.TestMatchResourceAttr(resourceName, "instances.0.endpoints.2", regexp.MustCompile(`^stomp\+ssl://[a-z0-9-\.]+:61614$`)), - resource.TestMatchResourceAttr(resourceName, "instances.0.endpoints.3", regexp.MustCompile(`^mqtt\+ssl://[a-z0-9-\.]+:8883$`)), - resource.TestMatchResourceAttr(resourceName, "instances.0.endpoints.4", regexp.MustCompile(`^wss://[a-z0-9-\.]+:61619$`)), resource.TestCheckResourceAttr(resourceName, "authentication_strategy", "ldap"), resource.TestCheckResourceAttr(resourceName, "ldap_server_metadata.0.hosts.#", "2"), resource.TestCheckResourceAttr(resourceName, "ldap_server_metadata.0.hosts.0", "my.ldap.server-1.com"), @@ -1133,8 +1095,7 @@ func TestAccAWSMqBroker_ldap(t *testing.T) { resource.TestCheckResourceAttr(resourceName, "ldap_server_metadata.0.role_name", "role.name"), resource.TestCheckResourceAttr(resourceName, "ldap_server_metadata.0.role_search_matching", "role.search.matching"), resource.TestCheckResourceAttr(resourceName, "ldap_server_metadata.0.role_search_subtree", "true"), - resource.TestCheckResourceAttr(resourceName, "ldap_server_metadata.0.service_account_password", "supersecret"), - resource.TestCheckResourceAttr(resourceName, "ldap_server_metadata.0.service_account_username", "admin"), + resource.TestCheckResourceAttr(resourceName, "ldap_server_metadata.0.service_account_username", "anyusername"), resource.TestCheckResourceAttr(resourceName, "ldap_server_metadata.0.user_base", "user.base"), resource.TestCheckResourceAttr(resourceName, "ldap_server_metadata.0.user_role_name", "user.role.name"), resource.TestCheckResourceAttr(resourceName, "ldap_server_metadata.0.user_search_matching", "user.search.matching"), @@ -1142,10 +1103,25 @@ func TestAccAWSMqBroker_ldap(t *testing.T) { ), }, { - ResourceName: resourceName, - ImportState: true, - ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"apply_immediately", "user", "ldap_server_metadata"}, + Config: testAccMqBrokerConfig_ldap(rName, "totoro"), + Check: resource.ComposeTestCheckFunc( + testAccCheckAwsMqBrokerExists(resourceName, &broker), + resource.TestCheckResourceAttr(resourceName, "auto_minor_version_upgrade", "false"), + resource.TestCheckResourceAttr(resourceName, "broker_name", rName), + resource.TestCheckResourceAttr(resourceName, "authentication_strategy", "ldap"), + resource.TestCheckResourceAttr(resourceName, "ldap_server_metadata.0.hosts.#", "2"), + resource.TestCheckResourceAttr(resourceName, "ldap_server_metadata.0.hosts.0", "my.ldap.server-1.com"), + resource.TestCheckResourceAttr(resourceName, "ldap_server_metadata.0.hosts.1", "my.ldap.server-2.com"), + resource.TestCheckResourceAttr(resourceName, "ldap_server_metadata.0.role_base", "role.base"), + resource.TestCheckResourceAttr(resourceName, "ldap_server_metadata.0.role_name", "role.name"), + resource.TestCheckResourceAttr(resourceName, "ldap_server_metadata.0.role_search_matching", "role.search.matching"), + resource.TestCheckResourceAttr(resourceName, "ldap_server_metadata.0.role_search_subtree", "true"), + resource.TestCheckResourceAttr(resourceName, "ldap_server_metadata.0.service_account_username", "totoro"), + resource.TestCheckResourceAttr(resourceName, "ldap_server_metadata.0.user_base", "user.base"), + resource.TestCheckResourceAttr(resourceName, "ldap_server_metadata.0.user_role_name", "user.role.name"), + resource.TestCheckResourceAttr(resourceName, "ldap_server_metadata.0.user_search_matching", "user.search.matching"), + resource.TestCheckResourceAttr(resourceName, "ldap_server_metadata.0.user_search_subtree", "true"), + ), }, }, }) @@ -1785,7 +1761,7 @@ resource "aws_mq_broker" "test" { `, rName) } -func testAccMqBrokerConfig_ldap(rName string) string { +func testAccMqBrokerConfig_ldap(rName, ldapUsername string) string { return fmt.Sprintf(` resource "aws_security_group" "test" { name = %[1]q @@ -1816,12 +1792,12 @@ resource "aws_mq_broker" "test" { role_search_matching = "role.search.matching" role_search_subtree = true service_account_password = "supersecret" - service_account_username = "admin" + service_account_username = %[2]q user_base = "user.base" user_role_name = "user.role.name" user_search_matching = "user.search.matching" user_search_subtree = true } } -`, rName) +`, rName, ldapUsername) } From 19ea2e37514cef42a8784b86a54ccea09812d927 Mon Sep 17 00:00:00 2001 From: Dirk Avery Date: Wed, 10 Mar 2021 17:28:52 -0500 Subject: [PATCH 04/10] r/mq_broker: Add zero check --- aws/resource_aws_mq_broker.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/aws/resource_aws_mq_broker.go b/aws/resource_aws_mq_broker.go index ff1b4416ac5a..e36da75e5d0f 100644 --- a/aws/resource_aws_mq_broker.go +++ b/aws/resource_aws_mq_broker.go @@ -989,6 +989,10 @@ func flattenMQLDAPServerMetadata(apiObject *mq.LdapServerMetadataOutput) []inter } func expandMQLDAPServerMetadata(tfList []interface{}) *mq.LdapServerMetadataInput { + if len(tfList) == 0 || tfList[0] == nil { + return nil + } + apiObject := &mq.LdapServerMetadataInput{} tfMap := tfList[0].(map[string]interface{}) From 2ce3b0847e82ffa9f17d978b68007fcd6c3748e3 Mon Sep 17 00:00:00 2001 From: Dirk Avery Date: Wed, 10 Mar 2021 21:27:27 -0500 Subject: [PATCH 05/10] r/mq_broker: Cleanup LDAP metadata --- aws/internal/service/mq/waiter/waiter.go | 5 +++-- aws/resource_aws_mq_broker.go | 11 +++++++---- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/aws/internal/service/mq/waiter/waiter.go b/aws/internal/service/mq/waiter/waiter.go index 3bc226dc58df..d55ab76c36b5 100644 --- a/aws/internal/service/mq/waiter/waiter.go +++ b/aws/internal/service/mq/waiter/waiter.go @@ -35,9 +35,10 @@ func BrokerCreated(conn *mq.MQ, id string) (*mq.DescribeBrokerResponse, error) { func BrokerDeleted(conn *mq.MQ, id string) (*mq.DescribeBrokerResponse, error) { stateConf := resource.StateChangeConf{ Pending: []string{ - mq.BrokerStateRunning, - mq.BrokerStateRebootInProgress, + mq.BrokerStateCreationFailed, mq.BrokerStateDeletionInProgress, + mq.BrokerStateRebootInProgress, + mq.BrokerStateRunning, }, Target: []string{}, Timeout: BrokerDeleteTimeout, diff --git a/aws/resource_aws_mq_broker.go b/aws/resource_aws_mq_broker.go index e36da75e5d0f..ab63df1bd416 100644 --- a/aws/resource_aws_mq_broker.go +++ b/aws/resource_aws_mq_broker.go @@ -146,6 +146,7 @@ func resourceAwsMqBroker() *schema.Resource { "ldap_server_metadata": { Type: schema.TypeList, Optional: true, + Computed: true, MaxItems: 1, Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ @@ -327,7 +328,6 @@ func resourceAwsMqBrokerCreate(d *schema.ResourceData, meta interface{}) error { AutoMinorVersionUpgrade: aws.Bool(d.Get("auto_minor_version_upgrade").(bool)), BrokerName: aws.String(name), CreatorRequestId: aws.String(requestId), - EncryptionOptions: expandMqEncryptionOptions(d.Get("encryption_options").([]interface{})), EngineType: aws.String(d.Get("engine_type").(string)), EngineVersion: aws.String(d.Get("engine_version").(string)), HostInstanceType: aws.String(d.Get("host_instance_type").(string)), @@ -338,19 +338,22 @@ func resourceAwsMqBrokerCreate(d *schema.ResourceData, meta interface{}) error { if v, ok := d.GetOk("authentication_strategy"); ok { input.AuthenticationStrategy = aws.String(v.(string)) } - if v, ok := d.GetOk("configuration"); ok { + if v, ok := d.GetOk("configuration"); ok && len(v.([]interface{})) > 0 && v.([]interface{})[0] != nil { input.Configuration = expandMqConfigurationId(v.([]interface{})) } if v, ok := d.GetOk("deployment_mode"); ok { input.DeploymentMode = aws.String(v.(string)) } - if v, ok := d.GetOk("logs"); ok && len(v.([]interface{})) > 0 { + if v, ok := d.GetOk("encryption_options"); ok && len(v.([]interface{})) > 0 && v.([]interface{})[0] != nil { + input.EncryptionOptions = expandMqEncryptionOptions(d.Get("encryption_options").([]interface{})) + } + if v, ok := d.GetOk("logs"); ok && len(v.([]interface{})) > 0 && v.([]interface{})[0] != nil { input.Logs = expandMqLogs(v.([]interface{})) } if v, ok := d.GetOk("ldap_server_metadata"); ok && len(v.([]interface{})) > 0 && v.([]interface{})[0] != nil { input.LdapServerMetadata = expandMQLDAPServerMetadata(v.([]interface{})) } - if v, ok := d.GetOk("maintenance_window_start_time"); ok { + if v, ok := d.GetOk("maintenance_window_start_time"); ok && len(v.([]interface{})) > 0 && v.([]interface{})[0] != nil { input.MaintenanceWindowStartTime = expandMqWeeklyStartTime(v.([]interface{})) } if v, ok := d.GetOk("security_groups"); ok && v.(*schema.Set).Len() > 0 { From e16d4a7aa41f295d985febfe8fe4b3fc06c20328 Mon Sep 17 00:00:00 2001 From: Dirk Avery Date: Wed, 10 Mar 2021 21:47:33 -0500 Subject: [PATCH 06/10] r/mq_broker: Mark password sensitive --- aws/resource_aws_mq_broker.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/aws/resource_aws_mq_broker.go b/aws/resource_aws_mq_broker.go index ab63df1bd416..4b86ff637397 100644 --- a/aws/resource_aws_mq_broker.go +++ b/aws/resource_aws_mq_broker.go @@ -146,7 +146,6 @@ func resourceAwsMqBroker() *schema.Resource { "ldap_server_metadata": { Type: schema.TypeList, Optional: true, - Computed: true, MaxItems: 1, Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ @@ -172,8 +171,9 @@ func resourceAwsMqBroker() *schema.Resource { Optional: true, }, "service_account_password": { - Type: schema.TypeString, - Optional: true, + Type: schema.TypeString, + Optional: true, + Sensitive: true, }, "service_account_username": { Type: schema.TypeString, From 37c009ce39d5b7cbccdc909f4b2ebd51fadc06e6 Mon Sep 17 00:00:00 2001 From: Dirk Avery Date: Wed, 10 Mar 2021 22:11:13 -0500 Subject: [PATCH 07/10] r/mq_broker: Avoid password diffs since not returned by API --- aws/resource_aws_mq_broker.go | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/aws/resource_aws_mq_broker.go b/aws/resource_aws_mq_broker.go index 4b86ff637397..fbeb0969a280 100644 --- a/aws/resource_aws_mq_broker.go +++ b/aws/resource_aws_mq_broker.go @@ -439,8 +439,12 @@ func resourceAwsMqBrokerRead(d *schema.ResourceData, meta interface{}) error { } if output.LdapServerMetadata != nil { - if err := d.Set("ldap_server_metadata", flattenMQLDAPServerMetadata(output.LdapServerMetadata)); err != nil { - return fmt.Errorf("error setting lda_server_metadata: %w", err) + password := "" + if v, ok := d.GetOk("ldap_server_metadata.0.service_account_password"); ok { + password = v.(string) + } + if err := d.Set("ldap_server_metadata", flattenMQLDAPServerMetadata(output.LdapServerMetadata, password)); err != nil { + return fmt.Errorf("error setting ldap_server_metadata: %w", err) } } else { d.Set("ldap_server_metadata", nil) @@ -950,7 +954,7 @@ func expandMqLogs(l []interface{}) *mq.Logs { return logs } -func flattenMQLDAPServerMetadata(apiObject *mq.LdapServerMetadataOutput) []interface{} { +func flattenMQLDAPServerMetadata(apiObject *mq.LdapServerMetadataOutput, password string) []interface{} { if apiObject == nil { return nil } @@ -972,6 +976,9 @@ func flattenMQLDAPServerMetadata(apiObject *mq.LdapServerMetadataOutput) []inter if v := apiObject.RoleSearchSubtree; v != nil { tfMap["role_search_subtree"] = aws.BoolValue(v) } + if password != "" { + tfMap["service_account_password"] = password + } if v := apiObject.ServiceAccountUsername; v != nil { tfMap["service_account_username"] = aws.StringValue(v) } From e4d64690d78c46c03a1f820d8a00454fda24c750 Mon Sep 17 00:00:00 2001 From: Dirk Avery Date: Wed, 10 Mar 2021 22:37:23 -0500 Subject: [PATCH 08/10] r/mq_broker: LDAP update requires reboot --- aws/resource_aws_mq_broker.go | 1 + aws/resource_aws_mq_broker_test.go | 1 + 2 files changed, 2 insertions(+) diff --git a/aws/resource_aws_mq_broker.go b/aws/resource_aws_mq_broker.go index fbeb0969a280..8ec95580bde3 100644 --- a/aws/resource_aws_mq_broker.go +++ b/aws/resource_aws_mq_broker.go @@ -511,6 +511,7 @@ func resourceAwsMqBrokerUpdate(d *schema.ResourceData, meta interface{}) error { if _, err := conn.UpdateBroker(input); err != nil { return fmt.Errorf("error updating MQ Broker (%s) LDAP server metadata: %w", d.Id(), err) } + requiresReboot = true } if d.HasChange("security_groups") { diff --git a/aws/resource_aws_mq_broker_test.go b/aws/resource_aws_mq_broker_test.go index c723f66913a1..3e28d798edf9 100644 --- a/aws/resource_aws_mq_broker_test.go +++ b/aws/resource_aws_mq_broker_test.go @@ -1768,6 +1768,7 @@ resource "aws_security_group" "test" { } resource "aws_mq_broker" "test" { + apply_immediately = true broker_name = %[1]q engine_type = "ActiveMQ" engine_version = "5.15.0" From 866ffdee4c6c32883b0d6b3a8a5fc9c6fb34a605 Mon Sep 17 00:00:00 2001 From: Dirk Avery Date: Thu, 11 Mar 2021 10:27:47 -0500 Subject: [PATCH 09/10] r/mq_broker: LDAP fixes --- aws/resource_aws_mq_broker.go | 17 +------------- aws/resource_aws_mq_broker_test.go | 36 ++++++------------------------ 2 files changed, 8 insertions(+), 45 deletions(-) diff --git a/aws/resource_aws_mq_broker.go b/aws/resource_aws_mq_broker.go index 8ec95580bde3..b43e1f9128b1 100644 --- a/aws/resource_aws_mq_broker.go +++ b/aws/resource_aws_mq_broker.go @@ -146,6 +146,7 @@ func resourceAwsMqBroker() *schema.Resource { "ldap_server_metadata": { Type: schema.TypeList, Optional: true, + ForceNew: true, MaxItems: 1, Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ @@ -498,22 +499,6 @@ func resourceAwsMqBrokerUpdate(d *schema.ResourceData, meta interface{}) error { requiresReboot := false - if d.HasChange("ldap_server_metadata") { - input := &mq.UpdateBrokerRequest{ - BrokerId: aws.String(d.Id()), - LdapServerMetadata: nil, - } - - if v, ok := d.GetOk("ldap_server_metadata"); ok && len(v.([]interface{})) > 0 && v.([]interface{})[0] != nil { - input.LdapServerMetadata = expandMQLDAPServerMetadata(v.([]interface{})) - } - - if _, err := conn.UpdateBroker(input); err != nil { - return fmt.Errorf("error updating MQ Broker (%s) LDAP server metadata: %w", d.Id(), err) - } - requiresReboot = true - } - if d.HasChange("security_groups") { _, err := conn.UpdateBroker(&mq.UpdateBrokerRequest{ BrokerId: aws.String(d.Id()), diff --git a/aws/resource_aws_mq_broker_test.go b/aws/resource_aws_mq_broker_test.go index 3e28d798edf9..d0fa5141d236 100644 --- a/aws/resource_aws_mq_broker_test.go +++ b/aws/resource_aws_mq_broker_test.go @@ -1102,27 +1102,6 @@ func TestAccAWSMqBroker_ldap(t *testing.T) { resource.TestCheckResourceAttr(resourceName, "ldap_server_metadata.0.user_search_subtree", "true"), ), }, - { - Config: testAccMqBrokerConfig_ldap(rName, "totoro"), - Check: resource.ComposeTestCheckFunc( - testAccCheckAwsMqBrokerExists(resourceName, &broker), - resource.TestCheckResourceAttr(resourceName, "auto_minor_version_upgrade", "false"), - resource.TestCheckResourceAttr(resourceName, "broker_name", rName), - resource.TestCheckResourceAttr(resourceName, "authentication_strategy", "ldap"), - resource.TestCheckResourceAttr(resourceName, "ldap_server_metadata.0.hosts.#", "2"), - resource.TestCheckResourceAttr(resourceName, "ldap_server_metadata.0.hosts.0", "my.ldap.server-1.com"), - resource.TestCheckResourceAttr(resourceName, "ldap_server_metadata.0.hosts.1", "my.ldap.server-2.com"), - resource.TestCheckResourceAttr(resourceName, "ldap_server_metadata.0.role_base", "role.base"), - resource.TestCheckResourceAttr(resourceName, "ldap_server_metadata.0.role_name", "role.name"), - resource.TestCheckResourceAttr(resourceName, "ldap_server_metadata.0.role_search_matching", "role.search.matching"), - resource.TestCheckResourceAttr(resourceName, "ldap_server_metadata.0.role_search_subtree", "true"), - resource.TestCheckResourceAttr(resourceName, "ldap_server_metadata.0.service_account_username", "totoro"), - resource.TestCheckResourceAttr(resourceName, "ldap_server_metadata.0.user_base", "user.base"), - resource.TestCheckResourceAttr(resourceName, "ldap_server_metadata.0.user_role_name", "user.role.name"), - resource.TestCheckResourceAttr(resourceName, "ldap_server_metadata.0.user_search_matching", "user.search.matching"), - resource.TestCheckResourceAttr(resourceName, "ldap_server_metadata.0.user_search_subtree", "true"), - ), - }, }, }) } @@ -1768,12 +1747,13 @@ resource "aws_security_group" "test" { } resource "aws_mq_broker" "test" { - apply_immediately = true - broker_name = %[1]q - engine_type = "ActiveMQ" - engine_version = "5.15.0" - host_instance_type = "mq.t2.micro" - security_groups = [aws_security_group.test.id] + apply_immediately = true + authentication_strategy = "ldap" + broker_name = %[1]q + engine_type = "ActiveMQ" + engine_version = "5.15.0" + host_instance_type = "mq.t2.micro" + security_groups = [aws_security_group.test.id] logs { general = true @@ -1784,8 +1764,6 @@ resource "aws_mq_broker" "test" { password = "TestTest1234" } - authentication_strategy = "ldap" - ldap_server_metadata { hosts = ["my.ldap.server-1.com", "my.ldap.server-2.com"] role_base = "role.base" From 180dedf22e521a404c681d0201b9cae5dfb1dd2f Mon Sep 17 00:00:00 2001 From: Dirk Avery Date: Thu, 11 Mar 2021 10:29:39 -0500 Subject: [PATCH 10/10] docs/r/mq_broker: Note on LDAP --- website/docs/r/mq_broker.html.markdown | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/docs/r/mq_broker.html.markdown b/website/docs/r/mq_broker.html.markdown index 40cff4e00ca6..7da2cbb79088 100644 --- a/website/docs/r/mq_broker.html.markdown +++ b/website/docs/r/mq_broker.html.markdown @@ -89,7 +89,7 @@ The following arguments are optional: * `configuration` - (Optional) Configuration block for broker configuration. Applies to `engine_type` of `ActiveMQ` only. Detailed below. * `deployment_mode` - (Optional) Deployment mode of the broker. Valid values are `SINGLE_INSTANCE`, `ACTIVE_STANDBY_MULTI_AZ`, and `CLUSTER_MULTI_AZ`. Default is `SINGLE_INSTANCE`. * `encryption_options` - (Optional) Configuration block containing encryption options. Detailed below. -* `ldap_server_metadata` - (Optional) Configuration block for the LDAP server used to authenticate and authorize connections to the broker. Not supported for `engine_type` `RabbitMQ`. Detailed below. +* `ldap_server_metadata` - (Optional) Configuration block for the LDAP server used to authenticate and authorize connections to the broker. Not supported for `engine_type` `RabbitMQ`. Detailed below. (Currently, AWS may not process changes to LDAP server metadata.) * `logs` - (Optional) Configuration block for the logging configuration of the broker. Detailed below. * `maintenance_window_start_time` - (Optional) Configuration block for the maintenance window start time. Detailed below. * `publicly_accessible` - (Optional) Whether to enable connections from applications outside of the VPC that hosts the broker's subnets.