

# RabbitMQ tutorials
<a name="rabbitmq-on-amazon-mq"></a>

The following tutorials show how you can configure and use RabbitMQ on Amazon MQ. To learn more about working with supported client libraries in a variety of programming languages such as Node.js, Python, .NET, and more, see [RabbitMQ Tutorials](https://www.rabbitmq.com/getstarted.html) in the *RabbitMQ Getting Started Guide*.

**Topics**
+ [Editing broker preferences](amazon-mq-rabbitmq-editing-broker-preferences.md)
+ [Using Python Pika with Amazon MQ for RabbitMQ](amazon-mq-rabbitmq-pika.md)
+ [Resolving RabbitMQ paused queue synchronization](rabbitmq-queue-sync.md)
+ [Reducing the number of connections and channels](reducing-connections-and-channels.md)
+ [Step 2: Connect a JVM-based application to your broker](#rabbitmq-connect-jvm-application)
+ [Connect your Amazon MQ for RabbitMQ broker to Lambda](#rabbitmq-connect-to-lambda)
+ [Using OAuth 2.0 authentication and authorization for Amazon MQ for RabbitMQ](oauth-tutorial.md)
+ [Using IAM authentication and authorization for Amazon MQ for RabbitMQ](rabbitmq-iam-tutorial.md)
+ [Using LDAP authentication and authorization for Amazon MQ for RabbitMQ](rabbitmq-ldap-tutorial.md)
+ [Using HTTP authentication and authorization for Amazon MQ for RabbitMQ](rabbitmq-http-tutorial.md)
+ [Using SSL certificate authentication for Amazon MQ for RabbitMQ](rabbitmq-ssl-tutorial.md)
+ [Using mTLS for AMQP and management endpoints](rabbitmq-mtls-tutorial.md)
+ [Connecting your JMS application](rabbitmq-tutorial-jms.md)

# Editing broker preferences
<a name="amazon-mq-rabbitmq-editing-broker-preferences"></a>

You can edit your broker preferences, such as enabling or disabling CloudWatch logs using the AWS Management Console.

## Edit RabbitMQ broker options
<a name="rabbitmq-edit-current-configuration-console"></a>

1. Sign in to the [Amazon MQ console](https://console.aws.amazon.com/amazon-mq/).

1. From the broker list, select your broker (for example, **MyBroker**) and then choose **Edit**.

1. On the **Edit *MyBroker*** page, in the **Specifications** section, select a **Broker engine version** or a **Broker Instance type**.

   

1. In the **CloudWatch Logs** section, click the toggle button to enable or disable general logs. No other steps are required.
**Note**  
For RabbitMQ brokers, Amazon MQ automatically uses a Service-Linked Role (SLR) to publish general logs to CloudWatch. For more information, see [Using service-linked roles for Amazon MQ](using-service-linked-roles.md) 
Amazon MQ does not support audit logging for RabbitMQ brokers.

1. In the **Maintenance** section, configure your broker's maintenance schedule:

   To upgrade the broker to new versions as AWS releases them, choose **Enable automatic minor version upgrades**. Automatic upgrades occur during the *maintenance window* defined by the day of the week, the time of day (in 24-hour format), and the time zone (UTC by default).

1. Choose **Schedule modifications**.
**Note**  
If you choose only **Enable automatic minor version upgrades**, the button changes to **Save** because no broker reboot is necessary.

   Your preferences are applied to your broker at the specified time.

# Using Python Pika with Amazon MQ for RabbitMQ
<a name="amazon-mq-rabbitmq-pika"></a>

 The following tutorial shows how you can set up a [Python Pika](https://github.com/pika/pika) client with TLS configured to connect to an Amazon MQ for RabbitMQ broker. Pika is a Python implementation of the AMQP 0-9-1 protocol for RabbitMQ. This tutorial guides you through installing Pika, declaring a queue, setting up a publisher to send messages to the broker's default exchange, and setting up a consumer to receive messages from the queue. 

**Topics**
+ [Prerequisites](#amazon-mq-rabbitmq-pika-prerequisites)
+ [Permissions](#amazon-mq-rabbitmq-pika-permissions)
+ [Step one: Create a basic Python Pika client](#amazon-mq-rabbitmq-pika-basic-client)
+ [Step two: Create a publisher and send a message](#amazon-mq-rabbitmq-pika-publisher-basic-publish)
+ [Step three: Create a consumer and receive a message](#amazon-mq-rabbitmq-pika-consumer-basic-get)
+ [Step four: (Optional) Set up an event loop and consume messages](#amazon-mq-rabbitmq-pika-consumer-basic-consume)
+ [What's next?](#amazon-mq-rabbitmq-pika-whats-next)

## Prerequisites
<a name="amazon-mq-rabbitmq-pika-prerequisites"></a>

 To complete the steps in this tutorial, you need the following prerequisites: 
+ An Amazon MQ for RabbitMQ broker. For more information, see [Creating an Amazon MQ for RabbitMQ broker](getting-started-rabbitmq.md#create-rabbitmq-broker).
+ [Python 3](https://www.python.org/downloads/) installed for your operating system.
+ [Pika](https://pika.readthedocs.io/en/stable/) installed using Python `pip`. To install Pika, open a new terminal window and run the following.

  ```
  $ python3 -m pip install pika
  ```

## Permissions
<a name="amazon-mq-rabbitmq-pika-permissions"></a>

For this tutorial, you need at least one Amazon MQ for RabbitMQ broker user with permission to write to, and read from, a vhost. The following table describes the necessary minimum permissions as regular expression (regexp) patterns.


| Tags | Configure regexp | Write regexp | Read regexp | 
| --- | --- | --- | --- | 
| none |  | .\$1 | .\$1 | 

 The user permissions listed provide only read and write permissions to the user, without granting access to the management plugin to perform administrative operations on the broker. You can further restrict permissions by providing regexp patterns that limit the user's access to specified queues. For example, if you change the read regexp pattern to `^[hello world].*`, the user will only have permission to read from queues that start with `hello world`. 

For more information about creating RabbitMQ users and managing user tags and permissions, see [Amazon MQ for RabbitMQ broker users](rabbitmq-simple-auth-broker-users.md#rabbitmq-basic-elements-user).

## Step one: Create a basic Python Pika client
<a name="amazon-mq-rabbitmq-pika-basic-client"></a>

To create a Python Pika client base class that defines a constructor and provides the SSL context necessary for TLS configuration when interacting with an Amazon MQ for RabbitMQ broker, do the following.

1.  Open a new terminal window, create a new directory for your project, and navigate to the directory. 

   ```
   $ mkdir pika-tutorial
   $ cd pika-tutorial
   ```

1.  Create a new file, `basicClient.py`, that contains the following Python code. 

   ```
   import ssl
   import pika
   
   class BasicPikaClient:
   
       def __init__(self, rabbitmq_broker_id, rabbitmq_user, rabbitmq_password, region):
   
           # SSL Context for TLS configuration of Amazon MQ for RabbitMQ
           ssl_context = ssl.SSLContext(ssl.PROTOCOL_TLSv1_2)
           ssl_context.set_ciphers('ECDHE+AESGCM:!ECDSA')
   
           url = f"amqps://{rabbitmq_user}:{rabbitmq_password}@{rabbitmq_broker_id}.mq.{region}.amazonaws.com:5671"
           parameters = pika.URLParameters(url)
           parameters.ssl_options = pika.SSLOptions(context=ssl_context)
   
           self.connection = pika.BlockingConnection(parameters)
           self.channel = self.connection.channel()
   ```

 You can now define additional classes for your publisher and consumer that inherit from `BasicPikaClient`. 

## Step two: Create a publisher and send a message
<a name="amazon-mq-rabbitmq-pika-publisher-basic-publish"></a>

 To create a publisher that declares a queue, and sends a single message, do the following. 

1.  Copy the contents of the following code sample, and save locally as `publisher.py` in the same directory you created in the previous step. 

   ```
   from basicClient import BasicPikaClient
   
   class BasicMessageSender(BasicPikaClient):
   
       def declare_queue(self, queue_name):
           print(f"Trying to declare queue({queue_name})...")
           self.channel.queue_declare(queue=queue_name)
   
       def send_message(self, exchange, routing_key, body):
           channel = self.connection.channel()
           channel.basic_publish(exchange=exchange,
                                 routing_key=routing_key,
                                 body=body)
           print(f"Sent message. Exchange: {exchange}, Routing Key: {routing_key}, Body: {body}")
   
       def close(self):
           self.channel.close()
           self.connection.close()
   
   if __name__ == "__main__":
   
       # Initialize Basic Message Sender which creates a connection
       # and channel for sending messages.
       basic_message_sender = BasicMessageSender(
           "<broker-id>",
           "<username>",
           "<password>",
           "<region>"
       )
   
       # Declare a queue
       basic_message_sender.declare_queue("hello world queue")
   
       # Send a message to the queue.
       basic_message_sender.send_message(exchange="", routing_key="hello world queue", body=b'Hello World!')
   
       # Close connections.
       basic_message_sender.close()
   ```

    The `BasicMessageSender` class inherits from `BasicPikaClient` and implements additional methods for delaring a queue, sending a message to the queue, and closing connections. The code sample routes a message to the default exchange, with a routing key equal to the name of the queue. 

1.  Under `if __name__ == "__main__":`, replace the parameters passed to the `BasicMessageSender` constructor statement with the following information. 
   +  **`<broker-id>`** – The unique ID that Amazon MQ generates for the broker. You can parse the ID from your broker ARN. For example, given the following ARN, `arn:aws:mq:us-east-2:123456789012:broker:MyBroker:b-1234a5b6-78cd-901e-2fgh-3i45j6k178l9`, the broker ID would be `b-1234a5b6-78cd-901e-2fgh-3i45j6k178l9`. 
   +  **`<username>`** – The username for a broker user with sufficient permissions to write messages to the broker. 
   +  **`<password>`** – The password for a broker user with sufficient permissions to write messages to the broker. 
   +  **`<region>`** – The AWS region in which you created your Amazon MQ for RabbitMQ broker. For example, `us-west-2`. 

1.  Run the following command in the same directory you created `publisher.py`. 

   ```
   $ python3 publisher.py
   ```

   If the code runs successfully, you will see the following output in your terminal window.

   ```
   Trying to declare queue(hello world queue)...
   Sent message. Exchange: , Routing Key: hello world queue, Body: b'Hello World!'
   ```

## Step three: Create a consumer and receive a message
<a name="amazon-mq-rabbitmq-pika-consumer-basic-get"></a>

 To create a consumer that receives a single message from the queue, do the following. 

1.  Copy the contents of the following code sample, and save locally as `consumer.py` in the same directory. 

   ```
   from basicClient import BasicPikaClient
   
   class BasicMessageReceiver(BasicPikaClient):
   
       def get_message(self, queue):
           method_frame, header_frame, body = self.channel.basic_get(queue)
           if method_frame:
               print(method_frame, header_frame, body)
               self.channel.basic_ack(method_frame.delivery_tag)
               return method_frame, header_frame, body
           else:
               print('No message returned')
   
       def close(self):
           self.channel.close()
           self.connection.close()
   
   
   if __name__ == "__main__":
   
       # Create Basic Message Receiver which creates a connection
       # and channel for consuming messages.
       basic_message_receiver = BasicMessageReceiver(
           "<broker-id>",
           "<username>",
           "<password>",
           "<region>"
       )
   
       # Consume the message that was sent.
       basic_message_receiver.get_message("hello world queue")
   
       # Close connections.
       basic_message_receiver.close()
   ```

    Similar to the publisher you created in the previous step, `BasicMessageReceiver` inherits from `BasicPikaClient` and implements additional methods for recieving a single message, and closing connections.

1.  Under the `if __name__ == "__main__":` statement, replace the parameters passed to the `BasicMessageReceiver` constructor with your information. 

1.  Run the following command in your project directory. 

   ```
   $ python3 consumer.py
   ```

   If the code runs successfully, you will see the message body, and headers including the routing key, displayed in your terminal window.

   ```
   <Basic.GetOk(['delivery_tag=1', 'exchange=', 'message_count=0', 'redelivered=False', 'routing_key=hello world queue'])> <BasicProperties> b'Hello World!'
   ```

## Step four: (Optional) Set up an event loop and consume messages
<a name="amazon-mq-rabbitmq-pika-consumer-basic-consume"></a>

 To consume multiple messages from a queue, use Pika's [https://pika.readthedocs.io/en/stable/modules/channel.html#pika.channel.Channel.basic_consume](https://pika.readthedocs.io/en/stable/modules/channel.html#pika.channel.Channel.basic_consume) method and a callback function as shown in the following 

1.  In `consumer.py`, add the following method definition to the `BasicMessageReceiver` class. 

   ```
   def consume_messages(self, queue):
       def callback(ch, method, properties, body):
           print(" [x] Received %r" % body)
   
       self.channel.basic_consume(queue=queue, on_message_callback=callback, auto_ack=True)
   
       print(' [*] Waiting for messages. To exit press CTRL+C')
       self.channel.start_consuming()
   ```

1.  In `consumer.py`, under `if __name__ == "__main__":`, invoke the `consume_messages` method you defined in the previous step. 

   ```
   if __name__ == "__main__":
   
       # Create Basic Message Receiver which creates a connection and channel for consuming messages.
       basic_message_receiver = BasicMessageReceiver(
           "<broker-id>",
           "<username>",
           "<password>",
           "<region>"
       )
   
       # Consume the message that was sent.
       # basic_message_receiver.get_message("hello world queue")
   
       # Consume multiple messages in an event loop.
       basic_message_receiver.consume_messages("hello world queue")
   
       # Close connections.
       basic_message_receiver.close()
   ```

1.  Run `consumer.py` again, and if successful, the queued messages will be displayed in your terminal window. 

   ```
   [*] Waiting for messages. To exit press CTRL+C
   [x] Received b'Hello World!'
   [x] Received b'Hello World!'
   ...
   ```

## What's next?
<a name="amazon-mq-rabbitmq-pika-whats-next"></a>
+  For more information about other supported RabbitMQ client libraries, see [RabbitMQ Client Documentation](https://www.rabbitmq.com/clients.html) on the RabbitMQ website. 

# Resolving RabbitMQ paused queue synchronization
<a name="rabbitmq-queue-sync"></a>

In an Amazon MQ for RabbitMQ [cluster deployment](rabbitmq-broker-architecture.md#rabbitmq-broker-architecture-cluster), messages published to each queue are replicated across three broker nodes. This replication, referred to as *mirroring*, provides high availability (HA) for RabbitMQ brokers. Queues in a cluster deployment consist of a *main* replica on one node and one or more *mirrors*. Every operation applied to a mirrored queue, including enqueuing messages, is first applied to the main queue and then replicated across its mirrors.

For example, consider a mirrored queue replicated across three nodes: the main node (`main`) and two mirrors (`mirror-1` and `mirror-2`). If all messages in this mirrored queue are successfully propagated to all mirrors, then the queue is synchronized. If a node (`mirror-1`) becomes unavailable for an interval of time, the queue is still operational and can continue to enqueue messages. However, for the queue to synchronize, messages published to `main` while `mirror-1` is unavailable must be replicated to `mirror-1`.

For more information about mirroring, see [Classic Mirrored Queues](https://www.rabbitmq.com/ha.html) on the RabbitMQ website.

**Maintenance and queue synchronization**

During [maintenance windows](amazon-mq-rabbitmq-editing-broker-preferences.md#rabbitmq-edit-current-configuration-console), Amazon MQ performs all maintenance work one node at a time to ensure that the broker remains operational. As a result, queues might need to synchronize as each node resumes operation. During synchronization, messages that need to be replicated to mirrors are loaded into memory from the corresponding Amazon Elastic Block Store (Amazon EBS) volume to be processed in batches. Processing messages in batches lets queues synchronize faster.

If queues are kept short and messages are small, the queues successfully synchronize and resume operation as expected. However, if the amount of data in a batch approaches the node's memory limit, the node raises a high memory alarm, pausing the queue sync. You can confirm memory usage by comparing the `RabbitMemUsed` and `RabbitMqMemLimit` [broker node metrics in CloudWatch](amazon-mq-accessing-metrics.md). Synchronization can't complete until messages are consumed or deleted, or the number of messages in the batch is reduced.

**Note**  
Reducing the queue synchronization batch size can result in a higher number of replication transactions.

To resolve a paused queue synchronization, follow the steps in this tutorial, which demonstrates applying an `ha-sync-batch-size` policy and restarting the queue sync.

**Topics**
+ [Prerequisites](#rabbitmq-queue-sync-prerequisites)
+ [Step 1: Apply an `ha-sync-batch-size` policy](#rabbitmq-queue-sync-step-1)
+ [Step 2: Restart the queue sync](#rabbitmq-queue-sync-step-2)
+ [Next steps](#rabbitmq-queue-sync-next-steps)
+ [Related resources](#rabbitmq-queue-sync-related-resources)

## Prerequisites
<a name="rabbitmq-queue-sync-prerequisites"></a>

For this tutorial, you must have an Amazon MQ for RabbitMQ broker user with administrator permissions. You can use the administrator user created when you first created the broker, or another user that you might have created afterwards. The following table provides the necessary administrator user tag and permissions as regular expression (regexp) patterns.


| Tags | Read regexp | Configure regexp | Write regexp | 
| --- | --- | --- | --- | 
| administrator | .\$1 | .\$1 | .\$1 | 

For more information about creating RabbitMQ users and managing user tags and permissions, see [Amazon MQ for RabbitMQ broker users](rabbitmq-simple-auth-broker-users.md#rabbitmq-basic-elements-user).

## Step 1: Apply an `ha-sync-batch-size` policy
<a name="rabbitmq-queue-sync-step-1"></a>

The following procedures demonstrate adding a policy that applies to all queues created on the broker. You can use the RabbitMQ web console or the RabbitMQ management API. For more information, see [Management Plugin](https://www.rabbitmq.com/management.html) on the RabbitMQ website.

**To apply an `ha-sync-batch-size` policy using the RabbitMQ web console**

1. Sign in to the [Amazon MQ console](https://console.aws.amazon.com/amazon-mq/).

1. In the left navigation pane, choose **Brokers**.

1. From the list of brokers, choose the name of the broker to which you want to apply the new policy.

1. On the broker's page, in the **Connections** section, choose the **RabbitMQ web console** URL. The RabbitMQ web console opens in a new browser tab or window.

1. Log in to the RabbitMQ web console with your broker administrator sign-in credentials.

1. In the RabbitMQ web console, at the top of the page, choose **Admin**.

1. On the **Admin** page, in the right navigation pane, choose **Policies**.

1. On the **Policies** page, you can see a list of the broker's current **User policies**. Below **User policies**, expand **Add / update a policy**.
**Note**  
By default, Amazon MQ for RabbitMQ clusters are created with an initial broker policy named `ha-all-AWS-OWNED-DO-NOT-DELETE`. Amazon MQ manages this policy to ensure that every queue on the broker is replicated to all three nodes and that queues are synchronized automatically.

1. To create a new broker policy, under **Add / update a policy**, do the following:

   1. For **Name**, enter a name for your policy, for example, **batch-size-policy**.

   1. For **Pattern**, enter the regexp pattern **.\$1** so that the policy matches all queues on the broker.

   1. For **Apply to**, choose **Exchanges and queues** from the dropdown list.

   1. For **Priority**, enter an integer greater than all other policies in applied to the vhost. You can apply exactly one set of policy definitions to RabbitMQ queues and exchanges at any given time. RabbitMQ chooses the matching policy with the highest priority value. For more information about policy priorities and how to combine policies, see [Policies](https://www.rabbitmq.com/parameters.html#policies) in the RabbitMQ Server Documentation.

   1. For **Definition**, add the following key-value pairs:
      + **ha-sync-batch-size**=*100*. Choose **Number** from the dropdown list.
**Note**  
You might need to adjust and calibrate the value of `ha-sync-batch-size` based on the number and size of unsynchronized messages in your queues.
      + **ha-mode**=**all**. Choose **String** from the dropdown list.
**Important**  
The `ha-mode` definition is required for all HA-related policies. Omitting it results in a validation failure.
      + **ha-sync-mode**=**automatic**. Choose **String** from the dropdown list.
**Note**  
The `ha-sync-mode` definition is required for all custom policies. If it is omitted, Amazon MQ automatically appends the definition.

   1. Choose **Add / update policy**.

1. Confirm that the new policy appears in the list of **User policies**.

**To apply an `ha-sync-batch-size` policy using the RabbitMQ management API**

1. Sign in to the [Amazon MQ console](https://console.aws.amazon.com/amazon-mq/).

1. In the left navigation pane, choose **Brokers**.

1. From the list of brokers, choose the name of the broker to which you want to apply the new policy.

1. On the broker's page, in the **Connections** section, note the **RabbitMQ web console** URL. This is the broker endpoint that you use in an HTTP request.

1. Open a new terminal or command line window of your choice.

1. To create a new broker policy, enter the following `curl` command. This command assumes a queue on the default `/` vhost, which is encoded as `%2F`.
**Note**  
Replace *username* and *password* with your broker administrator sign-in credentials. You might need to adjust and calibrate the value of `ha-sync-batch-size` (*100*) based on the number and size of unsynchronized messages in your queues. Replace the broker endpoint with the URL that you noted previously.

   ```
   curl -i -u username:password -H "content-type:application/json" -XPUT \
   -d '{"pattern":".*", "priority":1, "definition":{"ha-sync-batch-size":100, "ha-mode":"all", "ha-sync-mode":"automatic"}}' \
   https://b-589c045f-f8ln-4ab0-a89c-co62e1c32ef8.mq.us-west-2.amazonaws.com/api/policies/%2F/batch-size-policy
   ```

1. To confirm that the new policy is added to your broker's user policies, enter the following `curl` command to list all broker policies.

   ```
   curl -i -u username:password https://b-589c045f-f8ln-4ab0-a89c-co62e1c32ef8.mq.us-west-2.amazonaws.com/api/policies
   ```

## Step 2: Restart the queue sync
<a name="rabbitmq-queue-sync-step-2"></a>

After applying a new `ha-sync-batch-size` policy to your broker, restart the queue sync.

**To restart the queue sync using the RabbitMQ web console**
**Note**  
To open the RabbitMQ web console, see the previous instructions in Step 1 of this tutorial.

1. In the RabbitMQ web console, at the top of the page, choose **Queues**.

1. On the **Queues** page, under **All queues**, locate your paused queue. In the **Policy** row, your queue should list the name of the new policy that you created (for example, `batch-size-policy`).

1. To restart the synchronization process with a reduced batch size, first cancel queue sync. Then restart the queue sync. 

**Note**  
If synchronization pauses and doesn't finish successfully, try reducing the `ha-sync-batch-size` value and restarting the queue sync again.

## Next steps
<a name="rabbitmq-queue-sync-next-steps"></a>
+ Once your queue synchronizes successfully, you can monitor the amount of memory that your RabbitMQ nodes use by viewing the Amazon CloudWatch metric `RabbitMQMemUsed`. You can also view the `RabbitMQMemLimit` metric to monitor a node's memory limit. For more information, see [Accessing CloudWatch metrics for Amazon MQ](amazon-mq-accessing-metrics.md) and [Available CloudWatch metrics for Amazon MQ for RabbitMQ brokers](rabbitmq-logging-monitoring.md).
+ To prevent paused queue synchronization, we recommend keeping queues short and processing messages. For workloads with larger message sizes, we also recommend upgrading your broker instance type to a larger instance size with more memory. For more information about broker instance types and editing broker preferences, see [Editing broker preferences](amazon-mq-rabbitmq-editing-broker-preferences.md).
+  When you create a new Amazon MQ for RabbitMQ broker, Amazon MQ applies a set of default policies and virtual host limits to optimize broker performance. If your broker does not have the recommended default policies and limits, we recommend creating them yourself. For more information about creating default policies and vhost limits, see [https://docs.aws.amazon.com//amazon-mq/latest/developer-guide/rabbitmq-defaults.html](https://docs.aws.amazon.com//amazon-mq/latest/developer-guide/rabbitmq-defaults.html). 

## Related resources
<a name="rabbitmq-queue-sync-related-resources"></a>
+  [UpdateBrokerInput](https://docs.aws.amazon.com/amazon-mq/latest/api-reference/brokers-broker-id.html#brokers-broker-id-model-updatebrokerinput) – Use this broker property to update a broker instance type using the Amazon MQ API.
+ [Parameters and Policies](https://www.rabbitmq.com/parameters.html) (RabbitMQ Server Documentation) – Learn more about RabbitMQ parameters and policies on the RabbitMQ website.
+ [RabbitMQ Management HTTP API](https://pulse.mozilla.org/api/) – Learn more about the RabbitMQ management API.

# Reducing the number of connections and channels
<a name="reducing-connections-and-channels"></a>

Connections to your RabbitMQ on Amazon MQ broker can be closed either by your client applications, or by manually closing them using the RabbitMQ web console. To close a connection using the RabbitMQ web console, do the following:

1. Sign in to AWS Management Console and open your broker's RabbitMQ web console.

1.  On the RabbitMQ console, choose the **Connections** tab. 

1. On the **Connections** page, under **All connections**, choose the name of the connection you want to close from the list.

1.  On the connection details page, choose **Close this connection** to expand the section, then choose **Force Close**. Optionally, you can replace the default text for **Reason** with your own description. RabbitMQ on Amazon MQ will return the reason you specify to the client when you close the connection. 

1.  Choose **OK** on the dialog box to confirm and close the connection. 

 When you close a connection, any channels associated with closed connection will also be closed. 

**Note**  
 Your client applications may be configured to automatically re-establish connections to the broker after they are closed. In this case, closing connections from the broker web console will not be sufficient for reducing connection or channel counts. 

For brokers without public access, you can temporarily block connections by denying inbound traffic on the appropriate message protocol port, for example, port `5671` for AMQP connections. You can block the port in the security group that you provided to Amazon MQ when creating the broker. For more information on modifying your security group, see [Adding rules to a security group](https://docs.aws.amazon.com/vpc/latest/userguide/VPC_SecurityGroups.html#adding-security-group-rules) in the *Amazon VPC User Guide*. 

## Step 2: Connect a JVM-based application to your broker
<a name="rabbitmq-connect-jvm-application"></a>

 After you create a RabbitMQ broker, you can connect your application to it. The following examples show how you can use the [RabbitMQ Java client library](https://www.rabbitmq.com/java-client.html) to create a connection to your broker, create a queue, and send a message. You can connect to RabbitMQ brokers using supported RabbitMQ client libraries for a variety of languages. For more information on supported RabbitMQ client libraries, see [RabbitMQ client libraries and developer tools](https://www.rabbitmq.com/devtools.html). 

### Prerequisites
<a name="rabbitmq-connect-application-prerequisites-getting-started"></a>

**Note**  
The following prerequisite steps are only applicable to RabbitMQ brokers created without public accessibility. If you are creating a broker with public accessibility you can skip them.

#### Enable VPC attributes
<a name="rabbitmq-connect-application-enable-vpc-attributes-getting-started"></a>

To ensure that your broker is accessible within your VPC, you must enable the `enableDnsHostnames` and `enableDnsSupport` VPC attributes. For more information, see [DNS Support in your VPC](https://docs.aws.amazon.com/vpc/latest/userguide/vpc-dns.html#vpc-dns-support) in the *Amazon VPC User Guide*.

#### Enable inbound connections
<a name="rabbitmq-connect-application-allow-inbound-connections-getting-started"></a>

1. Sign in to the [Amazon MQ console](https://console.aws.amazon.com/amazon-mq/).

1. From the broker list, choose the name of your broker (for example, **MyBroker**).

1. On the ***MyBroker*** page, in the **Connections** section, note the addresses and ports of the broker's web console URL and wire-level protocols.

1. In the **Details** section, under **Security and network**, choose the name of your security group or ![\[Pencil icon indicating an edit or modification action.\]](http://docs.aws.amazon.com/amazon-mq/latest/developer-guide/images/amazon-mq-tutorials-broker-details-link.png).

   The **Security Groups** page of the EC2 Dashboard is displayed.

1. From the security group list, choose your security group.

1. At the bottom of the page, choose **Inbound**, and then choose **Edit**.

1. In the **Edit inbound rules** dialog box, add a rule for every URL or endpoint that you want to be publicly accessible (the following example shows how to do this for a broker web console).

   1. Choose **Add Rule**.

   1. For **Type**, select **Custom TCP**.

   1. For **Source**, leave **Custom** selected and then type the IP address of the system that you want to be able to access the web console (for example, `192.0.2.1`).

   1. Choose **Save**.

      Your broker can now accept inbound connections.

#### Add Java dependencies
<a name="rabbitmq-connect-application-java-dependencies-getting-started"></a>

If you are using Apache Maven for automating builds, add the following dependency to your `pom.xml` file. For more information on Project Object Model files in Apache Maven, see [Introduction to the POM](https://maven.apache.org/guides/introduction/introduction-to-the-pom.html).

```
<dependency>
    <groupId>com.rabbitmq</groupId>
    <artifactId>amqp-client</artifactId>
    <version>5.9.0</version>
</dependency>
```

If you are using [Gradle](https://docs.gradle.org/current/userguide/userguide.html) for automating builds, declare the following dependency.

```
dependencies {
    compile 'com.rabbitmq:amqp-client:5.9.0'
}
```

#### Import `Connection` and `Channel` classes
<a name="rabbitmq-import-connections-and-channels"></a>

 RabbitMQ Java client uses `com.rabbitmq.client` as its top-level package, with `Connection` and `Channel` API classes representing an AMQP 0-9-1 connection and channel, respectively. Import the `Connection` and `Channel` classes before using them, as shown in the following example. 

```
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.Channel;
```

#### Create a `ConnectionFactory` and connect to your broker
<a name="rabbitmq-create-connection-factory-and-connect"></a>

Use the following example to create an instance of the `ConnectionFactory` class with the given parameters. Use the `setHost` method to configure the broker endpoint you noted earlier. For `AMQPS` wire-level connections, use port `5671`.

```
ConnectionFactory factory = new ConnectionFactory();

factory.setUsername(username);
factory.setPassword(password);

//Replace the URL with your information
factory.setHost("b-c8352341-ec91-4a78-ad9c-a43f23d325bb.mq.us-west-2.amazonaws.com");
factory.setPort(5671);

// Allows client to establish a connection over TLS
factory.useSslProtocol();

// Create a connection
Connection conn = factory.newConnection();

// Create a channel
Channel channel = conn.createChannel();
```

#### Publish a message to an exchange
<a name="rabbitmq-publish-message"></a>

 You can use `Channel.basicPublish` to publish messages to an exchange. The following example uses the AMQP `Builder` class to build a message properties object with content-type `plain/text`. 

```
byte[] messageBodyBytes = "Hello, world!".getBytes();
channel.basicPublish(exchangeName, routingKey,
             new AMQP.BasicProperties.Builder()
               .contentType("text/plain")
               .userId("userId")
               .build(),
               messageBodyBytes);
```

**Note**  
Note that `BasicProperties` is an inner class of the autogenerated holder class, `AMQP`.

#### Subscribe to a queue and receive a message
<a name="rabbitmq-subscribe-receive-message"></a>

You can receive a message by subscribing to a queue using the `Consumer` interface. Once subscribed, messages will then be delivered automatically as they arrive.

The easiest way to implement a `Consumer` is to use the subclass `DefaultConsumer`. A `DefaultConsumer` object can be passed as part of a `basicConsume` call to set up the subscription as shown in the following example.

```
boolean autoAck = false;
channel.basicConsume(queueName, autoAck, "myConsumerTag",
     new DefaultConsumer(channel) {
         @Override
         public void handleDelivery(String consumerTag,
                                    Envelope envelope,
                                    AMQP.BasicProperties properties,
                                    byte[] body)
             throws IOException
         {
             String routingKey = envelope.getRoutingKey();
             String contentType = properties.getContentType();
             long deliveryTag = envelope.getDeliveryTag();
             // (process the message components here ...)
             channel.basicAck(deliveryTag, false);
         }
     });
```

**Note**  
Because we specified `autoAck = false`, it is necessary to acknowledge messages delivered to the `Consumer`, most conveniently done in the `handleDelivery` method, as shown in the example.

#### Close your connection and disconnect from the broker
<a name="rabbitmq-disconnect"></a>

In order to disconnect from your RabbitMQ broker, close both the channel and connection as shown in the following.

```
channel.close();
conn.close();
```

**Note**  
For more information on working with the RabbitMQ Java client library, see the [RabbitMQ Java Client API Guide](https://www.rabbitmq.com/api-guide.html).

## Step 3: (Optional) Connect to an AWS Lambda function
<a name="rabbitmq-connect-to-lambda"></a>

 AWS Lambda can connect to and consume messages from your Amazon MQ broker. When you connect a broker to Lambda, you create an [event source mapping](https://docs.aws.amazon.com/lambda/latest/dg/invocation-eventsourcemapping.html) that reads messages from a queue and invokes the function [synchronously](https://docs.aws.amazon.com/lambda/latest/dg/invocation-sync.html). The event source mapping you create reads messages from your broker in batches and converts them into a Lambda payload in the form of a JSON object. 

**To connect your broker to a Lambda function**

1. Add the following IAM role permissions to your Lambda function [execution role](https://docs.aws.amazon.com/lambda/latest/dg/lambda-intro-execution-role.html).
   + [mq:DescribeBroker](https://docs.aws.amazon.com/amazon-mq/latest/api-reference/brokers-broker-id.html#brokers-broker-id-http-methods)
   + [ec2:CreateNetworkInterface](https://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_CreateNetworkInterface.html)
   + [ec2:DeleteNetworkInterface](https://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_DeleteNetworkInterface.html)
   + [ec2:DescribeNetworkInterfaces](https://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_DescribeNetworkInterfaces.html)
   + [ec2:DescribeSecurityGroups](https://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_DescribeSecurityGroups.html)
   + [ec2:DescribeSubnets](https://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_DescribeSubnets.html)
   + [ec2:DescribeVpcs](https://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_DescribeVpcs.html)
   + [logs:CreateLogGroup](https://docs.aws.amazon.com/AmazonCloudWatchLogs/latest/APIReference/API_CreateLogGroup.html)
   + [logs:CreateLogStream](https://docs.aws.amazon.com/AmazonCloudWatchLogs/latest/APIReference/API_CreateLogStream.html)
   + [logs:PutLogEvents](https://docs.aws.amazon.com/AmazonCloudWatchLogs/latest/APIReference/API_PutLogEvents.html)
   + [secretsmanager:GetSecretValue](https://docs.aws.amazon.com/secretsmanager/latest/apireference/API_GetSecretValue.html)
**Note**  
Without the necessary IAM permissions, your function will not be able to successfully read records from Amazon MQ resources.

1.  (Optional) If you have created a broker without public accessibility, you must do one of the following to allow Lambda to connect to your broker: 
   +  Configure one NAT gateway per public subnet. For more information, see [Internet and service access for VPC-connected functions](https://docs.aws.amazon.com/lambda/latest/dg/configuration-vpc.html#vpc-internet) in the *AWS Lambda Developer Guide*. 
   + Create a connection between your Amazon Virtual Private Cloud (Amazon VPC) and Lambda using a VPC endpoint. Your Amazon VPC must also connect to AWS Security Token Service (AWS STS) and Secrets Manager endpoints. For more information, see [Configuring interface VPC endpoints for Lambda](https://docs.aws.amazon.com/lambda/latest/dg/configuration-vpc-endpoints.html) in the *AWS Lambda Developer Guide*. 

1.  [Configure your broker as an event source](https://docs.aws.amazon.com/lambda/latest/dg/with-mq.html#services-mq-eventsourcemapping) for a Lambda function using the AWS Management Console. You can also use the [https://docs.aws.amazon.com/cli/latest/reference/lambda/create-event-source-mapping.html](https://docs.aws.amazon.com/cli/latest/reference/lambda/create-event-source-mapping.html) AWS Command Line Interface command. 

1.  Write some code for your Lambda function to process the messages from your consumed from your broker. The Lambda payload that retrieved by your event source mapping depends on the engine type of the broker. The following is an example of a Lambda payload for an Amazon MQ for RabbitMQ queue. 
**Note**  
 In the example, `test` is the name of the queue, and `/` is the name of the default virtual host. When receiving messages, the event source lists messages under `test::/`. 

   ```
   {
     "eventSource": "aws:rmq",
     "eventSourceArn": "arn:aws:mq:us-west-2:112556298976:broker:test:b-9bcfa592-423a-4942-879d-eb284b418fc8",
     "rmqMessagesByQueue": {
       "test::/": [
         {
           "basicProperties": {
             "contentType": "text/plain",
             "contentEncoding": null,
             "headers": {
               "header1": {
                 "bytes": [
                   118,
                   97,
                   108,
                   117,
                   101,
                   49
                 ]
               },
               "header2": {
                 "bytes": [
                   118,
                   97,
                   108,
                   117,
                   101,
                   50
                 ]
               },
               "numberInHeader": 10
             }
             "deliveryMode": 1,
             "priority": 34,
             "correlationId": null,
             "replyTo": null,
             "expiration": "60000",
             "messageId": null,
             "timestamp": "Jan 1, 1970, 12:33:41 AM",
             "type": null,
             "userId": "AIDACKCEVSQ6C2EXAMPLE",
             "appId": null,
             "clusterId": null,
             "bodySize": 80
           },
           "redelivered": false,
           "data": "eyJ0aW1lb3V0IjowLCJkYXRhIjoiQ1pybWYwR3c4T3Y0YnFMUXhENEUifQ=="
         }
       ]
     }
   }
   ```

For more information on connecting Amazon MQ to Lambda, the options Lambda supports for an Amazon MQ event source, and event source mapping errors, see [Using Lambda with Amazon MQ](https://docs.aws.amazon.com/lambda/latest/dg/with-mq.html) in the *AWS Lambda Developer Guide*.

# Using OAuth 2.0 authentication and authorization for Amazon MQ for RabbitMQ
<a name="oauth-tutorial"></a>

This tutorial describes how to configure [OAuth 2.0 authentication](oauth-for-amq-for-rabbitmq.md) for your Amazon MQ for RabbitMQ brokers using Amazon Cognito as the OAuth 2.0 provider.

**Note**  
Amazon Cognito is not available in China (Beijing) and China (Ningxia).

**Important**  
This tutorial is specific to Amazon Cognito, but you can use other identity providers (IdPs). For more information, see [OAuth 2.0 Authentication Examples](https://www.rabbitmq.com/docs/oauth2-examples).

**Topics**
+ [Prerequisites to configure OAuth 2.0 authentication](#oauth-tutorial-prerequisites)
+ [Configuring OAuth 2.0 authentication with Amazon Cognito using AWS CLI](#oauth-tutorial-config-cognito-using-cli)
+ [Configuring OAuth 2.0 and simple authentication with Amazon Cognito](#oauth-tutorial-config-both-auth-methods-using-cli)

## Prerequisites to configure OAuth 2.0 authentication
<a name="oauth-tutorial-prerequisites"></a>

You can set the Amazon Cognito resources required in this tutorial by deploying the AWS CDK stack, [Amazon Cognito stack for RabbitMQ OAuth 2 plugin](https://github.com/aws-samples/amazon-mq-samples/tree/main/rabbitmq-samples/rabbitmq-oauth2-cognito-sample). If you're setting up Amazon Cognito manually, make sure that you fulfill the following prerequisites before configuring OAuth 2.0 on your Amazon MQ for RabbitMQ brokers:

**Prerequisites to set up Amazon Cognito**
+ Set up an Amazon Cognito endpoint by creating a user pool. To do this, see the blog titled [How to use OAuth 2.0 in Amazon Cognito: Learn about the different OAuth 2.0 grants](https://aws.amazon.com/blogs/security/how-to-use-oauth-2-0-in-amazon-cognito-learn-about-the-different-oauth-2-0-grants/).
+ Create a resource server called `rabbitmq` in the user pool with the following scopes defined: `read:all`, `write:all`, `configure:all`, and `tag:administrator`. These scopes will be associated with RabbitMQ permissions.

  For information about creating a resource server, see [Defining a resource server for your user pool (AWS Management Console)](https://docs.aws.amazon.com/cognito/latest/developerguide/cognito-user-pools-define-resource-servers.html#cognito-user-pools-define-resource-servers-console) in the *Amazon Cognito Developer Guide*.
+ Create the following application clients:
  + Application client for the user pool of type `Machine-to-Machine application`. This is a confidential client with a client secret that will be used for RabbitMQ AMQP clients. For more information about application clients and creating one, see [App client types](https://docs.aws.amazon.com/cognito/latest/developerguide/user-pool-settings-client-apps.html#user-pool-settings-client-app-client-types) and [Creating an app client](https://docs.aws.amazon.com/cognito/latest/developerguide/user-pool-settings-client-apps.html#cognito-user-pools-app-idp-settings-console-create).
  + Application client for the user pool of type `Single-page application`. This is a public client that will be used to log in users into the RabbitMQ management console. You must update this application client to include the endpoint of the Amazon MQ for RabbitMQ broker you'll create in the following procedure as an allowed callback URL. For more information, see [Setting up managed login with the Amazon Cognito console](https://docs.aws.amazon.com/cognito/latest/developerguide/cognito-user-pools-managed-login.html#set-up-managed-login).

**Prerequisite to set up Amazon MQ**
+ A working [Docker](https://docs.docker.com/engine/install/) installation to run a bash script that verifies whether or not the OAuth 2.0 setup is successful.
+ AWS CLI version >= `2.28.23` to make adding a username and password optional during broker creation.

## Configuring OAuth 2.0 authentication with Amazon Cognito using AWS CLI
<a name="oauth-tutorial-config-cognito-using-cli"></a>

The following procedure shows how to set up OAuth 2.0 authentication for your Amazon MQ for RabbitMQ brokers using Amazon Cognito as the IdP. This procedure uses AWS CLI to create and configure the necessary resources.

In the following procedure, make sure to replace the placeholder values, such as configurationID and Revision, *<c-fa3390a5-7e01-4559-ae0c-eb15b38b22ca>* and *<2>*, with their actual values.

1. Create a new configuration using the [create-configuration](https://docs.aws.amazon.com/cli/latest/reference/mq/create-configuration.html) AWS CLI command as shown in the following example.

   ```
   aws mq create-configuration \
     --name "rabbitmq-oauth2-config" \
     --engine-type "RABBITMQ" \
     --engine-version "3.13"
   ```

   This command returns a response similar to the following example.

   ```
   {
       "Arn": "arn:aws:mq:us-west-2:123456789012:configuration:c-fa3390a5-7e01-4559-ae0c-eb15b38b22ca",
       "AuthenticationStrategy": "simple",
       "Created": "2025-07-17T16:03:01.759943+00:00",
       "Id": "c-fa3390a5-7e01-4559-ae0c-eb15b38b22ca",
       "LatestRevision": {
       "Created": "2025-07-17T16:03:01.759000+00:00",
       "Description": "Auto-generated default for rabbitmq-oauth2-config on RabbitMQ 3.13",
       "Revision": 1
       },
       "Name": "rabbitmq-oauth2-config"
   }
   ```

1. Create a configuration file called **rabbitmq.conf** to use OAuth 2.0 as the authentication and authorization method, as shown in the following example.

   ```
   auth_backends.1 = oauth2
   
   # FIXME: Update this value with the token signing key URL of your Amazon Cognito user pool.
   # If you used the AWS CDK stack to deploy Amazon Cognito, this is one of the stack outputs.
   auth_oauth2.jwks_url = ${RabbitMqOAuth2TestStack.JwksUri}
   auth_oauth2.resource_server_id = rabbitmq
   # Amazon Cognito does not include an audience field in access tokens
   auth_oauth2.verify_aud = false 
   
   # Amazon Cognito does not allow * in its custom scopes. Use aliases to translate between Amazon Cognito and RabbitMQ.
   auth_oauth2.scope_prefix = rabbitmq/
   auth_oauth2.scope_aliases.1.alias = rabbitmq/read:all
   auth_oauth2.scope_aliases.1.scope = rabbitmq/read:*/*
   auth_oauth2.scope_aliases.2.alias = rabbitmq/write:all
   auth_oauth2.scope_aliases.2.scope = rabbitmq/write:*/*
   auth_oauth2.scope_aliases.3.alias = rabbitmq/configure:all
   auth_oauth2.scope_aliases.3.scope = rabbitmq/configure:*/*
   
   # Allow OAuth 2.0 login for RabbitMQ management console
   management.oauth_enabled = true
   # FIXME: Update this value with the client ID of your public application client
   management.oauth_client_id = ${RabbitMqOAuth2TestStack.ManagementConsoleAppClientId}
   # FIXME: Update this value with the base JWKS URI (without /.well-known/jwks.json)
   auth_oauth2.issuer = ${RabbitMqOAuth2TestStack.Issuer}
   management.oauth_scopes = rabbitmq/tag:administrator
   ```

   This configuration uses [scope aliases](https://www.rabbitmq.com/docs/oauth2#scope-translation) to map the scopes defined in Amazon Cognito to RabbitMQ compatible scopes.

1. Update the configuration using the [update-configuration](https://docs.aws.amazon.com/cli/latest/reference/mq/update-configuration.html) AWS CLI command as shown in the following example. In this command, add the configuration ID you received in the response of Step 1 of this procedure. For example, **c-fa3390a5-7e01-4559-ae0c-eb15b38b22ca**.

   ```
   aws mq update-configuration \
     --configuration-id "<c-fa3390a5-7e01-4559-ae0c-eb15b38b22ca>" \
     --data "$(cat rabbitmq.conf | base64 --wrap=0)"
   ```

   This command returns a response similar to the following example.

   ```
   {
       "Arn": "arn:aws:mq:us-west-2:123456789012:configuration:c-b600ac8e-8183-4f74-a713-983e59f30e3d",
       "Created": "2025-07-17T16:57:04.520931+00:00",
       "Id": "c-b600ac8e-8183-4f74-a713-983e59f30e3d",
       "LatestRevision": {
           "Created": "2025-07-17T16:57:39.172000+00:00",
           "Revision": 2
       },
       "Name": "rabbitmq-oauth2-config",
       "Warnings": []
   }
   ```

1. Create a broker with the OAuth 2.0 configuration you created in the Step 2 of this procedure. To do this, use the [create-broker](https://docs.aws.amazon.com/cli/latest/reference/mq/create-broker.html) AWS CLI command as shown in the following example. In this command, provide the configuration ID and revision number you obtained in the responses of Step 1 and 2 respectively. For example, **c-fa3390a5-7e01-4559-ae0c-eb15b38b22ca** and **2**.

   ```
   aws mq create-broker \
    --broker-name "rabbitmq-oauth2-broker" \ 
    --engine-type "RABBITMQ" \
    --engine-version "3.13" \
    --host-instance-type "mq.m7g.large" \
    --deployment-mode "CLUSTER_MULTI_AZ" \
    --logs '{"General": true}' \
    --publicly-accessible \
    --configuration '{"Id": "<c-fa3390a5-7e01-4559-ae0c-eb15b38b22ca>","Revision": <2>}' \
   ```

   This command returns a response similar to the following example.

   ```
   {
       "BrokerArn": "arn:aws:mq:us-west-2:123456789012:broker:rabbitmq-oauth2-broker:b-2a1b5133-a10c-49d2-879b-8c176c34cf73",
       "BrokerId": "b-2a1b5133-a10c-49d2-879b-8c176c34cf73"
   }
   ```

1. Verify that the broker's status transitions from `CREATION_IN_PROGRESS` to `RUNNING`, using the [describe-broker](https://docs.aws.amazon.com/cli/latest/reference/mq/describe-broker.html) AWS CLI command as shown in the following example. In this command, provide the broker ID you obtained in the result of the previous step For example, **b-2a1b5133-a10c-49d2-879b-8c176c34cf73**.

   ```
   aws mq describe-broker \
    --broker-id "<b-2a1b5133-a10c-49d2-879b-8c176c34cf73>"
   ```

   This command returns a response similar to the following example. The following response is an abbreviated version of the complete output that the `describe-broker` command returns. This response shows the broker status and the authentication strategy used to secure the broker. In this case, the `config_managed` authentication strategy indicates that the broker uses OAuth 2 authentication method.

   ```
   {
       "AuthenticationStrategy": "config_managed",
       ...,
       "BrokerState": "RUNNING",
       ...
   }
   ```

    To log in to the RabbitMQ management console using OAuth2, the broker endpoint needs to be added as a valid callback URL in the corresponding Amazon Cognito app client. For more information, refer to Step 5 in the setup of our sample [ Amazon Cognito CDK stack](https://github.com/aws-samples/amazon-mq-samples/tree/main/rabbitmq-samples/rabbitmq-oauth2-cognito-sample#step-5-update-callback-urls-if-using-placeholder-urls). 

1. Verify OAuth 2.0 authentication and authorization with the following `perf-test.sh` script.

   Use this bash script to test connectivity to your Amazon MQ for RabbitMQ broker. This script obtains a token from Amazon Cognito and verifies if the connection was properly configured. If it’s successfully configured, you’ll see your broker publish and consume messages.

   If you receive an `ACCESS_REFUSED` error, you can troubleshoot your configuration settings by using the CloudWatch logs for your broker. You can find the link for the CloudWatch log group for your broker in the Amazon MQ console.

   In this script, you'll need to provide the following values:
   + `CLIENT_ID` and `CLIENT_SECRET`: You can find these values on the **App clients** page of the Amazon Cognito console.
   + Cognito domain: You can find this on the Amazon Cognito console. Under **Branding**, choose **Domain**. On the **Domain** page, you can find this value under the **Resource servers** section.
   + Amazon MQ broker endpoint: You can find this value under **Connections** on the broker details page of the Amazon MQ console.

   ```
   #! /bin/bash
   set -e
   
   # Client information
   ## FIXME: Update this value with the client ID and secret of your confidential application client
   CLIENT_ID=${RabbitMqOAuth2TestStack.AmqpAppClientId}
   CLIENT_SECRET=${RabbitMqOAuth2TestStack.AmqpAppClientSecret}
   
   # FIXME: Update this value with the domain of your Amazon Cognito user pool
   RESPONSE=$(curl -X POST ${RabbitMqOAuth2TestStack.TokenEndpoint} \
                   -H "Content-Type: application/x-www-form-urlencoded" \
                   -d "grant_type=client_credentials&client_id=${CLIENT_ID}&client_secret=${CLIENT_SECRET}&scope=rabbitmq/configure:all rabbitmq/read:all rabbitmq/tag:administrator rabbitmq/write:all")
   
   
   # Extract the access_token from the response.
   # This token will be passed in the password field when connecting to the broker.
   # Note that the username is left blank, the field is ignored by the plugin.
   BROKER_PASSWORD=$(echo ${RESPONSE} | jq -r '.access_token')
   
   # FIXME: Update this value with the endpoint of your broker. For example, b-89424106-7e0e-4abe-8e98-8de0dada7630.mq.us-east-1.on.aws.
   BROKER_DNS=<broker_dns>
   CONNECTION_STRING=amqps://:${BROKER_PASSWORD}@${BROKER_DNS}:5671 
   
   # Produce/consume messages using the above connection string
   QUEUES_COUNT=1
   PRODUCERS_COUNT=1
   CONSUMERS_COUNT=1
   PRODUCER_RATE=1
   
   docker run -it --rm --ulimit nofile=40960:40960 pivotalrabbitmq/perf-test:latest \
       --queue-pattern 'test-queue-%d' --queue-pattern-from 1 --queue-pattern-to $QUEUES_COUNT \
       --producers $PRODUCERS_COUNT --consumers $CONSUMERS_COUNT \
       --id "test${QUEUES_COUNT}q${PRODUCERS_COUNT}p${CONSUMERS_COUNT}c${PRODUCER_RATE}r" \
       --uri ${CONNECTION_STRING} \
       --flag persistent --rate $PRODUCER_RATE
   ```

## Configuring OAuth 2.0 and simple authentication with Amazon Cognito
<a name="oauth-tutorial-config-both-auth-methods-using-cli"></a>

When you create a broker with OAuth 2.0 authentication, you can specify one of the following authentication methods:
+ **OAuth 2.0 only**: To use this method, don't provide a username and password while creating the broker. The [previous procedure](#oauth-tutorial-config-cognito-using-cli) shows how to use only OAuth 2.0 authentication method.
+ **Both OAuth 2.0 and simple authentication**: To use this method, provide a username and password while creating the broker. Also, add `auth_backends.2 = internal` to your broker configuration, as shown in the following procedure.

In the following procedure, make sure to replace the placeholder values, such as *<ConfigurationId>* and *<Revision>*, with their actual values.

1. To use both the authentication methods, create your broker configuration, as shown in the following example.

   ```
   auth_backends.1 = oauth2
   auth_backends.2 = internal
   
   # FIXME: Update this value with the token signing key URL of your Amazon Cognito user pool
   auth_oauth2.jwks_url = ${RabbitMqOAuth2TestStack.JwksUri}
   auth_oauth2.resource_server_id = rabbitmq
   auth_oauth2.verify_aud = false
   
   auth_oauth2.scope_prefix = rabbitmq/
   auth_oauth2.scope_aliases.1.alias = rabbitmq/read:all
   auth_oauth2.scope_aliases.1.scope = rabbitmq/read:*/*
   auth_oauth2.scope_aliases.2.alias = rabbitmq/write:all
   auth_oauth2.scope_aliases.2.scope = rabbitmq/write:*/*
   auth_oauth2.scope_aliases.3.alias = rabbitmq/configure:all
   auth_oauth2.scope_aliases.3.scope = rabbitmq/configure:*/*
   ```

   This configuration uses [scope aliases](https://www.rabbitmq.com/docs/oauth2#scope-translation) to map the scopes defined in Amazon Cognito to RabbitMQ compatible scopes.

1. Create a broker that uses both the authentication methods, as shown in the following example.

   ```
   aws mq create-broker \
    --broker-name "rabbitmq-oauth2-broker-with-internal-user" \
    --engine-type "RABBITMQ" \
    --engine-version "3.13" \
    --host-instance-type "mq.m7g.large" \
    --deployment-mode "CLUSTER_MULTI_AZ" \
    --logs '{"General": true}' \
    --publicly-accessible \
    --configuration '{"Id": "<ConfigurationId>","Revision": <Revision>}' \
    --users '[{"Username":"<myUser>","Password":"<myPassword11>"}]'
   ```

1. Verify the broker status and the configuration for setting up the authentication method was successful as described in Steps 5 and 6 of the [Configuring OAuth 2.0 authentication with Amazon Cognito](#oauth-tutorial-config-cognito-using-cli) procedure.

# Using IAM authentication and authorization for Amazon MQ for RabbitMQ
<a name="rabbitmq-iam-tutorial"></a>

The following procedure demonstrates how to enable AWS IAM authentication and authorization for an Amazon MQ for RabbitMQ broker. After enabling IAM, users can authenticate using AWS IAM credentials to access the RabbitMQ Management API and connect via AMQP. For details on how IAM authentication works with Amazon MQ for RabbitMQ, see [IAM authentication and authorization for Amazon MQ for RabbitMQ](iam-for-amq-for-rabbitmq.md).

## Prerequisites
<a name="iam-tutorial-prerequisites"></a>
+ AWS administrator credentials for the AWS account that owns the Amazon MQ for RabbitMQ broker
+ A shell environment configured with these administrator credentials (using AWS CLI profiles or environment variables)
+ AWS CLI installed and configured
+ `jq` command-line JSON processor installed
+ `curl` command-line tool installed

## Configuring IAM authentication and authorization using AWS CLI
<a name="iam-tutorial-procedure"></a>

1. **Set environment variables**

   Set the required environment variables for your broker:

   ```
   export AWS_DEFAULT_REGION=<region>
   export BROKER_ID=<broker-id>
   ```

1. **Enable outbound JWT tokens**

   Enable outbound web identity federation for your AWS account:

   ```
   ISSUER_IDENTIFIER=$(aws iam enable-outbound-web-identity-federation --query 'IssuerIdentifier' --output text)
   echo $ISSUER_IDENTIFIER
   ```

   The output displays a unique issuer identifier URL for your account in the format `https://<id>.tokens.sts.global.api.aws`.

1. **Create the IAM policy document**

   Create a policy document that grants permissions to obtain web identity tokens:

   ```
   cat > policy.json << 'EOF'
   {
       "Version": "2012-10-17",		 	 	 
       "Statement": [
           {
               "Sid": "VisualEditor0",
               "Effect": "Allow",
               "Action": [
                   "sts:GetWebIdentityToken",
                   "sts:TagGetWebIdentityToken"
               ],
               "Resource": "*"
           }
       ]
   }
   EOF
   ```

1. **Create the trust policy**

   Retrieve your caller identity and create a trust policy document:

   ```
   CALLER_ARN=$(aws sts get-caller-identity --query Arn --output text)
   cat > trust-policy.json << EOF
   {
       "Version": "2012-10-17",		 	 	 
       "Statement": [
           {
               "Effect": "Allow",
               "Principal": {
                   "AWS": "$CALLER_ARN"
               },
               "Action": "sts:AssumeRole"
           }
       ]
   }
   EOF
   ```

1. **Create the IAM role**

   Create the IAM role and attach the policy:

   ```
   aws iam create-role --role-name RabbitMqAdminRole --assume-role-policy-document file://trust-policy.json
   aws iam put-role-policy --role-name RabbitMqAdminRole --policy-name RabbitMqAdminRolePolicy --policy-document file://policy.json
   ```

1. **Configure RabbitMQ OAuth2 settings**

   Create a RabbitMQ configuration file with OAuth2 authentication and authorization settings:

   ```
   cat > rabbitmq.conf << EOF
   auth_backends.1 = oauth2
   auth_backends.2 = internal
   
   auth_oauth2.jwks_url = ${ISSUER_IDENTIFIER}/.well-known/jwks.json
   auth_oauth2.resource_server_id = rabbitmq
   auth_oauth2.scope_prefix = rabbitmq/
   
   auth_oauth2.additional_scopes_key = sub
   auth_oauth2.scope_aliases.1.alias = arn:aws:iam::$(aws sts get-caller-identity --query Account --output text):role/RabbitMqAdminRole
   auth_oauth2.scope_aliases.1.scope = rabbitmq/tag:administrator rabbitmq/read:*/* rabbitmq/write:*/* rabbitmq/configure:*/*
   auth_oauth2.https.hostname_verification = wildcard
   
   management.oauth_enabled = true
   EOF
   ```

1. **Update the broker configuration**

   Apply the new configuration to your broker:

   ```
   # Retrieve the configuration ID
   CONFIG_ID=$(aws mq describe-broker --broker-id $BROKER_ID --query 'Configurations[0].Id' --output text)
   
   # Create a new configuration revision
   REVISION=$(aws mq update-configuration --configuration-id $CONFIG_ID --data "$(cat rabbitmq.conf | base64 --wrap=0)" --query 'LatestRevision.Revision' --output text)
   
   # Apply the configuration to the broker
   aws mq update-broker --broker-id $BROKER_ID --configuration Id=$CONFIG_ID,Revision=$REVISION
   
   # Reboot the broker to apply changes
   aws mq reboot-broker --broker-id $BROKER_ID
   ```

   Wait for the broker status to return to `RUNNING` before proceeding to the next step.

1. **Obtain a JWT token**

   Assume the IAM role and obtain a web identity token:

   ```
   # Assume the RabbitMqAdminRole
   ROLE_CREDS=$(aws sts assume-role --role-arn arn:aws:iam::$(aws sts get-caller-identity --query Account --output text):role/RabbitMqAdminRole --role-session-name rabbitmq-session)
   
   # Configure the session with temporary credentials
   export AWS_ACCESS_KEY_ID=$(echo "$ROLE_CREDS" | jq -r '.Credentials.AccessKeyId')
   export AWS_SECRET_ACCESS_KEY=$(echo "$ROLE_CREDS" | jq -r '.Credentials.SecretAccessKey')
   export AWS_SESSION_TOKEN=$(echo "$ROLE_CREDS" | jq -r '.Credentials.SessionToken')
   
   # Obtain the web identity token
   TOKEN_RESPONSE=$(aws sts get-web-identity-token \
       --audience "rabbitmq" \
       --signing-algorithm ES384 \
       --duration-seconds 300 \
       --tags Key=scope,Value="rabbitmq/tag:administrator")
   
   # Extract the token
   TOKEN=$(echo "$TOKEN_RESPONSE" | jq -r '.WebIdentityToken')
   ```

1. **Access the RabbitMQ Management API**

   Use the JWT token to access the RabbitMQ Management API:

   ```
   BROKER_URL=<broker-id>.mq.<region>.on.aws
   
   curl -u ":$TOKEN" \
       -X GET https://${BROKER_URL}/api/overview \
       -H "Content-Type: application/json"
   ```

   A successful response confirms that IAM authentication is working correctly. The response contains broker overview information in JSON format.

1. **Connect via AMQP using the JWT token**

   Test AMQP connectivity using the JWT token with the perf-test tool:

   ```
   BROKER_DNS=<broker-endpoint>
   CONNECTION_STRING=amqps://:${TOKEN}@${BROKER_DNS}:5671
   
   docker run -it --rm --ulimit nofile=40960:40960 pivotalrabbitmq/perf-test:latest \
       --queue-pattern 'test-queue-%d' --queue-pattern-from 1 --queue-pattern-to 1 \
       --producers 1 --consumers 1 \
       --uri ${CONNECTION_STRING} \
       --flag persistent --rate 1
   ```

   If you receive an `ACCESS_REFUSED` error, you can troubleshoot your configuration settings by using the CloudWatch logs for your broker. You can find the link for the CloudWatch Logs log group for your broker in the Amazon MQ console.

# Using LDAP authentication and authorization for Amazon MQ for RabbitMQ
<a name="rabbitmq-ldap-tutorial"></a>

This tutorial describes how to configure LDAP authentication and authorization for your Amazon MQ for RabbitMQ brokers using AWS Managed Microsoft AD.

**Topics**
+ [Prerequisites to configure LDAP authentication and authorization](#rabbitmq-ldap-tutorial-prerequisites)
+ [Configuring LDAP in RabbitMQ using AWS CLI](#rabbitmq-ldap-tutorial-configure-cli)

## Prerequisites to configure LDAP authentication and authorization
<a name="rabbitmq-ldap-tutorial-prerequisites"></a>

You can set up the AWS resources required in this tutorial by deploying the [AWS CDK stack for Amazon MQ for RabbitMQ LDAP integration with AWS Managed Microsoft AD](https://github.com/aws-samples/amazon-mq-samples/blob/main/rabbitmq-samples/rabbitmq-ldap-activedirectory-sample/).

This CDK stack automatically creates all the necessary AWS resources including AWS Managed Microsoft AD, LDAP users and groups, Network Load Balancer, certificates, and IAM roles. See the package README for a complete list of resources created by the stack.

If you're setting up the resources manually instead of using the CDK stack, ensure you have the equivalent infrastructure in place before configuring LDAP on your Amazon MQ for RabbitMQ brokers.

### Prerequisite to set up Amazon MQ
<a name="rabbitmq-ldap-tutorial-prerequisite-cli"></a>

AWS CLI version >= 2.28.23 to make adding a username and password optional during broker creation.

## Configuring LDAP in RabbitMQ using AWS CLI
<a name="rabbitmq-ldap-tutorial-configure-cli"></a>

This procedure uses AWS CLI to create and configure the necessary resources. In the following procedure, make sure to replace the placeholder values, such as configurationID and Revision, `<c-fa3390a5-7e01-4559-ae0c-eb15b38b22ca>` and `<2>`, with their actual values.

1. Create a new configuration using the `create-configuration` AWS CLI command as shown in the following example.

   ```
   aws mq create-configuration \
     --name "rabbitmq-ldap-config" \
     --engine-type "RABBITMQ" \
     --engine-version "3.13"
   ```

   This command returns a response similar to the following example.

   ```
   {
   "Arn": "arn:aws:mq:us-west-2:123456789012:configuration:c-fa3390a5-7e01-4559-ae0c-eb15b38b22ca",
       "AuthenticationStrategy": "simple",
       "Created": "2025-07-17T16:03:01.759943+00:00",
       "Id": "c-fa3390a5-7e01-4559-ae0c-eb15b38b22ca",
       "LatestRevision": {
   "Created": "2025-07-17T16:03:01.759000+00:00",
       "Description": "Auto-generated default for rabbitmq-ldap-config on RabbitMQ 3.13",
       "Revision": 1
       },
       "Name": "rabbitmq-ldap-config"
   }
   ```

1. Create a configuration file called `rabbitmq.conf` to use LDAP as the authentication and authorization method, as shown in the following example. Replace all placeholder values in the template (marked with `${RabbitMqLdapTestStack.*}`) with actual values from your deployed AWS CDK prerequisite stack outputs or equivalent infrastructure.

   ```
   auth_backends.1 = ldap
   
   # LDAP authentication settings - For more information,
   # see https://www.rabbitmq.com/docs/ldap#basic
   
   # FIXME: Replace the ${RabbitMqLdapTestStack.*} placeholders with actual values
   # from your deployed prerequisite CDK stack outputs.
   auth_ldap.servers.1 = ${RabbitMqLdapTestStack.NlbDnsName}
   auth_ldap.dn_lookup_bind.user_dn = ${RabbitMqLdapTestStack.DnLookupUserDn}
   auth_ldap.dn_lookup_base = ${RabbitMqLdapTestStack.DnLookupBase}
   auth_ldap.dn_lookup_attribute = ${RabbitMqLdapTestStack.DnLookupAttribute}
   auth_ldap.port = 636
   auth_ldap.use_ssl = true
   auth_ldap.ssl_options.verify = verify_peer
   auth_ldap.log = network
   
   # AWS integration for secure credential retrieval
   # - see: https://github.com/amazon-mq/rabbitmq-aws
   # The aws plugin allows RabbitMQ to securely retrieve credentials and certificates
   # from AWS services.
   
   # Replace the ${RabbitMqLdapTestStack.*} placeholders with actual ARN values
   # from your deployed prerequisite CDK stack outputs.
   aws.arns.auth_ldap.ssl_options.cacertfile = ${RabbitMqLdapTestStack.CaCertArn}
   aws.arns.auth_ldap.dn_lookup_bind.password = ${RabbitMqLdapTestStack.DnLookupUserPasswordArn}
   aws.arns.assume_role_arn = ${RabbitMqLdapTestStack.AmazonMqAssumeRoleArn}
   
   # LDAP authorization queries - For more information,
   # see: https://www.rabbitmq.com/docs/ldap#authorisation
   
   # FIXME: Replace the ${RabbitMqLdapTestStack.*} placeholders with actual group DN
   # values from your deployed prerequisite CDK stack outputs
   # Uses Active Directory groups created by the prerequisite CDK stack
   auth_ldap.queries.tags = '''
   [{administrator, {in_group, "${RabbitMqLdapTestStack.RabbitMqAdministratorsGroupDn}"}},
   {management,    {in_group, "${RabbitMqLdapTestStack.RabbitMqMonitoringUsersGroupDn}"}}]
   '''
   
   # FIXME: This provides all authenticated users access to all vhosts
   # - update to restrict access as required
   auth_ldap.queries.vhost_access = '''
   {constant, true}
   '''
   
   # FIXME: This provides all authenticated users full access to all
   # queues and exchanges - update to restrict access as required
   auth_ldap.queries.resource_access = '''
   {for, [    {permission, configure, {constant, true}},
        {permission, write,
         {for, [{resource, queue,    {constant, true}},
                {resource, exchange, {constant, true}}]}},
        {permission, read,
         {for, [{resource, exchange, {constant, true}},
                {resource, queue,    {constant, true}}]}}
       ]
   }
   '''
   
   # FIXME: This provides all authenticated users access to all topics
   # - update to restrict access as required
   auth_ldap.queries.topic_access = '''
   {for, [{permission, write, {constant, true}},
        {permission, read,  {constant, true}}
       ]
   }
   '''
   ```

1. Update the configuration using the `update-configuration` AWS CLI command as shown in the following example. In this command, add the configuration ID you received in the response of Step 1 of this procedure. For example, `c-fa3390a5-7e01-4559-ae0c-eb15b38b22ca`.

   ```
   aws mq update-configuration \
     --configuration-id "<c-fa3390a5-7e01-4559-ae0c-eb15b38b22ca>" \
     --data "$(cat rabbitmq.conf | base64 --wrap=0)"
   ```

   This command returns a response similar to the following example.

   ```
   {
       "Arn": "arn:aws:mq:us-west-2:123456789012:configuration:c-b600ac8e-8183-4f74-a713-983e59f30e3d",
       "Created": "2025-07-17T16:57:04.520931+00:00",
       "Id": "c-b600ac8e-8183-4f74-a713-983e59f30e3d",
       "LatestRevision": {
           "Created": "2025-07-17T16:57:39.172000+00:00",
           "Revision": 2
       },
       "Name": "rabbitmq-ldap-config",
       "Warnings": []
   }
   ```

1. Create a broker with the LDAP configuration you created in the Step 2 of this procedure. To do this, use the `create-broker` AWS CLI command as shown in the following example. In this command, provide the configuration ID and revision number you obtained in the responses of Step 1 and 2 respectively. For example, `c-fa3390a5-7e01-4559-ae0c-eb15b38b22ca` and `2`.

   ```
   aws mq create-broker \
    --broker-name "rabbitmq-ldap-test-1" \
    --engine-type "RABBITMQ" \
    --engine-version "3.13" \
    --host-instance-type "mq.m7g.large" \
    --deployment-mode "CLUSTER_MULTI_AZ" \
    --logs '{"General": true}' \
    --publicly-accessible \
    --configuration '{"Id": "<c-fa3390a5-7e01-4559-ae0c-eb15b38b22ca>","Revision": <2>}'
   ```

   This command returns a response similar to the following example.

   ```
   {
       "BrokerArn": "arn:aws:mq:us-west-2:123456789012:broker:rabbitmq-ldap-broker:b-2a1b5133-a10c-49d2-879b-8c176c34cf73",
       "BrokerId": "b-2a1b5133-a10c-49d2-879b-8c176c34cf73"
   }
   ```
**Broker naming restriction**  
The IAM role created by the prerequisite CDK stack restricts broker names to start with `rabbitmq-ldap-test`. Ensure your broker name follows this pattern or the IAM role will not have permission to assume the role for ARN resolution.

1. Verify that the broker's status transitions from `CREATION_IN_PROGRESS` to `RUNNING`, using the `describe-broker` AWS CLI command as shown in the following example. In this command, provide the broker ID you obtained in the result of the previous step For example, `b-2a1b5133-a10c-49d2-879b-8c176c34cf73`.

   ```
   aws mq describe-broker \
    --broker-id "<b-2a1b5133-a10c-49d2-879b-8c176c34cf73>"
   ```

   This command returns a response similar to the following example. The following response is an abbreviated version of the complete output that the `describe-broker` command returns. This response shows the broker status and the authentication strategy used to secure the broker. In this case, the `config_managed` authentication strategy indicates that the broker uses LDAP authentication method.

   ```
   {
   "AuthenticationStrategy": "config_managed",
       ...,
       "BrokerState": "RUNNING",
       ...
   }
   ```

1. Validate RabbitMQ access using one of the test users created by the prerequisite CDK stack

   ```
   # FIXME: Replace ${RabbitMqLdapTestStack.ConsoleUserPasswordArn} with the actual ARN from your deployed prerequisite CDK stack outputs
   CONSOLE_PASSWORD=$(aws secretsmanager get-secret-value \
     --secret-id ${RabbitMqLdapTestStack.ConsoleUserPasswordArn} \
     --query 'SecretString' --output text)
   
   # FIXME: Replace BrokerConsoleURL with the actual ConsoleURL retrieved by
   # calling describe-broker for the broker created above
   # Call management API /api/overview (should succeed)
   curl -u RabbitMqConsoleUser:$CONSOLE_PASSWORD \
     https://${BrokerConsoleURL}/api/overview
   
   # Try to create a user (should fail - console user only has monitoring permissions)
   curl -u RabbitMqConsoleUser:$CONSOLE_PASSWORD \
     -X PUT https://${BrokerConsoleURL}/api/users/testuser \
     -H "Content-Type: application/json" \
     -d '{"password":"testpass","tags":"management"}'
   ```

# Using HTTP authentication and authorization for Amazon MQ for RabbitMQ
<a name="rabbitmq-http-tutorial"></a>

This tutorial describes how to configure HTTP authentication and authorization for your Amazon MQ for RabbitMQ brokers using an external HTTP server.

**Note**  
The HTTP authentication plugin is only available for Amazon MQ for RabbitMQ version 4 and above.

**Topics**
+ [Prerequisites to configure HTTP authentication and authorization](#rabbitmq-http-tutorial-prerequisites)
+ [Configuring HTTP authentication in RabbitMQ using AWS CLI](#rabbitmq-http-tutorial-configure-cli)

## Prerequisites to configure HTTP authentication and authorization
<a name="rabbitmq-http-tutorial-prerequisites"></a>

You can set up the AWS resources required in this tutorial by deploying the [AWS CDK stack for Amazon MQ for RabbitMQ HTTP authentication integration](https://github.com/aws-samples/amazon-mq-samples/blob/main/rabbitmq-samples/rabbitmq-http-sample/).

This CDK stack automatically creates all the necessary AWS resources including the HTTP authentication server, certificates, and IAM roles. See the package README for a complete list of resources created by the stack.

If you're setting up the resources manually instead of using the CDK stack, ensure you have the equivalent infrastructure in place before configuring HTTP authentication on your Amazon MQ for RabbitMQ brokers.

### Prerequisite to set up Amazon MQ
<a name="rabbitmq-http-tutorial-prerequisite-cli"></a>

AWS CLI version >= 2.28.23 to make adding a username and password optional during broker creation.

## Configuring HTTP authentication in RabbitMQ using AWS CLI
<a name="rabbitmq-http-tutorial-configure-cli"></a>

This procedure uses AWS CLI to create and configure the necessary resources. In the following procedure, make sure to replace the placeholder values with their actual values.

1. Create a new configuration using the `create-configuration` AWS CLI command as shown in the following example.

   ```
   aws mq create-configuration \
     --name "rabbitmq-http-config" \
     --engine-type "RABBITMQ" \
     --engine-version "4.2"
   ```

   This command returns a response similar to the following example.

   ```
   {
       "Arn": "arn:aws:mq:us-west-2:123456789012:configuration:c-fa3390a5-7e01-4559-ae0c-eb15b38b22ca",
       "AuthenticationStrategy": "simple",
       "Created": "2025-07-17T16:03:01.759943+00:00",
       "Id": "c-fa3390a5-7e01-4559-ae0c-eb15b38b22ca",
       "LatestRevision": {
           "Created": "2025-07-17T16:03:01.759000+00:00",
           "Description": "Auto-generated default for rabbitmq-http-config on RabbitMQ 4.2",
           "Revision": 1
       },
       "Name": "rabbitmq-http-config"
   }
   ```

1. Create a configuration file called `rabbitmq.conf` to use HTTP as the authentication and authorization method, as shown in the following example. Replace all placeholder values in the template (marked with `${...}`) with actual values from your deployed AWS CDK prerequisite stack outputs or equivalent infrastructure.

   ```
   auth_backends.1 = cache
   auth_backends.2 = http
   auth_cache.cached_backend = http
   
   # HTTP authentication settings
   # For more information, see https://github.com/rabbitmq/rabbitmq-auth-backend-http
   
   # FIXME: Replace the ${...} placeholders with actual values
   # from your deployed prerequisite CDK stack outputs.
   auth_http.http_method = post
   auth_http.user_path = ${HttpServerUserPath}
   auth_http.vhost_path = ${HttpServerVhostPath}
   auth_http.resource_path = ${HttpServerResourcePath}
   auth_http.topic_path = ${HttpServerTopicPath}
   
   # TLS/HTTPS configuration
   auth_http.ssl_options.verify = verify_peer
   auth_http.ssl_options.sni = test.amazonaws.com
   
   # AWS integration for secure credential retrieval
   # For more information, see https://github.com/amazon-mq/rabbitmq-aws
   
   # Replace the ${...} placeholders with actual ARN values
   # from your deployed prerequisite CDK stack outputs.
   aws.arns.assume_role_arn = ${AmazonMqAssumeRoleArn}
   aws.arns.auth_http.ssl_options.cacertfile = ${CaCertArn}
   ```

1. Update the configuration using the `update-configuration` AWS CLI command. Use the configuration ID from Step 3.

   ```
   aws mq update-configuration \
     --configuration-id "<c-fa3390a5-7e01-4559-ae0c-eb15b38b22ca>" \
     --data "$(cat rabbitmq.conf | base64 --wrap=0)"
   ```

   This command returns a response similar to the following example.

   ```
   {
       "Arn": "arn:aws:mq:us-west-2:123456789012:configuration:c-fa3390a5-7e01-4559-ae0c-eb15b38b22ca",
       "Created": "2025-07-17T16:57:04.520931+00:00",
       "Id": "c-fa3390a5-7e01-4559-ae0c-eb15b38b22ca",
       "LatestRevision": {
           "Created": "2025-07-17T16:57:39.172000+00:00",
           "Revision": 2
       },
       "Name": "rabbitmq-http-config",
       "Warnings": []
   }
   ```

1. Create a broker with the HTTP configuration. Use the configuration ID and revision number from the previous steps.

   ```
   aws mq create-broker \
     --broker-name "rabbitmq-http-test-1" \
     --engine-type "RABBITMQ" \
     --engine-version "4.2" \
     --host-instance-type "mq.m7g.large" \
     --deployment-mode "SINGLE_INSTANCE" \
     --logs '{"General": true}' \
     --publicly-accessible \
     --configuration '{"Id": "<c-fa3390a5-7e01-4559-ae0c-eb15b38b22ca>","Revision": <2>}'
   ```

   This command returns a response similar to the following example.

   ```
   {
       "BrokerArn": "arn:aws:mq:us-west-2:123456789012:broker:rabbitmq-http-test-1:b-2a1b5133-a10c-49d2-879b-8c176c34cf73",
       "BrokerId": "b-2a1b5133-a10c-49d2-879b-8c176c34cf73"
   }
   ```

1. Verify that the broker's status transitions from `CREATION_IN_PROGRESS` to `RUNNING`, using the `describe-broker` AWS CLI command.

   ```
   aws mq describe-broker \
     --broker-id "<b-2a1b5133-a10c-49d2-879b-8c176c34cf73>"
   ```

   This command returns a response similar to the following example. The `config_managed` authentication strategy indicates that the broker uses HTTP authentication method.

   ```
   {
       "AuthenticationStrategy": "config_managed",
       ...,
       "BrokerState": "RUNNING",
       ...
   }
   ```

1. Validate RabbitMQ access using one of the test users created by the prerequisite CDK stack

   ```
   # FIXME: Replace ${RabbitMqHttpAuthElbStack.ConsoleUserPasswordArn} with the actual ARN from your deployed prerequisite CDK stack outputs
   CONSOLE_PASSWORD=$(aws secretsmanager get-secret-value \
     --secret-id ${RabbitMqHttpAuthElbStack.ConsoleUserPasswordArn} \
     --query 'SecretString' --output text)
   
   # FIXME: Replace BrokerConsoleURL with the actual ConsoleURL retrieved by
   # calling describe-broker for the broker created above
   # Call management API /api/overview (should succeed)
   curl -u RabbitMqConsoleUser:$CONSOLE_PASSWORD \
     https://${BrokerConsoleURL}/api/overview
   
   # Try to create a vhost (should fail - console user only has management permissions)
   curl -u RabbitMqConsoleUser:$CONSOLE_PASSWORD \
     -X PUT https://${BrokerConsoleURL}/api/vhosts/test-vhost \
     -H "Content-Type: application/json" \
     -d '{}'
   ```

# Using SSL certificate authentication for Amazon MQ for RabbitMQ
<a name="rabbitmq-ssl-tutorial"></a>

This tutorial describes how to configure SSL certificate authentication for your Amazon MQ for RabbitMQ brokers using a private certificate authority.

**Note**  
The SSL certificate authentication plugin is only available for Amazon MQ for RabbitMQ version 4 and above.

**Topics**
+ [Prerequisites to configure SSL certificate authentication](#rabbitmq-ssl-tutorial-prerequisites)
+ [Configuring SSL certificate authentication in RabbitMQ using AWS CLI](#rabbitmq-ssl-tutorial-configure-cli)

## Prerequisites to configure SSL certificate authentication
<a name="rabbitmq-ssl-tutorial-prerequisites"></a>

SSL certificate authentication uses mutual TLS (mTLS) to authenticate clients using X.509 certificates. You can set up the AWS resources required in this tutorial by deploying the [AWS CDK stack for Amazon MQ for RabbitMQ mTLS integration](https://github.com/aws-samples/amazon-mq-samples/blob/main/rabbitmq-samples/rabbitmq-mtls-sample/).

This CDK stack automatically creates all the necessary AWS resources including certificate authority, client certificates, and IAM roles. See the package README for a complete list of resources created by the stack.

**Note**  
Before deploying the CDK stack, set the `RABBITMQ_TEST_USER_NAME` environment variable. This value will be used as the Common Name (CN) in the client certificate and must match the username you use in the tutorial steps. For example: `export RABBITMQ_TEST_USER_NAME="myuser"`

If you're setting up the resources manually instead of using the CDK stack, ensure you have the equivalent infrastructure in place before configuring SSL certificate authentication on your Amazon MQ for RabbitMQ brokers.

### Prerequisite to set up Amazon MQ
<a name="rabbitmq-ssl-tutorial-prerequisite-cli"></a>

AWS CLI version >= 2.28.23 to make adding a username and password optional during broker creation.

## Configuring SSL certificate authentication in RabbitMQ using AWS CLI
<a name="rabbitmq-ssl-tutorial-configure-cli"></a>

This procedure uses AWS CLI to create and configure the necessary resources. In the following procedure, make sure to replace the placeholder values, such as configurationID and Revision, `<c-fa3390a5-7e01-4559-ae0c-eb15b38b22ca>` and `<2>`, with their actual values.

1. Create a new configuration using the `create-configuration` AWS CLI command as shown in the following example.

   ```
   aws mq create-configuration \
     --name "rabbitmq-ssl-config" \
     --engine-type "RABBITMQ" \
     --engine-version "4.2"
   ```

   This command returns a response similar to the following example.

   ```
   {
       "Arn": "arn:aws:mq:us-west-2:123456789012:configuration:c-fa3390a5-7e01-4559-ae0c-eb15b38b22ca",
       "AuthenticationStrategy": "simple",
       "Created": "2025-07-17T16:03:01.759943+00:00",
       "Id": "c-fa3390a5-7e01-4559-ae0c-eb15b38b22ca",
       "LatestRevision": {
           "Created": "2025-07-17T16:03:01.759000+00:00",
           "Description": "Auto-generated default for rabbitmq-ssl-config on RabbitMQ 4.2",
           "Revision": 1
       },
       "Name": "rabbitmq-ssl-config"
   }
   ```

1. Create a configuration file called `rabbitmq.conf` to use SSL certificate authentication, as shown in the following example. Replace all placeholder values in the template (marked with `${...}`) with actual values from your deployed AWS CDK prerequisite stack outputs or equivalent infrastructure.

   ```
   auth_mechanisms.1 = EXTERNAL
   ssl_cert_login_from = common_name
   
   auth_backends.1 = internal
   
   # Reject if no client cert
   ssl_options.verify = verify_peer
   ssl_options.fail_if_no_peer_cert = true
   
   # AWS integration for secure credential retrieval
   # For more information, see https://github.com/amazon-mq/rabbitmq-aws
   
   # FIXME: Replace the ${...} placeholders with actual ARN values
   # from your deployed prerequisite CDK stack outputs.
   aws.arns.assume_role_arn = ${AmazonMqAssumeRoleArn}
   aws.arns.ssl_options.cacertfile = ${CaCertArn}
   ```

1. Update the configuration using the `update-configuration` AWS CLI command as shown in the following example. In this command, add the configuration ID you received in the response of Step 1 of this procedure. For example, `c-fa3390a5-7e01-4559-ae0c-eb15b38b22ca`.

   ```
   aws mq update-configuration \
     --configuration-id "<c-fa3390a5-7e01-4559-ae0c-eb15b38b22ca>" \
     --data "$(cat rabbitmq.conf | base64 --wrap=0)"
   ```

   This command returns a response similar to the following example.

   ```
   {
       "Arn": "arn:aws:mq:us-west-2:123456789012:configuration:c-fa3390a5-7e01-4559-ae0c-eb15b38b22ca",
       "Created": "2025-07-17T16:57:04.520931+00:00",
       "Id": "c-fa3390a5-7e01-4559-ae0c-eb15b38b22ca",
       "LatestRevision": {
           "Created": "2025-07-17T16:57:39.172000+00:00",
           "Revision": 2
       },
       "Name": "rabbitmq-ssl-config",
       "Warnings": []
   }
   ```

1. Create a broker with the SSL certificate authentication configuration you created in Step 2 of this procedure. To do this, use the `create-broker` AWS CLI command as shown in the following example. In this command, provide the configuration ID and revision number you obtained in the responses of Step 1 and 2 respectively. For example, `c-fa3390a5-7e01-4559-ae0c-eb15b38b22ca` and `2`.

   ```
   aws mq create-broker \
     --broker-name "rabbitmq-ssl-test-1" \
     --engine-type "RABBITMQ" \
     --engine-version "4.2" \
     --host-instance-type "mq.m7g.large" \
     --deployment-mode "SINGLE_INSTANCE" \
     --logs '{"General": true}' \
     --publicly-accessible \
     --configuration '{"Id": "<c-fa3390a5-7e01-4559-ae0c-eb15b38b22ca>","Revision": <2>}' \
     --users '[{"Username":"testuser","Password":"testpassword"}]'
   ```

   This command returns a response similar to the following example.

   ```
   {
       "BrokerArn": "arn:aws:mq:us-west-2:123456789012:broker:rabbitmq-ssl-test-1:b-2a1b5133-a10c-49d2-879b-8c176c34cf73",
       "BrokerId": "b-2a1b5133-a10c-49d2-879b-8c176c34cf73"
   }
   ```

1. Verify that the broker's status transitions from `CREATION_IN_PROGRESS` to `RUNNING`, using the `describe-broker` AWS CLI command as shown in the following example. In this command, provide the broker ID you obtained in the result of the previous step. For example, `b-2a1b5133-a10c-49d2-879b-8c176c34cf73`.

   ```
   aws mq describe-broker \
     --broker-id "<b-2a1b5133-a10c-49d2-879b-8c176c34cf73>"
   ```

   This command returns a response similar to the following example. The following response is an abbreviated version of the complete output that the `describe-broker` command returns. This response shows the broker status and the authentication strategy used to secure the broker. In this case, the `config_managed` authentication strategy indicates that the broker uses SSL certificate authentication method.

   ```
   {
       "AuthenticationStrategy": "config_managed",
       ...,
       "BrokerState": "RUNNING",
       ...
   }
   ```

1. Verify SSL certificate authentication with the following `ssl.sh` script.

   Use this bash script to test connectivity to your Amazon MQ for RabbitMQ broker. This script uses your client certificate for authentication and verifies if the connection was properly configured. If it's successfully configured, you'll see your broker publish and consume messages.

   If you receive an `ACCESS_REFUSED` error, you can troubleshoot your configuration settings by using the CloudWatch logs for your broker. You can find the link for the CloudWatch log group for your broker in the Amazon MQ console.

   In this script, you'll need to provide the following values:
   + `USERNAME`: The common name (CN) from your client certificate.
   + `CLIENT_KEYSTORE`: Path to your client keystore file (PKCS12 format). If you used the prerequisite CDK stack, the default path is `$(pwd)/certs/client-keystore.p12`.
   + `KEYSTORE_PASSWORD`: Password for your client keystore. If you used the prerequisite CDK stack, the default password is `changeit`.
   + `BROKER_DNS`: You can find this value under **Connections** on the broker details page of the Amazon MQ console.

   ```
   #! /bin/bash
   set -e
   
   # Client information
   ## FIXME: Update this value with the client ID and secret of your confidential application client
   USERNAME=<client_cert_common_name>
   CLIENT_KEYSTORE=$(pwd)/certs/client-keystore.p12
   KEYSTORE_PASSWORD=changeit
   
   BROKER_DNS=<broker_dns>
   CONNECTION_STRING=amqps://${BROKER_DNS}:5671 
   
   # Produce/consume messages using the above connection string
   QUEUES_COUNT=1
   PRODUCERS_COUNT=1
   CONSUMERS_COUNT=1
   PRODUCER_RATE=1
   
   finch run --rm --ulimit nofile=40960:40960 \
       -v ${CLIENT_KEYSTORE}:/certs/client-keystore.p12:ro \
       -e JAVA_TOOL_OPTIONS="-Djavax.net.ssl.keyStore=/certs/client-keystore.p12 -Djavax.net.ssl.keyStorePassword=${KEYSTORE_PASSWORD} -Djavax.net.ssl.keyStoreType=PKCS12" \
       pivotalrabbitmq/perf-test:latest \
       --queue-pattern 'test-queue-cert-%d' --queue-pattern-from 1 --queue-pattern-to $QUEUES_COUNT \
       --producers $PRODUCERS_COUNT --consumers $CONSUMERS_COUNT \
       --id "cert-test${QUEUES_COUNT}q${PRODUCERS_COUNT}p${CONSUMERS_COUNT}c${PRODUCER_RATE}r" \
       --uri ${CONNECTION_STRING} \
       --sasl-external \
       --use-default-ssl-context \
       --flag persistent --rate $PRODUCER_RATE
   ```

# Using mTLS for AMQP and management endpoints
<a name="rabbitmq-mtls-tutorial"></a>

This tutorial describes how to configure mutual TLS (mTLS) for AMQP client connections and the RabbitMQ management interface using a private certificate authority.

**Note**  
The use of private certificate authorities for mTLS is only available for Amazon MQ for RabbitMQ version 4 and above.

**Topics**
+ [Prerequisites to configure mTLS](#rabbitmq-mtls-tutorial-prerequisites)
+ [Configuring mTLS in RabbitMQ using AWS CLI](#rabbitmq-mtls-tutorial-configure-cli)

## Prerequisites to configure mTLS
<a name="rabbitmq-mtls-tutorial-prerequisites"></a>

You can set up the AWS resources required in this tutorial by deploying the [AWS CDK stack for Amazon MQ for RabbitMQ mTLS integration with ](https://github.com/aws-samples/amazon-mq-samples/blob/main/rabbitmq-samples/rabbitmq-mtls-sample/).

This CDK stack automatically creates all the necessary AWS resources including certificate authority, client certificates, and IAM roles. See the package README for a complete list of resources created by the stack.

If you're setting up the resources manually instead of using the CDK stack, ensure you have the equivalent infrastructure in place before configuring mTLS on your Amazon MQ for RabbitMQ brokers.

### Prerequisite to set up Amazon MQ
<a name="rabbitmq-mtls-tutorial-prerequisite-cli"></a>

AWS CLI version >= 2.28.23 to make adding a username and password optional during broker creation.

## Configuring mTLS in RabbitMQ using AWS CLI
<a name="rabbitmq-mtls-tutorial-configure-cli"></a>

This procedure uses AWS CLI to create and configure the necessary resources. In the following procedure, make sure to replace the placeholder values, such as configurationID and Revision, `<c-fa3390a5-7e01-4559-ae0c-eb15b38b22ca>` and `<2>`, with their actual values.

1. Create a new configuration using the `create-configuration` AWS CLI command as shown in the following example.

   ```
   aws mq create-configuration \
     --name "rabbitmq-mtls-config" \
     --engine-type "RABBITMQ" \
     --engine-version "4.2"
   ```

   This command returns a response similar to the following example.

   ```
   {
       "Arn": "arn:aws:mq:us-west-2:123456789012:configuration:c-fa3390a5-7e01-4559-ae0c-eb15b38b22ca",
       "AuthenticationStrategy": "simple",
       "Created": "2025-07-17T16:03:01.759943+00:00",
       "Id": "c-fa3390a5-7e01-4559-ae0c-eb15b38b22ca",
       "LatestRevision": {
           "Created": "2025-07-17T16:03:01.759000+00:00",
           "Description": "Auto-generated default for rabbitmq-mtls-config on RabbitMQ 4.2",
           "Revision": 1
       },
       "Name": "rabbitmq-mtls-config"
   }
   ```

1. Create a configuration file called `rabbitmq.conf` to configure mTLS for AMQP and management endpoints, as shown in the following example. Replace all placeholder values in the template (marked with `${...}`) with actual values from your deployed AWS CDK prerequisite stack outputs or equivalent infrastructure.

   ```
   auth_backends.1 = internal
   
   # TLS configuration
   ssl_options.verify = verify_peer
   ssl_options.fail_if_no_peer_cert = true
   management.ssl.verify = verify_peer
   
   # AWS integration for secure credential retrieval
   # For more information, see https://github.com/amazon-mq/rabbitmq-aws
   
   # FIXME: Replace the ${...} placeholders with actual ARN values
   # from your deployed prerequisite CDK stack outputs.
   aws.arns.assume_role_arn = ${AmazonMqAssumeRoleArn}
   aws.arns.ssl_options.cacertfile = ${CaCertArn}
   aws.arns.management.ssl.cacertfile = ${CaCertArn}
   ```

1. Update the configuration using the `update-configuration` AWS CLI command as shown in the following example. In this command, add the configuration ID you received in the response of Step 1 of this procedure. For example, `c-fa3390a5-7e01-4559-ae0c-eb15b38b22ca`.

   ```
   aws mq update-configuration \
     --configuration-id "<c-fa3390a5-7e01-4559-ae0c-eb15b38b22ca>" \
     --data "$(cat rabbitmq.conf | base64 --wrap=0)"
   ```

   This command returns a response similar to the following example.

   ```
   {
       "Arn": "arn:aws:mq:us-west-2:123456789012:configuration:c-fa3390a5-7e01-4559-ae0c-eb15b38b22ca",
       "Created": "2025-07-17T16:57:04.520931+00:00",
       "Id": "c-fa3390a5-7e01-4559-ae0c-eb15b38b22ca",
       "LatestRevision": {
           "Created": "2025-07-17T16:57:39.172000+00:00",
           "Revision": 2
       },
       "Name": "rabbitmq-mtls-config",
       "Warnings": []
   }
   ```

1. Create a broker with the mTLS configuration you created in Step 2 of this procedure. To do this, use the `create-broker` AWS CLI command as shown in the following example. In this command, provide the configuration ID and revision number you obtained in the responses of Step 1 and 2 respectively. For example, `c-fa3390a5-7e01-4559-ae0c-eb15b38b22ca` and `2`.

   ```
   aws mq create-broker \
     --broker-name "rabbitmq-mtls-test-1" \
     --engine-type "RABBITMQ" \
     --engine-version "4.2" \
     --host-instance-type "mq.m7g.large" \
     --deployment-mode "SINGLE_INSTANCE" \
     --logs '{"General": true}' \
     --publicly-accessible \
     --configuration '{"Id": "<c-fa3390a5-7e01-4559-ae0c-eb15b38b22ca>","Revision": <2>}' \
     --users '[{"Username":"testuser","Password":"testpassword"}]'
   ```

   This command returns a response similar to the following example.

   ```
   {
       "BrokerArn": "arn:aws:mq:us-west-2:123456789012:broker:rabbitmq-mtls-test-1:b-2a1b5133-a10c-49d2-879b-8c176c34cf73",
       "BrokerId": "b-2a1b5133-a10c-49d2-879b-8c176c34cf73"
   }
   ```

1. Verify that the broker's status transitions from `CREATION_IN_PROGRESS` to `RUNNING`, using the `describe-broker` AWS CLI command as shown in the following example. In this command, provide the broker ID you obtained in the result of the previous step. For example, `b-2a1b5133-a10c-49d2-879b-8c176c34cf73`.

   ```
   aws mq describe-broker \
     --broker-id "<b-2a1b5133-a10c-49d2-879b-8c176c34cf73>"
   ```

   This command returns a response similar to the following example. The following response is an abbreviated version of the complete output that the `describe-broker` command returns.

   ```
   {
       "AuthenticationStrategy": "simple",
       ...,
       "BrokerState": "RUNNING",
       ...
   }
   ```

1. Verify mTLS authentication with the following `mtls.sh` script.

   Use this bash script to test connectivity to your Amazon MQ for RabbitMQ broker. This script uses your client certificate to authenticate and verifies if the connection was properly configured. If it's successfully configured, you'll see your broker publish and consume messages.

   If you receive an `ACCESS_REFUSED` error, you can troubleshoot your configuration settings by using the CloudWatch logs for your broker. You can find the link for the CloudWatch log group for your broker in the Amazon MQ console.

   In this script, you'll need to provide the following values:
   + `USERNAME` and `PASSWORD`: The RabbitMQ user credentials you created with the broker.
   + `CLIENT_KEYSTORE`: Path to your client keystore file (PKCS12 format). If you used the prerequisite CDK stack, the default path is `$(pwd)/certs/client-keystore.p12`.
   + `KEYSTORE_PASSWORD`: Password for your client keystore. If you used the prerequisite CDK stack, the default password is `changeit`.
   + `BROKER_DNS`: You can find this value under **Connections** on the broker details page of the Amazon MQ console.

   ```
   #! /bin/bash
   set -e
   
   # Client information
   ## FIXME: Update this value with the client ID and secret of your confidential application client
   USERNAME=<testuser>
   PASSWORD=<testpassword>
   CLIENT_KEYSTORE=$(pwd)/certs/client-keystore.p12
   KEYSTORE_PASSWORD=changeit
   
   BROKER_DNS=<broker_dns>
   CONNECTION_STRING=amqps://${USERNAME}:${PASSWORD}@${BROKER_DNS}:5671 
   
   # Produce/consume messages using the above connection string
   QUEUES_COUNT=1
   PRODUCERS_COUNT=1
   CONSUMERS_COUNT=1
   PRODUCER_RATE=1
   
   finch run --rm --ulimit nofile=40960:40960 \
       -v ${CLIENT_KEYSTORE}:/certs/client-keystore.p12:ro \
       -e JAVA_TOOL_OPTIONS="-Djavax.net.ssl.keyStore=/certs/client-keystore.p12 -Djavax.net.ssl.keyStorePassword=${KEYSTORE_PASSWORD} -Djavax.net.ssl.keyStoreType=PKCS12" \
       pivotalrabbitmq/perf-test:latest \
       --queue-pattern 'test-queue-cert-%d' --queue-pattern-from 1 --queue-pattern-to $QUEUES_COUNT \
       --producers $PRODUCERS_COUNT --consumers $CONSUMERS_COUNT \
       --id "cert-test${QUEUES_COUNT}q${PRODUCERS_COUNT}p${CONSUMERS_COUNT}c${PRODUCER_RATE}r" \
       --uri ${CONNECTION_STRING} \
       --use-default-ssl-context \
       --flag persistent --rate $PRODUCER_RATE
   ```

# Connecting your JMS application
<a name="rabbitmq-tutorial-jms"></a>

 This tutorial shows you how to connect your JMS application to Amazon MQ for RabbitMQ broker using the RabbitMQ JMS client. You will learn how to create a producer to send messages and a consumer to receive messages from RabbitMQ queues. 

 Before you begin, add the appropriate RabbitMQ JMS dependency to your Maven project: 

 For JMS 1.1 and 2.0: 

```
<dependencies>

  <dependency>
    <groupId>com.rabbitmq.jms</groupId>
    <artifactId>rabbitmq-jms</artifactId>
    <version>2.12.0</version>
  </dependency>

</dependencies>
```

 For JMS 3.1: 

```
<dependencies>

  <dependency>
    <groupId>com.rabbitmq.jms</groupId>
    <artifactId>rabbitmq-jms</artifactId>
    <version>3.5.0</version>
  </dependency>

</dependencies>
```

## Create a producer
<a name="rabbitmq-tutorial-jms-producer"></a>

 The following code example shows how to write to a RabbitMQ queue using JMS: 

```
import jakarta.jms.*;
import com.rabbitmq.jms.admin.*;

// Setting the connection factory
RMQConnectionFactory factory = new RMQConnectionFactory();
factory.setHost(envProps.getProperty("RABBITMQ_HOST", "localhost"));
factory.setPort(Integer.parseInt(envProps.getProperty("RABBITMQ_PORT", "5672")));
factory.setUsername(envProps.getProperty("RABBITMQ_USERNAME", "guest"));
factory.setPassword(envProps.getProperty("RABBITMQ_PASSWORD", "guest"));
factory.setVirtualHost(envProps.getProperty("RABBITMQ_VIRTUAL_HOST", "/"));
factory.useSslProtocol();

connection = factory.createConnection();
connection.start();

String queueName = "test-queue-jms";
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);

RMQDestination destination = new RMQDestination(queueName, true, false);

// Send the message to the queue
MessageProducer producer = session.createProducer(destination);
producer.setDeliveryMode(DeliveryMode.PERSISTENT);

String msg_content = "Hello World!!";
TextMessage textMessage = session.createTextMessage(msg_content);
producer.send(textMessage);

System.out.printf("Published to AMQP queue '%s': %s", queueName, msg_content);
```

## Create a consumer
<a name="rabbitmq-tutorial-jms-consumer"></a>

 The following code example shows how to read from a RabbitMQ queue using JMS: 

```
import jakarta.jms.*;
import com.rabbitmq.jms.admin.*;

// Setting the connection factory
RMQConnectionFactory factory = new RMQConnectionFactory();
factory.setHost(envProps.getProperty("RABBITMQ_HOST", "localhost"));
factory.setPort(Integer.parseInt(envProps.getProperty("RABBITMQ_PORT", "5672")));
factory.setUsername(envProps.getProperty("RABBITMQ_USERNAME", "guest"));
factory.setPassword(envProps.getProperty("RABBITMQ_PASSWORD", "guest"));
factory.setVirtualHost(envProps.getProperty("RABBITMQ_VIRTUAL_HOST", "/"));
factory.useSslProtocol();

// Establish the connection and session
jakarta.jms.Connection connection = factory.createConnection();

String queueName = "test-queue-jms";
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);

RMQDestination destination = new RMQDestination();
destination.setDestinationName(queueName);
destination.setAmqp(true);
destination.setAmqpQueueName(queueName);

// Initialize consumer
MessageConsumer consumer = session.createConsumer(destination);
consumer.setMessageListener(message -> {
    try {
        if (message instanceof TextMessage) {
            TextMessage textMessage = (TextMessage) message;
            System.out.printf("Message: %s%n", textMessage.getText());
        } else if (message instanceof BytesMessage) {
            BytesMessage bytesMessage = (BytesMessage) message;
            byte[] bytes = new byte[(int) bytesMessage.getBodyLength()];
            bytesMessage.readBytes(bytes);
            String content = new String(bytes);
            System.out.printf("Message: %s%n", content);
        } else {
            System.out.printf("Message: [%s]%n", message.getClass().getSimpleName());
        }
    } catch (JMSException e) {
        System.err.printf("Error processing message: %s%n", e.getMessage());
    }
});

connection.start();
```