Introduction
RabbitMQ is the most widely deployed open-source message broker, supporting AMQP, MQTT, and STOMP protocols. Ansible's community.rabbitmq collection provides modules for managing every aspect — installation, clustering, virtual hosts, users, permissions, exchanges, queues, policies, and plugins. This guide covers single-node through production clustered deployments.
Prerequisites
ansible-galaxy collection install community.rabbitmq
Install RabbitMQ
---
- name: Deploy RabbitMQ
hosts: rabbitmq_servers
become: true
vars:
rabbitmq_admin_user: admin
rabbitmq_admin_password: "{{ vault_rabbitmq_admin_password }}"
tasks:
- name: Install Erlang and RabbitMQ (Debian)
block:
- name: Add RabbitMQ signing key
ansible.builtin.apt_key:
url: https://github.com/rabbitmq/signing-keys/releases/download/3.0/rabbitmq-release-signing-key.asc
state: present
- name: Add Erlang repository
ansible.builtin.apt_repository:
repo: "deb https://ppa1.novemberain.com/rabbitmq/rabbitmq-erlang/deb/ubuntu {{ ansible_distribution_release }} main"
filename: erlang
state: present
- name: Add RabbitMQ repository
ansible.builtin.apt_repository:
repo: "deb https://ppa1.novemberain.com/rabbitmq/rabbitmq-server/deb/ubuntu {{ ansible_distribution_release }} main"
filename: rabbitmq
state: present
- name: Install packages
ansible.builtin.apt:
name:
- erlang-base
- erlang-nox
- rabbitmq-server
state: present
when: ansible_os_family == 'Debian'
- name: Start RabbitMQ
ansible.builtin.service:
name: rabbitmq-server
state: started
enabled: true
- name: Enable management plugin
community.rabbitmq.rabbitmq_plugin:
names: rabbitmq_management
state: enabled
notify: restart rabbitmq
- name: Create admin user
community.rabbitmq.rabbitmq_user:
user: "{{ rabbitmq_admin_user }}"
password: "{{ rabbitmq_admin_password }}"
tags: administrator
permissions:
- vhost: /
configure_priv: .*
read_priv: .*
write_priv: .*
state: present
- name: Remove default guest user
community.rabbitmq.rabbitmq_user:
user: guest
state: absent
handlers:
- name: restart rabbitmq
ansible.builtin.service:
name: rabbitmq-server
state: restarted
Virtual Hosts and Users
- name: Create virtual hosts
community.rabbitmq.rabbitmq_vhost:
name: "{{ item }}"
state: present
loop:
- production
- staging
- monitoring
- name: Create application users
community.rabbitmq.rabbitmq_user:
user: "{{ item.name }}"
password: "{{ item.password }}"
tags: "{{ item.tags | default('') }}"
permissions:
- vhost: "{{ item.vhost }}"
configure_priv: "{{ item.configure | default('') }}"
read_priv: "{{ item.read | default('.*') }}"
write_priv: "{{ item.write | default('.*') }}"
state: present
loop:
- name: webapp
password: "{{ vault_rabbitmq_webapp_password }}"
vhost: production
configure: "^webapp\\."
read: ".*"
write: "^webapp\\."
- name: worker
password: "{{ vault_rabbitmq_worker_password }}"
vhost: production
configure: ""
read: "^(webapp\\.|tasks\\.)"
write: "^tasks\\."
- name: monitor
password: "{{ vault_rabbitmq_monitor_password }}"
vhost: production
tags: monitoring
configure: ""
read: ".*"
write: ""
no_log: true
Exchanges and Queues
- name: Declare exchanges
community.rabbitmq.rabbitmq_exchange:
name: "{{ item.name }}"
type: "{{ item.type }}"
vhost: production
durable: true
login_user: "{{ rabbitmq_admin_user }}"
login_password: "{{ rabbitmq_admin_password }}"
loop:
- { name: events, type: topic }
- { name: tasks, type: direct }
- { name: notifications, type: fanout }
- { name: dlx, type: direct }
- name: Declare queues
community.rabbitmq.rabbitmq_queue:
name: "{{ item.name }}"
vhost: production
durable: true
arguments: "{{ item.args | default({}) }}"
login_user: "{{ rabbitmq_admin_user }}"
login_password: "{{ rabbitmq_admin_password }}"
loop:
- name: tasks.email
args:
x-dead-letter-exchange: dlx
x-dead-letter-routing-key: dead.email
x-message-ttl: 86400000
- name: tasks.process
args:
x-dead-letter-exchange: dlx
x-max-length: 100000
- name: dead.letters
args: {}
- name: Bind queues to exchanges
community.rabbitmq.rabbitmq_binding:
name: tasks
destination: "{{ item.queue }}"
destination_type: queue
routing_key: "{{ item.key }}"
vhost: production
login_user: "{{ rabbitmq_admin_user }}"
login_password: "{{ rabbitmq_admin_password }}"
loop:
- { queue: tasks.email, key: email }
- { queue: tasks.process, key: process }
Clustering
---
- name: Configure RabbitMQ cluster
hosts: rabbitmq_servers
become: true
vars:
rabbitmq_erlang_cookie: "{{ vault_erlang_cookie }}"
rabbitmq_cluster_master: "{{ groups['rabbitmq_servers'][0] }}"
tasks:
- name: Set Erlang cookie
ansible.builtin.copy:
content: "{{ rabbitmq_erlang_cookie }}"
dest: /var/lib/rabbitmq/.erlang.cookie
mode: '0400'
owner: rabbitmq
group: rabbitmq
notify: restart rabbitmq
- name: Set cluster node name
ansible.builtin.lineinfile:
path: /etc/rabbitmq/rabbitmq-env.conf
line: "NODENAME=rabbit@{{ inventory_hostname }}"
create: true
mode: '0644'
notify: restart rabbitmq
- name: Flush handlers
ansible.builtin.meta: flush_handlers
- name: Join cluster (non-master nodes)
when: inventory_hostname != rabbitmq_cluster_master
block:
- name: Stop app
ansible.builtin.command: rabbitmqctl stop_app
- name: Reset node
ansible.builtin.command: rabbitmqctl reset
- name: Join cluster
ansible.builtin.command: >
rabbitmqctl join_cluster rabbit@{{ rabbitmq_cluster_master }}
register: join_result
changed_when: "'already_member' not in join_result.stderr"
- name: Start app
ansible.builtin.command: rabbitmqctl start_app
Policies
- name: Configure HA policy (quorum queues)
community.rabbitmq.rabbitmq_policy:
name: ha-all
vhost: production
pattern: ".*"
tags:
ha-mode: all
ha-sync-mode: automatic
apply_to: queues
login_user: "{{ rabbitmq_admin_user }}"
login_password: "{{ rabbitmq_admin_password }}"
- name: Configure message TTL policy
community.rabbitmq.rabbitmq_policy:
name: ttl-24h
vhost: production
pattern: "^tasks\\."
tags:
message-ttl: 86400000
max-length: 500000
apply_to: queues
login_user: "{{ rabbitmq_admin_user }}"
login_password: "{{ rabbitmq_admin_password }}"
TLS Configuration
- name: Configure RabbitMQ TLS
ansible.builtin.template:
src: rabbitmq.conf.j2
dest: /etc/rabbitmq/rabbitmq.conf
mode: '0644'
notify: restart rabbitmq
# templates/rabbitmq.conf.j2
listeners.ssl.default = 5671
ssl_options.cacertfile = /etc/rabbitmq/tls/ca.crt
ssl_options.certfile = /etc/rabbitmq/tls/server.crt
ssl_options.keyfile = /etc/rabbitmq/tls/server.key
ssl_options.verify = verify_peer
ssl_options.fail_if_no_peer_cert = false
# Management TLS
management.ssl.port = 15671
management.ssl.cacertfile = /etc/rabbitmq/tls/ca.crt
management.ssl.certfile = /etc/rabbitmq/tls/server.crt
management.ssl.keyfile = /etc/rabbitmq/tls/server.key
# Disable non-TLS listeners (production)
# listeners.tcp = none
Monitoring
- name: Enable Prometheus plugin
community.rabbitmq.rabbitmq_plugin:
names: rabbitmq_prometheus
state: enabled
notify: restart rabbitmq
# Prometheus scrape config:
# - job_name: rabbitmq
# static_configs:
# - targets: ['rabbitmq01:15692']
Health Check
- name: RabbitMQ health check
ansible.builtin.command: rabbitmq-diagnostics check_running
register: rmq_health
changed_when: false
failed_when: rmq_health.rc != 0
- name: Check cluster status
ansible.builtin.command: rabbitmqctl cluster_status
register: cluster_status
changed_when: false
run_once: true
- name: Check queue depths
ansible.builtin.uri:
url: "http://localhost:15672/api/queues/production"
user: "{{ rabbitmq_admin_user }}"
password: "{{ rabbitmq_admin_password }}"
force_basic_auth: true
register: queues
- name: Alert on deep queues
ansible.builtin.debug:
msg: "WARNING: {{ item.name }} has {{ item.messages }} messages"
loop: "{{ queues.json }}"
when: item.messages | default(0) > 10000
Troubleshooting
Cluster Partition
- name: Check for partitions
ansible.builtin.command: rabbitmqctl cluster_status --formatter json
register: status
changed_when: false
# Set partition handling in rabbitmq.conf:
# cluster_partition_handling = autoheal
Memory Alarm
- name: Set memory high watermark
ansible.builtin.lineinfile:
path: /etc/rabbitmq/rabbitmq.conf
line: "vm_memory_high_watermark.relative = 0.6"
regexp: "^vm_memory_high_watermark"
notify: restart rabbitmq
Related Articles
Conclusion
Ansible's community.rabbitmq collection manages the full RabbitMQ lifecycle — installation, clustering with shared Erlang cookies, virtual hosts for multi-tenancy, users with fine-grained permissions, exchanges and queues with dead-letter routing, HA policies, and TLS encryption. Use quorum queues for durability, Prometheus for monitoring, and policies for automatic message lifecycle management. All configuration is declarative and idempotent.