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

Updated Amazon MQ functionality #16261

Merged
merged 10 commits into from
Mar 11, 2021
5 changes: 3 additions & 2 deletions aws/internal/service/mq/waiter/waiter.go
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
54 changes: 26 additions & 28 deletions aws/resource_aws_mq_broker.go
Original file line number Diff line number Diff line change
Expand Up @@ -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{
Expand All @@ -171,8 +172,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,
Expand Down Expand Up @@ -327,7 +329,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)),
Expand All @@ -338,19 +339,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{})[0].(map[string]interface{}))
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 {
Expand Down Expand Up @@ -436,8 +440,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)
Expand Down Expand Up @@ -491,21 +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{})[0].(map[string]interface{}))
}

if _, err := conn.UpdateBroker(input); err != nil {
return fmt.Errorf("error updating MQ Broker (%s) LDAP server metadata: %w", d.Id(), err)
}
}

if d.HasChange("security_groups") {
_, err := conn.UpdateBroker(&mq.UpdateBrokerRequest{
BrokerId: aws.String(d.Id()),
Expand Down Expand Up @@ -947,7 +940,7 @@ func expandMqLogs(l []interface{}) *mq.Logs {
return logs
}

func flattenMQLDAPServerMetadata(apiObject *mq.LdapServerMetadataOutput) map[string]interface{} {
func flattenMQLDAPServerMetadata(apiObject *mq.LdapServerMetadataOutput, password string) []interface{} {
if apiObject == nil {
return nil
}
Expand All @@ -969,6 +962,9 @@ func flattenMQLDAPServerMetadata(apiObject *mq.LdapServerMetadataOutput) map[str
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)
}
Expand All @@ -985,16 +981,18 @@ 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 {
func expandMQLDAPServerMetadata(tfList []interface{}) *mq.LdapServerMetadataInput {
if len(tfList) == 0 || tfList[0] == nil {
return nil
}

apiObject := &mq.LdapServerMetadataInput{}

tfMap := tfList[0].(map[string]interface{})

if v, ok := tfMap["hosts"]; ok && len(v.([]interface{})) > 0 {
apiObject.Hosts = expandStringList(v.([]interface{}))
}
Expand Down
163 changes: 163 additions & 0 deletions aws/resource_aws_mq_broker_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1007,6 +1007,105 @@ func TestAccAWSMqBroker_rabbitmq(t *testing.T) {
})
}

func TestAccAWSMqBroker_clusterRabbitMQ(t *testing.T) {
var broker mq.DescribeBrokerResponse
rName := acctest.RandomWithPrefix("tf-acc-test")
resourceName := "aws_mq_broker.test"

resource.ParallelTest(t, resource.TestCase{
PreCheck: func() {
testAccPreCheck(t)
testAccPartitionHasServicePreCheck(mq.EndpointsID, 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 := acctest.RandomWithPrefix("tf-acc-test")
resourceName := "aws_mq_broker.test"

resource.ParallelTest(t, resource.TestCase{
PreCheck: func() {
testAccPreCheck(t)
testAccPartitionHasServicePreCheck(mq.EndpointsID, t)
testAccPreCheckAWSMq(t)
},
Providers: testAccProviders,
CheckDestroy: testAccCheckAwsMqBrokerDestroy,
Steps: []resource.TestStep{
{
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, "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", "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"),
resource.TestCheckResourceAttr(resourceName, "ldap_server_metadata.0.user_search_subtree", "true"),
),
},
},
})
}

func testAccCheckAwsMqBrokerDestroy(s *terraform.State) error {
conn := testAccProvider.Meta().(*AWSClient).mqconn

Expand Down Expand Up @@ -1617,3 +1716,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, ldapUsername string) string {
return fmt.Sprintf(`
resource "aws_security_group" "test" {
name = %[1]q
}

resource "aws_mq_broker" "test" {
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
}

user {
username = "Test"
password = "TestTest1234"
}

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 = %[2]q
user_base = "user.base"
user_role_name = "user.role.name"
user_search_matching = "user.search.matching"
user_search_subtree = true
}
}
`, rName, ldapUsername)
}
2 changes: 1 addition & 1 deletion website/docs/r/mq_broker.html.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down