AWS ActiveMQ Python STOMP Example - with SSL | Devops Junction

In this article, we are going to see how to connect to AWS ActiveMQ using Python.

STOMP ( Simple Text Oriented Messaging Protcol)  is a protocol supported by Message Oriented Middleware products like ActiveMQ, RabbitMQ for faster and reliable message streaming.

We are going to use STOMP with Python to connect to ActiveMQ in this article.

Python provides a library called stomp.py which we will be using to connect to our message broker using the STOMP protocol.

aws activemq

Creating Certificate to present to SSL Stomp connector

Before you can execute the python code from the EC2 instance, there is a requirement we need to address

Remember that AWS ActiveMQ Supports STOMP with SSL

you can see it in the endpoint itself that it would have ssl+stomp

In order to connect to this SSL enabled stomp we must produce a certificate.  So we are now going to create one dummy certificate using OpenSSL

Run the following code on your EC2 instance to generate the privateKey.key and cert.pem required for the SSL connection to ActiveMQ.

openssl req -newkey rsa:2048 -nodes -keyout privateKey.key -x509 -days 365 -out cert.pem

This would create a private key and a certificate that we can produce to the STOMP + SSL enabled AWS ActiveMQ.

Now we have the certificate file and the private key ready. Let us move on to copying the Python code and executing it

Creating AWS ActiveMQ

As we have mentioned already, we are going to use AWS ActiveMQ and our code is going to be deployed on EC2.

So we have given a quick Video how to create a AWS ActiveMQ with Simple Authentication.

 

Now we have created the AWS ActiveMQ with some user and password and now we can create the python program and can use the STOMP host and Port to connect

ActiveMQ AWS

As you can see There are five different type of endpoints available with different protocol support

but we are going with STOMP

 

Python program to connect AWS ActiveMQ

This program is designed to connect to the AWS ActiveMQ using the STOMP protocol.

