├── .ansible-lint ├── tests ├── test.yaml └── inventory ├── tasks ├── main.yaml ├── exporter.yaml └── nats-streaming-server.yaml ├── meta └── main.yaml ├── templates ├── nats-streaming-server.service.j2 ├── nats-exporter.service.j2 └── nats-streaming-server.conf.j2 ├── handlers └── main.yaml ├── .github └── workflows │ └── ci.yaml ├── defaults └── main.yaml ├── LICENSE └── README.md /.ansible-lint: -------------------------------------------------------------------------------- 1 | warn_list: 2 | - '106' 3 | -------------------------------------------------------------------------------- /tests/test.yaml: -------------------------------------------------------------------------------- 1 | - hosts: localhost 2 | remote_user: root 3 | roles: 4 | - ansible-role-nats-streaming 5 | -------------------------------------------------------------------------------- /tasks/main.yaml: -------------------------------------------------------------------------------- 1 | - include_tasks: nats-streaming-server.yaml 2 | 3 | - include_tasks: exporter.yaml 4 | when: nats_exporter_enabled == 'true' 5 | -------------------------------------------------------------------------------- /tests/inventory: -------------------------------------------------------------------------------- 1 | [streaming] 2 | localhost ansible_connection=local ansible_host=127.0.0.1 nats_client_advertise=127.0.0.1 nats_cluster_routes_address=127.0.0.1 3 | -------------------------------------------------------------------------------- /meta/main.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | galaxy_info: 3 | role_name: nats-streaming 4 | author: Mohammad Abdolirad 5 | description: Set up NATS Streaming in Debian-like systems 6 | company: Snapp 7 | min_ansible_version: 2.6 8 | license: MIT 9 | platforms: 10 | - name: Ubuntu 11 | versions: 12 | - all 13 | - name: Debian 14 | versions: 15 | - all 16 | galaxy_tags: 17 | - nats 18 | - streaming 19 | - messaging 20 | 21 | dependencies: [] 22 | -------------------------------------------------------------------------------- /templates/nats-streaming-server.service.j2: -------------------------------------------------------------------------------- 1 | # {{ ansible_managed }} 2 | 3 | [Unit] 4 | Description="NATS Streaming Server" 5 | After=network.target 6 | 7 | [Service] 8 | Type=simple 9 | RestartSec=5s 10 | Restart=on-failure 11 | ExecStop=/bin/kill -s SIGINT $MAINPID 12 | ExecReload=/bin/kill -s HUP $MAINPID 13 | ExecStart=/usr/local/bin/nats-streaming-server -sc /etc/nats-streaming-server.conf -ns {{ nats_streaming_nats_server_url }} 14 | 15 | [Install] 16 | WantedBy=multi-user.target 17 | -------------------------------------------------------------------------------- /templates/nats-exporter.service.j2: -------------------------------------------------------------------------------- 1 | # {{ ansible_managed }} 2 | 3 | [Unit] 4 | Description="Prometheus NATS Exporter" 5 | After=network.target nats-server.service 6 | 7 | [Service] 8 | Type=simple 9 | RestartSec=5s 10 | Restart=on-failure 11 | User=nats-exporter 12 | Group=nats-exporter 13 | ExecStop=/bin/kill -s SIGINT $MAINPID 14 | #ExecReload=/bin/kill -s HUP $MAINPID 15 | ExecStart=/usr/local/bin/prometheus-nats-exporter -channelz -connz -routez -serverz -subz -varz http://127.0.0.1:8222 16 | 17 | [Install] 18 | WantedBy=multi-user.target 19 | -------------------------------------------------------------------------------- /handlers/main.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: restart nats-streaming-server 3 | service: 4 | name: nats-streaming-server 5 | state: restarted 6 | 7 | - name: reload nats-streaming-server 8 | service: 9 | name: nats-streaming-server 10 | state: reloaded 11 | 12 | - name: reload daemon nats-streaming-server 13 | systemd: 14 | state: stopped 15 | daemon_reload: true 16 | name: nats-streaming-server 17 | 18 | - name: reload daemon nats-exporter 19 | systemd: 20 | state: stopped 21 | daemon_reload: true 22 | name: nats-exporter 23 | -------------------------------------------------------------------------------- /.github/workflows/ci.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | name: ci 3 | on: 4 | - push 5 | jobs: 6 | build: 7 | runs-on: ubuntu-latest 8 | steps: 9 | - uses: actions/checkout@v2 10 | - uses: actions/setup-python@v2 11 | with: 12 | python-version: 3.9 13 | - name: install ansible 14 | run: | 15 | python -m pip install --upgrade ansible ansible-lint 16 | - name: create ansible.cfg with correct roles_path 17 | run: printf '[defaults]\nroles_path=../' > ansible.cfg 18 | - name: ansible-lint 19 | run: ansible-lint . 20 | - run: ansible-playbook tests/test.yaml -i tests/inventory --syntax-check 21 | name: basic role syntax check 22 | - run: ansible-playbook tests/test.yaml -i tests/inventory --become 23 | name: install STAN and start its service 24 | - run: /usr/local/bin/nats-streaming-server -v 25 | name: nats streaming server version 26 | -------------------------------------------------------------------------------- /defaults/main.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | nats_streaming_version: "0.24.2" 3 | nats_streaming_host_group: "streaming" 4 | 5 | nats_streaming_cluster_id: "snapp" 6 | nats_streaming_nats_server_url: "nats://nats.service.consul:4222" 7 | 8 | nats_streaming_store_limits_max_channels: 100 9 | nats_streaming_store_limits_max_subs: 200 10 | nats_streaming_store_limits_max_msgs: 1000000 11 | nats_streaming_store_limits_max_bytes: "1GB" 12 | nats_streaming_store_limits_max_age: "48h" 13 | nats_streaming_store_limits_max_inactivity: "72h" 14 | nats_streaming_store_limits_channels: {} 15 | 16 | nats_streaming_file_options_buffer_size: 16MB 17 | nats_streaming_file_options_parallel_recovery: 4 18 | nats_streaming_file_options_read_buffer_size: 16MB 19 | nats_streaming_file_options_auto_sync: "1m" 20 | 21 | nats_streaming_cluster_node_id: "{{ ansible_hostname }}" 22 | nats_streaming_cluster_log_cache_size: 4096 23 | nats_streaming_cluster_sync: true 24 | 25 | nats_exporter_enabled: "true" 26 | nats_prometheus_exporter_version: "0.9.1" 27 | -------------------------------------------------------------------------------- /tasks/exporter.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Install NATS Prometheus exporter package from the GitHub. 3 | apt: 4 | state: present 5 | deb: "https://github.com/nats-io/prometheus-nats-exporter/releases/download/\ 6 | v{{ nats_prometheus_exporter_version }}/\ 7 | prometheus-nats-exporter-\ 8 | v{{ nats_prometheus_exporter_version }}-amd64.deb" 9 | 10 | - name: Create the NATS Prometheus exporter user 11 | user: 12 | name: nats-exporter 13 | comment: "NATS Prometheus exporter user (Ansible Managed)" 14 | createhome: "no" 15 | shell: "/usr/sbin/nologin" 16 | system: "yes" 17 | 18 | - name: Ensure NATS exporter service file is available. 19 | template: 20 | src: nats-exporter.service.j2 21 | dest: /etc/systemd/system/nats-exporter.service 22 | mode: 0644 23 | backup: true 24 | notify: 25 | - reload daemon nats-exporter 26 | 27 | - name: Ensure NATS exporter service is started and enabled on boot. 28 | service: 29 | name: nats-exporter 30 | state: started 31 | enabled: true 32 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 Snapp 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /tasks/nats-streaming-server.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Install NATS Streaming package from the GitHub. 3 | apt: 4 | state: present 5 | deb: "https://github.com/nats-io/nats-streaming-server/releases/download/\ 6 | v{{ nats_streaming_version }}/\ 7 | nats-streaming-server-v{{ nats_streaming_version }}-amd64.deb" 8 | 9 | - name: Create a directory for NATS Streaming 10 | file: 11 | path: /var/lib/nats-streaming 12 | state: directory 13 | mode: '0755' 14 | 15 | - name: Ensure NATS Streaming service file is available. 16 | template: 17 | src: nats-streaming-server.service.j2 18 | dest: /etc/systemd/system/nats-streaming-server.service 19 | mode: 0644 20 | backup: true 21 | notify: 22 | - reload daemon nats-streaming-server 23 | 24 | - name: Ensure NATS Streaming service is started and enabled on boot. 25 | service: 26 | name: nats-streaming-server 27 | state: started 28 | enabled: true 29 | 30 | - name: Create or update NATS Streaming configuration file (/etc/nats-streaming-server.conf) 31 | template: 32 | src: nats-streaming-server.conf.j2 33 | dest: /etc/nats-streaming-server.conf 34 | mode: 0644 35 | backup: true 36 | notify: 37 | - restart nats-streaming-server 38 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # NATS Streaming Ansible Role 2 | 3 | ![GitHub Actions Workflow Status](https://img.shields.io/github/actions/workflow/status/snapp-cab/ansible-role-nats-streaming/ci.yaml?style=for-the-badge&logo=github) 4 | 5 | NATS Streaming is a data streaming system powered by NATS, and written in the Go programming language. 6 | 7 | ## Installation 8 | 9 | ```yaml 10 | # requirments.yaml 11 | - src: git@github.com:snapp-incubator/ansible-role-nats-streaming.git 12 | scm: git 13 | version: master 14 | name: nats-streaming 15 | ``` 16 | 17 | ## Role Variables 18 | 19 | ```yaml 20 | nats_streaming_version: "0.18.0" 21 | nats_streaming_host_group: "streaming" 22 | 23 | nats_streaming_cluster_id: snapp 24 | nats_streaming_nats_server_url: "nats.service.consul" 25 | 26 | nats_streaming_store_limits_max_channels: 100 27 | nats_streaming_store_limits_max_subs: 200 28 | nats_streaming_store_limits_max_age: "48h" 29 | nats_streaming_store_limits_max_inactivity: "72h" 30 | 31 | nats_streaming_file_options_buffer_size: 16MB 32 | nats_streaming_file_options_parallel_recovery: 4 33 | nats_streaming_file_options_read_buffer_size: 16MB 34 | nats_streaming_file_options_auto_sync: "1m" 35 | 36 | nats_streaming_cluster_node_id: "{{ ansible_hostname }}" 37 | nats_streaming_cluster_bootstrap: true 38 | nats_streaming_cluster_log_cache_size: 4096 39 | nats_streaming_cluster_sync: true 40 | 41 | nats_exporter_enabled: "true" 42 | nats_prometheus_exporter_version: "0.6.2" 43 | ``` 44 | 45 | ## Example Playbook 46 | 47 | ```yaml 48 | - hosts: some_servers 49 | vars: 50 | nats_streaming_version: "0.18.0" 51 | nats_streaming_host_group: "some_servers" 52 | nats_exporter_enabled: "true" 53 | nats_prometheus_exporter_version: "0.6.2" 54 | roles: 55 | - nats-streaming 56 | ``` 57 | -------------------------------------------------------------------------------- /templates/nats-streaming-server.conf.j2: -------------------------------------------------------------------------------- 1 | #jinja2: trim_blocks: True, lstrip_blocks: True 2 | # {{ ansible_managed }} 3 | 4 | # HTTP monitoring port 5 | http_port = 8222 6 | 7 | streaming: { 8 | # Cluster name 9 | cluster_id: {{ nats_streaming_cluster_id }} 10 | 11 | # Store type 12 | store: file 13 | # When using a file store, this is the root directory 14 | dir: /var/lib/nats-streaming/nats-streaming-data 15 | 16 | # If specified, connects to an external NATS Server, otherwise starts an embedded one 17 | # nats_server_url: {{ nats_streaming_nats_server_url }} 18 | 19 | # Store Limits 20 | store_limits: { 21 | # Maximum number of channels 22 | max_channels: {{ nats_streaming_store_limits_max_channels }} 23 | # Maximum number of subscriptions per channel 24 | max_subs: {{ nats_streaming_store_limits_max_subs }} 25 | # Maximum number of messages per channel 26 | max_msgs: {{ nats_streaming_store_limits_max_msgs }} 27 | # Total size of messages per channel 28 | max_bytes: {{ nats_streaming_store_limits_max_bytes }} 29 | # How long messages can stay in the log 30 | max_age: {{ nats_streaming_store_limits_max_age }} 31 | # How long without any subscription and any new message before a channel can be automatically deleted 32 | max_inactivity: {{ nats_streaming_store_limits_max_inactivity }} 33 | {% if nats_streaming_store_limits_channels %} 34 | channels: { 35 | {% for channel, store_limit in nats_streaming_store_limits_channels.items() %} 36 | "{{ channel }}": { 37 | max_subs: {{ store_limit.max_subs | default(omit) }} 38 | max_msgs: {{ store_limit.max_msgs | default(omit) }} 39 | max_bytes: {{ store_limit.max_bytes | default(omit) }} 40 | max_age: {{ store_limit.max_age | default(omit) }} 41 | max_inactivity: {{ store_limit.max_inactivity | default(omit) }} 42 | } 43 | {% endfor %} 44 | } 45 | {% endif %} 46 | } 47 | 48 | # File Store specific options 49 | file_options: { 50 | # Size of buffers that can be used to buffer write operations 51 | buffer_size: {{ nats_streaming_file_options_buffer_size }} 52 | # When the server starts, the recovery of channels (directories) is done sequentially. 53 | parallel_recovery: {{ nats_streaming_file_options_parallel_recovery }} 54 | # Size of buffers used to read ahead from message stores. 55 | # This can significantly speed up sending messages to consumers after messages have been published. 56 | read_buffer_size: {{ nats_streaming_file_options_read_buffer_size }} 57 | # Interval at which the store should be automatically flushed and sync'ed on disk. 58 | auto_sync: "{{ nats_streaming_file_options_auto_sync }}" 59 | } 60 | 61 | # Cluster Configuration 62 | cluster: { 63 | # ID of the node within the cluster if there is no stored ID 64 | node_id: "{{ nats_streaming_cluster_node_id }}" 65 | # List of cluster peer node IDs to bootstrap cluster state 66 | peers: [ 67 | {% for node in groups[nats_streaming_host_group] %} 68 | {% if hostvars[node].ansible_hostname == ansible_hostname %} 69 | {% else %} 70 | "{{ hostvars[node].ansible_hostname }}" 71 | {% endif %} 72 | {% endfor %} 73 | ] 74 | 75 | # Directory to store log replication data 76 | log_path: "/var/lib/nats-streaming/nats-streaming-replication-data" 77 | # Number of log entries to cache in memory to reduce disk IO 78 | log_cache_size: {{ nats_streaming_cluster_log_cache_size }} 79 | # Do a file sync after every write to the replication log and message store 80 | sync: {{ nats_streaming_cluster_sync | lower }} 81 | } 82 | } 83 | --------------------------------------------------------------------------------