# Wazuh-Ansible [![Slack](https://img.shields.io/badge/slack-join-blue.svg)](https://wazuh.com/community/join-us-on-slack/) [![Email](https://img.shields.io/badge/email-join-blue.svg)](https://groups.google.com/forum/#!forum/wazuh) [![Documentation](https://img.shields.io/badge/docs-view-green.svg)](https://documentation.wazuh.com) [![Documentation](https://img.shields.io/badge/web-view-green.svg)](https://wazuh.com) These playbooks install and configure Wazuh agent, manager and Elastic Stack. ## Documentation * [Wazuh Ansible documentation](https://documentation.wazuh.com/current/deploying-with-ansible/index.html) * [Full documentation](http://documentation.wazuh.com) ## Directory structure ├── wazuh-ansible │ ├── roles │ │ ├── elastic-stack │ │ │ ├── ansible-elasticsearch │ │ │ ├── ansible-kibana │ │ │ │ ├── opendistro │ │ │ ├── opendistro-elasticsearch │ │ │ ├── opendistro-kibana │ │ │ │ ├── wazuh │ │ │ ├── ansible-filebeat │ │ │ ├── ansible-filebeat-oss │ │ │ ├── ansible-wazuh-manager │ │ │ ├── ansible-wazuh-agent │ │ │ │ ├── ansible-galaxy │ │ │ ├── meta │ │ ├── playbooks │ │ ├── wazuh-agent.yml │ │ ├── wazuh-elastic.yml │ │ ├── wazuh-elastic_stack-distributed.yml │ │ ├── wazuh-elastic_stack-single.yml │ │ ├── wazuh-kibana.yml │ │ ├── wazuh-manager.yml │ │ ├── wazuh-manager-oss.yml │ │ ├── wazuh-opendistro.yml │ │ ├── wazuh-opendistro-kibana.yml │ │ ├── README.md │ ├── VERSION │ ├── CHANGELOG.md ## Example: production-ready distributed environment ### Playbook The hereunder example playbook uses the `wazuh-ansible` role to provision a production-ready Wazuh environment. The architecture includes 2 Wazuh nodes, 3 ODFE nodes and a mixed ODFE-Kibana node. ```yaml --- # Certificates generation - hosts: es1 roles: - role: ../roles/opendistro/opendistro-elasticsearch elasticsearch_network_host: "{{ private_ip }}" elasticsearch_cluster_nodes: - "{{ hostvars.es1.private_ip }}" - "{{ hostvars.es2.private_ip }}" - "{{ hostvars.es3.private_ip }}" elasticsearch_discovery_nodes: - "{{ hostvars.es1.private_ip }}" - "{{ hostvars.es2.private_ip }}" - "{{ hostvars.es3.private_ip }}" perform_installation: false become: yes become_user: root vars: elasticsearch_node_master: true instances: node1: name: node-1 # Important: must be equal to elasticsearch_node_name. ip: "{{ hostvars.es1.private_ip }}" # When unzipping, the node will search for its node name folder to get the cert. node2: name: node-2 ip: "{{ hostvars.es2.private_ip }}" node3: name: node-3 ip: "{{ hostvars.es3.private_ip }}" node4: name: node-4 ip: "{{ hostvars.manager.private_ip }}" node5: name: node-5 ip: "{{ hostvars.worker.private_ip }}" node6: name: node-6 ip: "{{ hostvars.kibana.private_ip }}" tags: - generate-certs #ODFE Cluster - hosts: odfe_cluster strategy: free roles: - role: ../roles/opendistro/opendistro-elasticsearch elasticsearch_network_host: "{{ private_ip }}" become: yes become_user: root vars: elasticsearch_cluster_nodes: - "{{ hostvars.es1.private_ip }}" - "{{ hostvars.es2.private_ip }}" - "{{ hostvars.es3.private_ip }}" elasticsearch_discovery_nodes: - "{{ hostvars.es1.private_ip }}" - "{{ hostvars.es2.private_ip }}" - "{{ hostvars.es3.private_ip }}" elasticsearch_node_master: true instances: node1: name: node-1 # Important: must be equal to elasticsearch_node_name. ip: "{{ hostvars.es1.private_ip }}" # When unzipping, the node will search for its node name folder to get the cert. node2: name: node-2 ip: "{{ hostvars.es2.private_ip }}" node3: name: node-3 ip: "{{ hostvars.es3.private_ip }}" node4: name: node-4 ip: "{{ hostvars.manager.private_ip }}" node5: name: node-5 ip: "{{ hostvars.worker.private_ip }}" node6: name: node-6 ip: "{{ hostvars.kibana.private_ip }}" #Wazuh cluster - hosts: manager roles: - role: "../roles/wazuh/ansible-wazuh-manager" - role: "../roles/wazuh/ansible-filebeat-oss" filebeat_node_name: node-4 become: yes become_user: root vars: wazuh_manager_config: connection: - type: 'secure' port: '1514' protocol: 'tcp' queue_size: 131072 api: https: 'yes' cluster: disable: 'no' node_name: 'master' node_type: 'master' nodes: - '"{{ hostvars.manager.private_ip }}"' hidden: 'no' filebeat_output_elasticsearch_hosts: - "{{ hostvars.es1.private_ip }}" - "{{ hostvars.es2.private_ip }}" - "{{ hostvars.es3.private_ip }}" - hosts: worker roles: - role: "../roles/wazuh/ansible-wazuh-manager" - role: "../roles/wazuh/ansible-filebeat-oss" filebeat_node_name: node-5 become: yes become_user: root vars: wazuh_manager_config: connection: - type: 'secure' port: '1514' protocol: 'tcp' queue_size: 131072 api: https: 'yes' cluster: disable: 'no' node_name: 'worker_01' node_type: 'worker' key: 'c98b62a9b6169ac5f67dae55ae4a9088' nodes: - '"{{ hostvars.manager.private_ip }}"' hidden: 'no' filebeat_output_elasticsearch_hosts: - "{{ hostvars.es1.private_ip }}" - "{{ hostvars.es2.private_ip }}" - "{{ hostvars.es3.private_ip }}" #ODFE+Kibana node - hosts: kibana roles: - role: "../roles/opendistro/opendistro-elasticsearch" - role: "../roles/opendistro/opendistro-kibana" become: yes become_user: root vars: elasticsearch_network_host: "{{ hostvars.kibana.private_ip }}" elasticsearch_node_name: node-6 elasticsearch_node_master: false elasticsearch_node_ingest: false elasticsearch_node_data: false elasticsearch_cluster_nodes: - "{{ hostvars.es1.private_ip }}" - "{{ hostvars.es2.private_ip }}" - "{{ hostvars.es3.private_ip }}" elasticsearch_discovery_nodes: - "{{ hostvars.es1.private_ip }}" - "{{ hostvars.es2.private_ip }}" - "{{ hostvars.es3.private_ip }}" kibana_node_name: node-6 wazuh_api_credentials: - id: default url: https://{{ hostvars.manager.private_ip }} port: 55000 user: foo password: bar instances: node1: name: node-1 # Important: must be equal to elasticsearch_node_name. ip: "{{ hostvars.es1.private_ip }}" # When unzipping, the node will search for its node name folder to get the cert. node2: name: node-2 ip: "{{ hostvars.es2.private_ip }}" node3: name: node-3 ip: "{{ hostvars.es3.private_ip }}" node4: name: node-4 ip: "{{ hostvars.manager.private_ip }}" node5: name: node-5 ip: "{{ hostvars.worker.private_ip }}" node6: name: node-6 ip: "{{ hostvars.kibana.private_ip }}" ``` ### Inventory file The inventory file sets the public and private address of each node. The public addresses are used to gather facts and provision the instances while the private addresses are used for the cluster communications. The ssh credentials used by Ansible during the provision can be specified in this file too. Another option is including them directly on the playbook. ```ini es1 ansible_host= private_ip= elasticsearch_node_name=node-1 es2 ansible_host= private_ip= elasticsearch_node_name=node-2 es3 ansible_host= private_ip= elasticsearch_node_name=node-3 kibana ansible_host= private_ip= manager ansible_host= private_ip= worker ansible_host= private_ip= [odfe_cluster] es1 es2 es3 [all:vars] ansible_ssh_user=vagrant ansible_ssh_private_key_file=/path/to/ssh/key.pem ansible_ssh_extra_args='-o StrictHostKeyChecking=no' ``` ### Launching playbook ```bash ansible-playbook wazuh-odfe-production-ready.yml -i inventory ``` ## Example: single-host environment ### Playbook The hereunder example playbook uses the `wazuh-ansible` role to provision a single-host Wazuh environment. This architecture includes all the Wazuh and ODFE components in a single node. ```yaml ``` ### Launching playbook ```bash ansible-playbook wazuh-odfe-single.yml -i inventory ``` ## Branches * `master` branch on correspond to the last Wazuh-Ansible stable version. ## Contribute If you want to contribute to our repository, please fork our Github repository and submit a pull request. If you are not familiar with Github, you can also share them through [our users mailing list](https://groups.google.com/d/forum/wazuh), to which you can subscribe by sending an email to `wazuh+subscribe@googlegroups.com`. ### Modified by Wazuh The playbooks have been modified by Wazuh, including some specific requirements, templates and configuration to improve integration with Wazuh ecosystem. ## Credits and Thank you Based on previous work from dj-wasabi. https://github.com/dj-wasabi/ansible-ossec-server ## License and copyright WAZUH Copyright (C) 2016-2020 Wazuh Inc. (License GPLv2) ## Web references * [Wazuh website](http://wazuh.com)