Before you can use this program, you need to replace the following variables in the python source code given below.

  • AMQHOST - ActiveMQ Stomp Hostname ( stomp+ssl:// removed)
  • AMQPORT - ActiveMQ Stomp port ( usually 61614 or 61613)
  • AMQUSER - ActiveMQ userName that we created
  • AMQPASS - ActiveMQ Password
  • TOPICNAME - ActiveMQ Topic name ( if not exist, it would be created)

During the creation of the broker, we created the username and password which we would use as AMQUSER and AMQPASS.

Copy the following code and create a new file named amq-client.py

Note*: Make sure this python file is created/present on the same directory where we have created the privatekey and certificate pem file

Here is the source code

import time
import sys
import stomp
import ssl


class MsgListener(stomp.ConnectionListener):

    def on_error(self, message):
        print('received an error "%s"' % message.body)
    def on_message(self, frame):
        print('received a message "%s"' % frame.body)


AMQHOST=<YOUR STOMP HOST, WITH NO PROTOCOL SPECIFIED>
AMQPORT=<AMQ STOM PORT - 61614 usually >
AMQUSER=<USERNAME YOU CREATE IN AWS ACTIVEMQ>
AMQPASS=<PASSWORD OF THE USER NAME MENTIONED ABOVE>
TOPICNAME=topic/testtopic

hosts = [(AMQHOST, AMQPORT)]

conn = stomp.Connection(host_and_ports=hosts)
conn.set_listener('stomp_listener', MsgListener())
conn.set_ssl(for_hosts=[(AMQHOST, AMQPORT)], cert_file='cert.pem', key_file='privateKey.key',ssl_version=ssl.PROTOCOL_TLSv1_2)
conn.connect(AMQUSER, AMQPORT, wait=True,headers = {'client-id': 'clientname'})

conn.send(body=' '.join(sys.argv[1:]), destination=TOPICNAME)
time.sleep(320)
conn.subscribe(destination=TOPICNAME, id=1, ack='auto')


conn.disconnect()

Install PIP and Stomp

Now we need to install the Stomp Package on the EC2 instance where we are going to execute the python code.

if you do not have PIP, refer to this page and get it installed

Once the pip is installed and ready. execute the following command to install the stomp

pip install stomp.py

Make sure your EC2 instance has external internet connectivity otherwise you would not be able to install any PyPI packages.

 

Run the Program

Now run the Python program by issuing the following command

python amq-client.py "hello world"

If all goes well you will see your message being published into the topic name you have given and read back by the subscriber/listener we have configured.

 

Secure Alternative with AWS Parameter Store

In the preceding program, you might have seen that we are hardcoding the password and other configuration info

It is not a good practice to keep these secrets hardcoded in the production environment.

So the better alternative is to store these in some Secret Manager like

  • Hashicorp Vault
  • AWS Secret Manager
  • AWS parameter Store

Since we are using the EC2 instance and an AWS ActiveMQ. Let us choose the AWS Vault mechanism

People usually prefer AWS Secret Manager over AWS Parameter Store but we are taking up AWS Parameter Store in this article.

AWS Parameter Store can be a viable solution to store secrets.

In order to use AWS Parameter Store in our program, we need to use boto3 the powerful python SDK to connect to AWS

Now here is the modified python code that uses boto3 to connect and fetch secrets/parameters from the AWS parameter store.

import time
import sys
import stomp
import ssl
import boto3

def read_param(paramname):
    ssm= boto3.client('ssm','us-east-1')
    parameter = ssm.get_parameter(Name=paramname,WithDecryption=True)
    print(parameter['Parameter']['Value'])
    return parameter['Parameter']['Value']

class MsgListener(stomp.ConnectionListener):

    def on_error(self, message):
        print('received an error "%s"' % message.body)
    def on_message(self, frame):
        print('received a message "%s"' % frame.body)


AMQHOST=read_param("AMQ_STOMP_URL")
AMQPORT=read_param("AMQ_STOMP_PORT")
AMQUSER=read_param("AMQ_USERNAME")
AMQPASS=read_param("AMQ_PASSWORD")
TOPICNAME=read_param("AMQ_TOPIC")

hosts = [(AMQHOST, AMQPORT)]

conn = stomp.Connection(host_and_ports=hosts)
conn.set_listener('stomp_listener', MsgListener())
conn.set_ssl(for_hosts=[(AMQHOST, AMQPORT)], cert_file='cert.pem', key_file='privateKey.key',ssl_version=ssl.PROTOCOL_TLSv1_2)
conn.connect(AMQUSER, AMQPORT, wait=True,headers = {'client-id': 'clientname'})

conn.send(body=' '.join(sys.argv[1:]), destination=TOPICNAME)
time.sleep(320)
conn.subscribe(destination=TOPICNAME, id=1, ack='auto')


conn.disconnect()

 

AWS Parameter Store.

Create Parameters using SecureString as the Parameter type. You can also choose other Parameter types but we recommend using SecureString for added security concerns

  • Go to Parameter Store in AWS.
  • Create a Parameter and enter the name.
  • Choose Tier as Standard, Type as SecureString and enter the Value of the Parameter.

Your parameters would look like this:

 

Creating IAM Role and mapping to EC2

As we are going to read the configuration and secrets from the AWS parameter store. We need to make sure that our EC2 instance has the right IAM role/permission to be able to do that.

To create IAM Role which is necessary for this objective, follow the steps:

  • Go to IAM > Roles > Create Role.
  • Select AWS Service as Trusted entity type and EC2 as Use case.
  • Click Next and Add AmazonSSMReadOnlyAccess permission from Permission policies.
  • Provide the Role name and create the role.

Now we have given permission for the Ec2 instance to read Parameters so we are good to test our code now.

 

Run the Program

Run your Python Client to establish the connection to your ActiveMQ Broker using the command:

python <name_of_your_python_client_file.py> "message"

 

Execution output

here is the execution output of the program when tried from our end

ActiveMQ Python

Conclusion

With this article hope you were able to learn how to use ActiveMQ with Python using STOMP protocol

we also covered how securely store and fetch the configuration and credential info from AWS Secret Manager/ Parameter Store using Boto3

If you have any requirement in DevOps where you need our professional help, please do reach out to us at [email protected]

 

 

Co Authored By
Vishnu & Sarav AK

Follow me on Linkedin My Profile
Follow DevopsJunction onFacebook orTwitter
For more practical videos and tutorials. Subscribe to our channel

Buy Me a Coffee at ko-fi.com

Signup for Exclusive "Subscriber-only" Content

Loading