diff --git a/grafana/ansible-role-requirements.yml b/grafana/ansible-role-requirements.yml new file mode 100644 index 00000000..6bc583d6 --- /dev/null +++ b/grafana/ansible-role-requirements.yml @@ -0,0 +1,5 @@ +--- +- name: grafana + scm: git + src: https://github.com/cloudalchemy/ansible-grafana + version: master diff --git a/grafana/installGrafana.yml b/grafana/installGrafana.yml index cef7579e..94a7849d 100644 --- a/grafana/installGrafana.yml +++ b/grafana/installGrafana.yml @@ -14,7 +14,7 @@ # limitations under the License. - name: Deploy Grafana - hosts: grafana + hosts: grafana_all become: true vars_files: - vars/variables.yml @@ -36,6 +36,10 @@ when: - galera_root_password is undefined + - name: Install PyMySQL + package: + name: python-pymysql + - name: Create DB for service mysql_db: login_user: "{{ galera_root_user }}" diff --git a/grafana/inventory.example.yml b/grafana/inventory.example.yml index 43032048..dc4ae3a9 100644 --- a/grafana/inventory.example.yml +++ b/grafana/inventory.example.yml @@ -24,6 +24,6 @@ hosts: logging01: # This is the location where grafana(s) will live -grafana: +grafana_all: hosts: logging01: diff --git a/grafana/site.yml b/grafana/site.yml new file mode 100644 index 00000000..ef61ddc2 --- /dev/null +++ b/grafana/site.yml @@ -0,0 +1,16 @@ +--- +# Copyright 2019, Rackspace US, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +- import_playbook: installGrafana.yml diff --git a/osquery/env.d/fleet.yml b/osquery/env.d/fleet.yml index d8cf81d0..f44c5346 100644 --- a/osquery/env.d/fleet.yml +++ b/osquery/env.d/fleet.yml @@ -5,10 +5,10 @@ component_skel: - fleet_all - kolide-fleet_all - mariadb: + kolide-db: belongs_to: - fleet_all - - mariadb_all + - kolide-db_all container_skel: kolide-fleet_container: @@ -16,7 +16,7 @@ container_skel: - kolide_containers contains: - kolide-fleet - - mariadb + - kolide-db physical_skel: kolide_containers: diff --git a/osquery/installDB.yml b/osquery/installDB.yml index 0759dfb0..61ea0b4e 100644 --- a/osquery/installDB.yml +++ b/osquery/installDB.yml @@ -14,7 +14,7 @@ # limitations under the License. - name: Install MariaDB Galera Cluster - hosts: "mariadb_all" + hosts: "kolide-db_all" become: true user: root gather_facts: "{{ osa_gather_facts | default(True) }}" @@ -34,7 +34,7 @@ roles: - role: galera_server - galera_cluster_members: "{{ groups['mariadb_all'] }}" + galera_cluster_members: "{{ groups['kolide-db_all'] }}" galera_wsrep_node_name: "{{ inventory_hostname }}" galera_cluster_name: telemetry_galera_cluster galera_monitoring_allowed_source: "0.0.0.0/0" diff --git a/osquery/installOSquery.yml b/osquery/installOSquery.yml index eede075f..a479024c 100644 --- a/osquery/installOSquery.yml +++ b/osquery/installOSquery.yml @@ -64,7 +64,7 @@ - name: Install osquery - hosts: "hosts:all_containers" + hosts: "osquery_all" become: true vars_files: - vars/variables.yml diff --git a/osquery/roles/fleet/tasks/createFleetDB.yml b/osquery/roles/fleet/tasks/createFleetDB.yml index 2220e035..2ad524d7 100644 --- a/osquery/roles/fleet/tasks/createFleetDB.yml +++ b/osquery/roles/fleet/tasks/createFleetDB.yml @@ -20,7 +20,7 @@ login_host: "127.0.0.1" name: "{{ kolide_fleet_db_name }}" state: "present" - delegate_to: "{{ groups['mariadb_all'][0] }}" + delegate_to: "{{ groups['kolide-db_all'][0] }}" no_log: False run_once: true @@ -35,7 +35,7 @@ state: "present" priv: "{{ kolide_fleet_db_name }}.*:ALL" append_privs: "{{ kolide_fleet_db_append_privs | default(omit) }}" - delegate_to: "{{ groups['mariadb_all'][0] }}" + delegate_to: "{{ groups['kolide-db_all'][0] }}" with_items: - 'localhost' - '127.0.0.1' diff --git a/osquery/tests/inventory/test-container-inventory.yml b/osquery/tests/inventory/test-container-inventory.yml index 1bcadca4..f49606e9 100644 --- a/osquery/tests/inventory/test-container-inventory.yml +++ b/osquery/tests/inventory/test-container-inventory.yml @@ -20,7 +20,9 @@ all: ansible_user: root -hosts: +osquery_all: + hosts: + localhost: {} vars: physical_host: localhost management_cidr: "172.29.236.0/24" @@ -30,9 +32,6 @@ hosts: netmask: "255.255.255.0" bridge: "{{ hostvars[physical_host]['ansible_default_ipv4']['alias'] }}" - hosts: - localhost: {} - all_containers: vars: @@ -45,9 +44,9 @@ all_containers: bridge: "{{ hostvars[physical_host]['ansible_default_ipv4']['alias'] }}" children: - mariadb_all: + kolide-db_all: children: - mariadb: + kolide-db: hosts: kolide-fleet0: {} kolide-fleet1: {} diff --git a/osquery/tests/inventory/test-metal-inventory.yml b/osquery/tests/inventory/test-metal-inventory.yml index 99055900..f97b50d0 100644 --- a/osquery/tests/inventory/test-metal-inventory.yml +++ b/osquery/tests/inventory/test-metal-inventory.yml @@ -7,14 +7,15 @@ all: ansible_host: 127.0.0.1 ansible_user: root -hosts: + +osquery_all: hosts: localhost: {} -mariadb_all: +kolide-db_all: children: - mariadb: + kolide-db: hosts: localhost: {} diff --git a/overlay-inventories/README.md b/overlay-inventories/README.md new file mode 100644 index 00000000..90e33cfc --- /dev/null +++ b/overlay-inventories/README.md @@ -0,0 +1,85 @@ +# Overlay Ansible inventories + +To deploy any of the operational tooling within an existing OpenStack-Ansible +deployment environment, or any environment that is using Ansible, it's +possible to use an overlay inventory to deploy systems without having to make +configuration changes in an environment or it's given inventory. + +> An overlay inventory is nothing more than a second inventory source which + contains meta groups that reference other groups as children. + +This project folder contains reference overlay inventories that can be used +to deploy all of the tested operational tooling. + +####### What's currently included + +* elk_metrics_6x +* grafana +* osquery +* skydive + +#### Deploying | The environment + +The example overlay inventory file `osa-integration-inventory.yml` in this +directory is being used in this example to deploy all of the operational +tooling in an already online OpenStack-Ansible deployed cloud. + +> The use of overlay inventories requires modern versions of Ansible. In + this deployment example the embedded Ansible solution is being used to + ensure all of the requirements are met. + +``` shell +# Clone this repo into place +git clone https://github.com/openstack/openstack-ansible-ops /opt/openstack-ansible-ops + +# Source the embedded ansible +source /opt/openstack-ansible-ops/bootstrap-embedded-ansible/bootstrap-embedded-ansible.sh + +# Deploy osquery and kolide/fleet +pushd /opt/openstack-ansible-ops/osquery + ansible-galaxy install -r ansible-role-requirements.yml + ansible-playbook -i /opt/openstack-ansible/inventory/dynamic_inventory.py \ + -i /opt/openstack-ansible-ops/overlay-inventories/osa-integration-inventory.yml \ + -e @/etc/openstack_deploy/user_secrets.yml \ + site.yml +popd + +# Deploy the elastic-stack +pushd /opt/openstack-ansible-ops/elk_metrics_6x + ansible-galaxy install -r ansible-role-requirements.yml + ansible-playbook -i /opt/openstack-ansible/inventory/dynamic_inventory.py \ + -i /opt/openstack-ansible-ops/overlay-inventories/osa-integration-inventory.yml \ + -e @/etc/openstack_deploy/user_secrets.yml \ + site.yml +popd + +# Deploy skydive +pushd /opt/openstack-ansible-ops/skydive + ansible-galaxy install -r ansible-role-requirements.yml + ansible-playbook -i /opt/openstack-ansible/inventory/dynamic_inventory.py \ + -i /opt/openstack-ansible-ops/overlay-inventories/osa-integration-inventory.yml \ + -e @/etc/openstack_deploy/user_secrets.yml \ + site.yml +popd + +# Deploy grafana +pushd /opt/openstack-ansible-ops/grafana + ansible-galaxy install -r ansible-role-requirements.yml + ansible-playbook -i /opt/openstack-ansible/inventory/dynamic_inventory.py \ + -i /opt/openstack-ansible-ops/overlay-inventories/osa-integration-inventory.yml \ + -e @/etc/openstack_deploy/user_secrets.yml \ + -e @/opt/openstack-ansible-ops/elk_metrics_6x/vars/variables.yml \ + site.yml -e grafana_use_provisioning=no -e grafana_admin_password=secrete +popd + +# Disable the embedded ansible post deployment +deactivate + +# If using haproxy, run the haproxy playbook using the multiple inventory sources. +pushd /opt/openstack-ansible/playbooks + openstack-ansible -i /opt/openstack-ansible/inventory/dynamic_inventory.py \ + -i /opt/openstack-ansible-ops/overlay-inventories/osa-integration-inventory.yml \ + -e @/etc/openstack_deploy/user_secrets.yml \ + haproxy-install.yml +popd +``` diff --git a/overlay-inventories/osa-integration-inventory.yml b/overlay-inventories/osa-integration-inventory.yml new file mode 100644 index 00000000..ca656549 --- /dev/null +++ b/overlay-inventories/osa-integration-inventory.yml @@ -0,0 +1,161 @@ +--- + +all_systems: + vars: {} + children: + systems: + vars: + # General Ansible options for OSA + ansible_become: yes + ansible_become_user: "root" + ansible_user: "root" + ## Grafana options + grafana_admin_password: "{{ haproxy_stats_password }}" + ## Kolide options + kolide_fleet_db_password: "{{ haproxy_stats_password }}" + kolide_fleet_jwt_key: "{{ haproxy_stats_password }}" + kolide_fleet_admin_password: "{{ haproxy_stats_password }}" + galera_root_password: "{{ galera_root_password | default(haproxy_stats_password) }}" + ## Skydive options + skydive_password: "{{ haproxy_stats_password }}" + skydive_elasticsearch_servers: "{{ groups['elastic-logstash'] | map('extract', hostvars, ['ansible_host']) | list | join(',') }}" + skydive_bind_address: "{{ container_address | default(ansible_host) }}" + ## Elastic-stack options + elastic_skydive_retention: 2 # Elastic retention set to 2 days max + elastic_skydive_size: 51200 # Elastic retention set to 50GiB max + ## Beat options + beat_service_states: + true: + state: restarted + false: + state: stopped + elastic_retention_refresh: true + auditbeat_service_state: "{{ beat_service_states[(inventory_hostname in (groups['hosts'] | default([])) | string | lower)]['state'] }}" + filebeat_service_state: "{{ beat_service_states[(inventory_hostname in (groups['hosts'] | default([])) | string | lower)]['state'] }}" + heartbeat_service_state: "{{ beat_service_states[(inventory_hostname in (groups['utility_all'] | default([])) | string | lower)]['state'] }}" + journalbeat_service_state: "{{ beat_service_states[(inventory_hostname in (groups['hosts'] | default([])) | string | lower)]['state'] }}" + metricbeat_service_state: "{{ beat_service_states[(inventory_hostname in (groups['hosts'] | default([])) | string | lower)]['state'] }}" + packetbeat_service_state: "{{ beat_service_states[(inventory_hostname in (groups['network_hosts'] | default([])) | string | lower)]['state'] }}" + ## HAProxy options + haproxy_extra_services: + - service: + haproxy_service_name: skydive_analyzer + haproxy_backend_nodes: "{{ groups['skydive_analyzers'] | default([]) }}" + haproxy_bind: "{{ [internal_lb_vip_address] }}" + haproxy_port: 8082 + haproxy_balance_type: http + haproxy_ssl: true + haproxy_backend_options: + - "httpchk HEAD / HTTP/1.0\\r\\nUser-agent:\\ osa-haproxy-healthcheck" + - service: + haproxy_service_name: traefik + haproxy_backend_nodes: "{{ groups['skydive_analyzers'] | default([]) }}" + haproxy_bind: "{{ [internal_lb_vip_address] }}" + haproxy_port: 8090 + haproxy_balance_type: http + haproxy_ssl: true + haproxy_backend_options: + - "httpchk HEAD / HTTP/1.0\\r\\nUser-agent:\\ osa-haproxy-healthcheck" + haproxy_backend_httpcheck_options: + - expect rstatus 200|401 + - service: + haproxy_service_name: elasticsearch + haproxy_backend_nodes: "{{ groups['elastic-logstash'] | default([]) }}" + haproxy_ssl: True + haproxy_port: 9201 + haproxy_backend_port: 9200 + haproxy_balance_type: http + haproxy_backend_options: + - "httpchk HEAD / HTTP/1.0\\r\\nUser-agent:\\ osa-haproxy-healthcheck" + - service: + haproxy_service_name: kibana_ssl + haproxy_backend_nodes: "{{ groups['kibana'] | default([]) }}" + haproxy_ssl: True + haproxy_port: 8443 + haproxy_backend_port: 81 + haproxy_balance_type: tcp + haproxy_backend_options: + - tcpka + - service: + haproxy_service_name: apm-server + haproxy_backend_nodes: "{{ groups['apm-server'] | default([]) }}" + haproxy_ssl: True + haproxy_port: 8200 + haproxy_balance_type: tcp + haproxy_backend_options: + - tcpka + - service: + haproxy_service_name: kolide-fleet + haproxy_backend_nodes: "{{ groups['kolide-fleet_all'] | default([]) }}" + haproxy_ssl: True + haproxy_port: 6443 + haproxy_check_port: 443 + haproxy_backend_port: 443 + haproxy_balance_type: tcp + haproxy_backend_options: + - tcpka + - service: + haproxy_service_name: grafana + haproxy_backend_nodes: "{{ groups['grafana_all'] | default([]) }}" + haproxy_ssl: True + haproxy_port: 3000 + haproxy_balance_type: http + haproxy_backend_options: + - "httpchk HEAD / HTTP/1.0\\r\\nUser-agent:\\ osa-haproxy-healthcheck" + + children: + traefik_all: + children: + traefik_build_nodes: {} + + skydive_all: + children: + skydive_build_nodes: {} + + skydive_agents: + children: + hosts: {} # This is an osa native group, as such nothing needs to be added. Values will be inherited. + + skydive_analyzers: + children: + utility_all: {} # This is an osa native group, as such nothing needs to be added. Values will be inherited. + + elk_all: + children: + elastic-logstash_all: + children: + elastic-logstash: + children: + log_hosts: {} # This is an osa native group, as such nothing needs to be added. Values will be inherited. + + kibana_all: + children: + kibana: + children: + log_hosts: {} # This is an osa native group, as such nothing needs to be added. Values will be inherited. + + fleet_all: + children: + kolide-db_all: + children: + kolide-db: + children: + log_hosts: {} # This is an osa native group, as such nothing needs to be added. Values will be inherited. + + kolide-fleet_all: + children: + kolide-fleet: + children: + log_hosts: {} # This is an osa native group, as such nothing needs to be added. Values will be inherited. + + osquery_all: + children: + osquery: + children: + hosts: {} # This is an osa native group, as such nothing needs to be added. Values will be inherited. + + grafana_all: + children: + grafana: + children: + utility_all: {} # This is an osa native group, as such nothing needs to be added. Values will be inherited. diff --git a/skydive/README.md b/skydive/README.md index 2b03585a..e7ebd45f 100644 --- a/skydive/README.md +++ b/skydive/README.md @@ -106,7 +106,7 @@ While it is possible to integrate skydive into an OSA cloud using environment extensions and `openstack_user_config.yml` additions, the deployment of this system is possible through the use of an inventory overlay. -> The example overlay inventory file inventory/osa-integration-inventory.yml +> The example overlay inventory file `inventory/osa-integration-inventory.yml` assumes elasticsearch is already deployed and is located on the baremetal machine(s) within the log_hosts group. If this is not the case, adjust the overlay inventory for your environment. @@ -117,7 +117,7 @@ source bootstrap-embedded-ansible.sh # Run the skydive deployment NOTE: This is using multiple inventories. ansible-playbook -i /opt/openstack-ansible/inventory/dynamic_inventory.py \ - -i /opt/openstack-ansible/ops/skydive/inventory/osa-integration-inventory.yml \ + -i /opt/openstack-ansible-ops/overlay-inventories/osa-integration-inventory.yml \ -e @/etc/openstack_deploy/user_secrets.yml \ site.yml @@ -127,10 +127,13 @@ deactivate # If using haproxy, run the haproxy playbook using the multiple inventory sources. cd /opt/openstack-ansible/playbooks openstack-ansible -i /opt/openstack-ansible/inventory/dynamic_inventory.py \ - -i /opt/openstack-ansible/ops/skydive/inventory/osa-integration-inventory.yml \ + -i /opt/openstack-ansible-ops/overlay-inventories/osa-integration-inventory.yml \ haproxy-install.yml ``` +More on using overlay inventories can be seen in the `overlay-inventory` +directory. + ##### Configuration | Haproxy The example overlay inventory contains a section for general haproxy diff --git a/skydive/inventory/osa-integration-inventory.yml b/skydive/inventory/osa-integration-inventory.yml deleted file mode 100644 index a634a66e..00000000 --- a/skydive/inventory/osa-integration-inventory.yml +++ /dev/null @@ -1,63 +0,0 @@ ---- - -all_systems: - vars: {} - children: - systems: - vars: - ansible_become: yes - ansible_become_user: "root" - ansible_user: "root" - skydive_password: "{{ haproxy_stats_password }}" - skydive_elasticsearch_servers: "{{ groups['elastic-logstash'] | map('extract', hostvars, ['ansible_host']) | list | join(',') }}" - skydive_bind_address: "{{ container_address | default(ansible_host) }}" - elastic_skydive_retention: 2 # Elastic retention set to 2 days max - elastic_skydive_size: 51200 # Elastic retention set to 50GiB max - haproxy_extra_services: - - service: - haproxy_service_name: skydive_analyzer - haproxy_backend_nodes: "{{ groups['skydive_analyzers'] | default([]) }}" - haproxy_bind: "{{ [internal_lb_vip_address] }}" - haproxy_port: 8082 - haproxy_balance_type: http - haproxy_ssl: true - haproxy_backend_options: - - "httpchk HEAD / HTTP/1.0\\r\\nUser-agent:\\ osa-haproxy-healthcheck" - - service: - haproxy_service_name: traefik - haproxy_backend_nodes: "{{ groups['skydive_analyzers'] | default([]) }}" - haproxy_bind: "{{ [internal_lb_vip_address] }}" - haproxy_port: 8090 - haproxy_balance_type: http - haproxy_ssl: true - haproxy_backend_options: - - "httpchk HEAD / HTTP/1.0\\r\\nUser-agent:\\ osa-haproxy-healthcheck" - haproxy_backend_httpcheck_options: - - expect rstatus 200|401 - - children: - traefik_all: - children: - traefik_build_nodes: {} - - skydive_all: - children: - skydive_build_nodes: {} - - skydive_agents: - children: - hosts: {} # This is an osa native group, as such nothing needs to be added. Values will be inherited. - - skydive_analyzers: - children: - utility_all: {} # This is an osa native group, as such nothing needs to be added. Values will be inherited. - - elk_all: - children: - elastic-logstash: - children: - log_hosts: {} # This is an osa native group, as such nothing needs to be added. Values will be inherited. - - kibana: - children: - log_hosts: {} # This is an osa native group, as such nothing needs to be added. Values will be inherited.