This guide provides a complete Ansible playbook to install Riemann using Docker with proper configuration for event stream processing, alerting, and integration with other monitoring tools.
Current Riemann version: 0.4.7 (Docker image)
Create a file named riemann.yml:
---
- name: Install and Configure Riemann
hosts: riemann
become: true
vars:
riemann_version: "0.4.7"
riemann_tcp_port: 5555
riemann_udp_port: 5555
riemann_ws_port: 5556
riemann_config_dir: "/opt/riemann/config"
riemann_data_dir: "/opt/riemann/data"
tasks:
- name: Create Riemann directories
file:
path: "{{ item }}"
state: directory
owner: root
group: root
mode: '0755'
loop:
- "{{ riemann_config_dir }}"
- "{{ riemann_data_dir }}"
- name: Create Riemann configuration
copy:
dest: "{{ riemann_config_dir }}/riemann.config"
owner: root
group: root
mode: '0644'
content: |
; Riemann Configuration
; See: http://riemann.io/howto/write-a-config.html
; Set logging level
(set! java.util.logging.Logger/java.util.logging.Level :info)
; TCP and UDP servers
(tcp-server {:host "0.0.0.0" :port {{ riemann_tcp_port }}})
(udp-server {:host "0.0.0.0" :port {{ riemann_udp_port }}})
; WebSocket server for dashboard
(ws-server {:port {{ riemann_ws_port }}})
; Index configuration
(let [index (index)]
; Stream all events through index
(streams index
; Log all events
(where (service #"^riemann")
(with :host "riemann-server"
(prn)))
; Alert on critical services
(where (and (service #"^(?!riemann)")
(state "critical"))
(email "admin@example.com"))
; Rate limiting for alerts
(where (service #"^(?!riemann)")
(rate 5
(email "admin@example.com")))))
- name: Create Docker Compose file
copy:
dest: "{{ riemann_data_dir }}/docker-compose.yml"
owner: root
group: root
mode: '0644'
content: |
version: '3.8'
services:
riemann:
image: docker.io/aphistic/riemann:{{ riemann_version }}
container_name: riemann
restart: unless-stopped
ports:
- "{{ riemann_tcp_port }}:{{ riemann_tcp_port }}"
- "{{ riemann_udp_port }}:{{ riemann_udp_port }}/udp"
- "{{ riemann_ws_port }}:{{ riemann_ws_port }}"
volumes:
- {{ riemann_config_dir }}:/etc/riemann
- {{ riemann_data_dir }}:/var/lib/riemann
environment:
- RIEMANN_CONFIG=/etc/riemann/riemann.config
networks:
- riemann_net
networks:
riemann_net:
driver: bridge
- name: Start Riemann container
community.docker.docker_compose:
project_src: "{{ riemann_data_dir }}"
state: present
build: false
pull: true
- name: Wait for Riemann to start
wait_for:
port: "{{ riemann_tcp_port }}"
delay: 10
timeout: 120
- name: Configure firewall (UFW)
ufw:
rule: allow
port: "{{ item }}"
proto: tcp
comment: "Riemann service"
loop:
- "{{ riemann_tcp_port }}"
- "{{ riemann_ws_port }}"
when: ansible_os_family == "Debian"
failed_when: false
- name: Configure firewall for UDP
ufw:
rule: allow
port: "{{ riemann_udp_port }}"
proto: udp
comment: "Riemann UDP"
when: ansible_os_family == "Debian"
failed_when: false
- name: Configure firewall (firewalld)
firewalld:
port: "{{ item }}/tcp"
permanent: true
immediate: true
state: enabled
loop:
- "{{ riemann_tcp_port }}"
- "{{ riemann_ws_port }}"
when: ansible_os_family == "RedHat"
failed_when: false
- name: Verify Riemann is running
command: docker exec riemann riemann-client query "true"
register: riemann_check
changed_when: false
failed_when: false
- name: Display Riemann status
debug:
msg: |
Riemann {{ riemann_version }} installed successfully!
TCP Port: {{ riemann_tcp_port }}
UDP Port: {{ riemann_udp_port }}
WebSocket Port: {{ riemann_ws_port }}
Configuration directory: {{ riemann_config_dir }}
Data directory: {{ riemann_data_dir }}
---
riemann:
hosts:
riemann-server:
ansible_host: 192.168.1.117
ansible_user: ansible
ansible_become: true
# Test connectivity
ansible all -i inventory.yml -m ping
# Run the Riemann playbook
ansible-playbook -i inventory.yml riemann.yml
# Check container status
ssh riemann-server "docker ps | grep riemann"
# View container logs
ssh riemann-server "docker logs riemann"
# Test TCP connection
ssh riemann-server "nc -zv localhost 5555"
# Access Riemann dash (web UI)
# http://riemann-server:5556
- name: Configure Riemann email notifications
hosts: riemann
become: true
vars:
riemann_config_dir: "/opt/riemann/config"
smtp_host: "smtp.example.com"
smtp_port: 587
smtp_user: "riemann@example.com"
smtp_password: "smtp_password"
alert_email: "admin@example.com"
tasks:
- name: Update Riemann config for email
copy:
dest: "{{ riemann_config_dir }}/riemann.config"
owner: root
group: root
mode: '0644'
content: |
; Riemann Configuration with Email
(set! java.util.logging.Logger/java.util.logging.Level :info)
; Email configuration
(def mailer (mail {:from "riemann@example.com"
:host "{{ smtp_host }}"
:port {{ smtp_port }}
:user "{{ smtp_user }}"
:pass "{{ smtp_password }}"
:ssl true}))
; TCP and UDP servers
(tcp-server {:host "0.0.0.0" :port {{ riemann_tcp_port }}})
(udp-server {:host "0.0.0.0" :port {{ riemann_udp_port }}})
(ws-server {:port {{ riemann_ws_port }}})
; Index and streams
(let [index (index)]
(streams index
; Log Riemann events
(where (service #"^riemann")
(with :host "riemann-server"
(prn)))
; Email on critical state
(where (state "critical")
(mailer {:subject "Riemann Alert: Critical"
:body "A service is in critical state"
:recipients ["{{ alert_email }}"]}))
; Email on warning state (rate limited)
(where (state "warning")
(rate 300
(mailer {:subject "Riemann Alert: Warning"
:body "A service is in warning state"
:recipients ["{{ alert_email }}"]})))
; Email on service failure
(where (expired true)
(mailer {:subject "Riemann Alert: Service Expired"
:body "A service has stopped reporting"
:recipients ["{{ alert_email }}"]}))
; All events to index
index))
- name: Configure Riemann Slack integration
hosts: riemann
become: true
vars:
riemann_config_dir: "/opt/riemann/config"
slack_token: "xoxb-your-slack-bot-token"
slack_channel: "#alerts"
tasks:
- name: Update Riemann config for Slack
copy:
dest: "{{ riemann_config_dir }}/riemann.config"
owner: root
group: root
mode: '0644'
content: |
; Riemann Configuration with Slack
(set! java.util.logging.Logger/java.util.logging.Level :info)
; Slack configuration
(def slack (slack {:token "{{ slack_token }}"
:channel "{{ slack_channel }}"}))
; TCP and UDP servers
(tcp-server {:host "0.0.0.0" :port {{ riemann_tcp_port }}})
(udp-server {:host "0.0.0.0" :port {{ riemann_udp_port }}})
(ws-server {:port {{ riemann_ws_port }}})
; Index and streams
(let [index (index)]
(streams index
; Slack on critical
(where (state "critical")
(slack {:title "Critical Alert"
:text "Service {{ "{{" }}service{{ "}}" }} is critical on {{ "{{" }}host{{ "}}" }}"
:color "danger"}))
; Slack on warning
(where (state "warning")
(rate 300
(slack {:title "Warning Alert"
:text "Service {{ "{{" }}service{{ "}}" }} is in warning state"
:color "warning"})))
index))
- name: Send test event to Riemann
hosts: riemann
become: false
vars:
riemann_tcp_port: 5555
tasks:
- name: Send test event using riemann-client
shell: |
docker exec riemann riemann-client send \
--host test-host \
--service test-service \
--state warning \
--metric 42.5 \
--description "Test event from Ansible" \
--tags test,ansible
register: send_result
changed_when: false
- name: Query events
shell: |
docker exec riemann riemann-client query "host = \"test-host\""
register: query_result
changed_when: false
- name: Display test results
debug:
msg: |
Test event sent!
Query result: {{ query_result.stdout }}
- name: Configure Riemann Prometheus exporter
hosts: riemann
become: true
vars:
riemann_data_dir: "/opt/riemann/data"
prometheus_port: 5557
tasks:
- name: Update Docker Compose with Prometheus exporter
copy:
dest: "{{ riemann_data_dir }}/docker-compose.yml"
owner: root
group: root
mode: '0644'
content: |
version: '3.8'
services:
riemann:
image: docker.io/aphistic/riemann:{{ riemann_version }}
container_name: riemann
restart: unless-stopped
ports:
- "{{ riemann_tcp_port }}:{{ riemann_tcp_port }}"
- "{{ riemann_udp_port }}:{{ riemann_udp_port }}/udp"
- "{{ riemann_ws_port }}:{{ riemann_ws_port }}"
- "{{ prometheus_port }}:{{ prometheus_port }}"
volumes:
- {{ riemann_config_dir }}:/etc/riemann
- {{ riemann_data_dir }}:/var/lib/riemann
environment:
- RIEMANN_CONFIG=/etc/riemann/riemann.config
networks:
- riemann_net
riemann-prometheus:
image: prom/riemann-exporter:latest
container_name: riemann-prometheus
restart: unless-stopped
ports:
- "{{ prometheus_port }}:9400"
command:
- --riemann.host=riemann
- --riemann.port={{ riemann_tcp_port }}
- --web.listen-address=:9400
depends_on:
- riemann
networks:
- riemann_net
networks:
riemann_net:
driver: bridge
- name: Restart Riemann
community.docker.docker_compose:
project_src: "{{ riemann_data_dir }}"
state: present
restarted: true
- name: Backup Riemann configuration
hosts: riemann
become: true
vars:
riemann_config_dir: "/opt/riemann/config"
riemann_data_dir: "/opt/riemann/data"
backup_dir: "/backup/riemann"
tasks:
- name: Create backup directory
file:
path: "{{ backup_dir }}"
state: directory
mode: '0755'
- name: Backup configuration
archive:
path: "{{ riemann_config_dir }}"
dest: "{{ backup_dir }}/config-backup-{{ ansible_date_time.date }}.tar.gz"
- name: Backup data directory
archive:
path: "{{ riemann_data_dir }}"
dest: "{{ backup_dir }}/data-backup-{{ ansible_date_time.date }}.tar.gz"
- name: Clean up old backups (keep 7 days)
find:
paths: "{{ backup_dir }}"
patterns: "*.tar.gz"
age: 7d
register: old_backups
- name: Remove old backups
file:
path: "{{ item.path }}"
state: absent
loop: "{{ old_backups.files }}"
# Check container logs
docker logs riemann
# Check configuration syntax
docker exec riemann riemann-client query "true"
# Check container status
docker ps -a | grep riemann
# Check if port is listening
docker exec riemann netstat -tlnp | grep 5555
# Test TCP connection
nc -zv localhost 5555
# Send test event
docker exec riemann riemann-client send --service test --state ok
# Validate configuration
docker exec riemann cat /etc/riemann/riemann.config
# Check Java errors
docker logs riemann 2>&1 | grep -i error
We develop tailored automation solutions for:
Let’s discuss your requirements: office@linux-server-admin.com | Contact