diff --git a/roles/filebeat/TODO.md b/roles/filebeat/TODO.md new file mode 100644 index 000000000..bb0c7ba1a --- /dev/null +++ b/roles/filebeat/TODO.md @@ -0,0 +1,2 @@ +- deploy certificates +- fix warnings diff --git a/roles/filebeat/defaults/main.yml b/roles/filebeat/defaults/main.yml index 1723b8c41..42fe68408 100644 --- a/roles/filebeat/defaults/main.yml +++ b/roles/filebeat/defaults/main.yml @@ -1,2 +1,20 @@ -filebeat_tls: False -filebeat_eblog: False +filebeat_tls: false +filebeat_eblog: false +filebeat_major_version: 7 +filebeat_apt_url: "https://artifacts.elastic.co/packages/oss-{{ filebeat_major_version }}.x/apt" +# add instances to group or host vars: +# filebeat_instances: +# - name: filebeat_sc_prd +# description: "Filebeat instance to send logs to logstash" # description for systemd unit file +# logpaths: +# - "/opt/openconext/logs/apps/prod_sc/eb/eb.log" +# - "/opt/openconext/logs/log_logins/prod_sc/eb-authentication.log" +# fields: +# - "env: prod_sc" +# logstash_hosts: '["logstashserver.example.com:5044","logstashserver2.example.com:5044"]' +# logstash_ca_path: "/etc/pki/tls/certs" +# logstash_ca: "{{ logstash_ca_path }}/logstash-prod-ca.pem" +# cacert_content: | +# -----BEGIN CERTIFICATE----- +# MIIEKzCCAxOgAwIBAgIJAMjE1SXBf9RJMA0GCSqGSIb3DQEBBQUAMIGqMQswCQYD +# VQQGEwJOTDEQMA4GA1UECAwHVXRyZWNodDEQMA4GA1UEBwwHVXRyZWNodDEVMBMG diff --git a/roles/filebeat/handlers/main.yml b/roles/filebeat/handlers/main.yml index 96e15a224..b7b63374e 100644 --- a/roles/filebeat/handlers/main.yml +++ b/roles/filebeat/handlers/main.yml @@ -1,3 +1,9 @@ --- -- name: restart filebeat - service: name=filebeat state=restarted +- name: Restart filebeat + ansible.builtin.service: + name: filebeat_all.target + state: restarted + +- name: Reload systemd + ansible.builtin.systemd_service: + daemon_reload: true diff --git a/roles/filebeat/tasks/main.yml b/roles/filebeat/tasks/main.yml index 67a93a73a..61c642d60 100644 --- a/roles/filebeat/tasks/main.yml +++ b/roles/filebeat/tasks/main.yml @@ -1,25 +1,141 @@ --- -- name: Add Elasticsearch GPG key. - rpm_key: - key: http://packages.elasticsearch.org/GPG-KEY-elasticsearch - state: present -- name: Add elasticsearch yum repo - copy: - src: elasticsearch.repo - dest: /etc/yum.repos.d/elasticsearch.repo - mode: 0644 +- name: "/etc/Message for non redhat family servers" + when: ansible_facts['os_family'] != 'Debian' + ansible.builtin.fail: + msg: "Sorry, this role only works on Debian family servers" -- name: Install Filebeat - yum: name=filebeat state=present +- name: "Install filebeat on Debian" + when: ansible_facts["os_family"] == "Debian" + block: - #- name: Install cacert certificate - #copy: src={{ inventory_dir }}/files/certs/elastic_ca.pem dest=/etc/pki/elastic/ + - name: "Gather installed package facts" + ansible.builtin.package_facts: + manager: "apt" -- name: Install filebeat.yml - template: src=filebeat.yml.j2 dest=/etc/filebeat/filebeat.yml + - name: "Determine if Filebeat install is needed" + ansible.builtin.set_fact: + filebeat_install_needed: "{{ 'filebeat' not in ansible_facts.packages }}" + + - name: "Install or upgrade filebeat when it is not installed already" + when: filebeat_install_needed + block: + - name: "Debug ansible facts packages" + ansible.builtin.debug: + msg: "ansible facts packages: {{ ansible_facts.packages }}" + verbosity: 3 + + - name: "Debug file install needed" + ansible.builtin.debug: + msg: "filebeat_install_needed: {{ filebeat_install_needed }}" + verbosity: 2 + + - name: "Ensure keyrings directory exists" + ansible.builtin.file: + path: "/etc/apt/keyrings" + state: "directory" + mode: '0755' + + - name: "Download Elasticsearch GPG key" + ansible.builtin.get_url: + url: "https://artifacts.elastic.co/GPG-KEY-elasticsearch" + dest: "/tmp/GPG-KEY-elasticsearch" + mode: '0644' + + - name: "Dearmor and install Elasticsearch GPG key" + ansible.builtin.command: gpg --dearmor -o /etc/apt/keyrings/elasticsearch.gpg /tmp/GPG-KEY-elasticsearch + args: + creates: "/etc/apt/keyrings/elasticsearch.gpg" + + - name: "Add Elasticsearch repository" + ansible.builtin.template: + src: "elastic.list.j2" + dest: "/etc/apt/sources.list.d/elastic.list" + mode: '0644' + + - name: "Update the repository cache and install filebeat" + ansible.builtin.apt: + name: "filebeat" + state: "present" + update_cache: true + +- name: "Create configuration directories for all instances" + ansible.builtin.file: + path: "/etc/{{ item.name }}" + state: "directory" + owner: "root" + group: "root" + mode: "0755" + loop: "{{ filebeat_instances }}" + +- name: "Create configuration files for all instances" + ansible.builtin.template: + dest: "/etc/{{ item.name }}/filebeat.yml" + src: "filebeat.yml.j2" + owner: "root" + group: "root" + mode: "0644" + loop: "{{ filebeat_instances }}" + notify: "Restart filebeat" + +- name: "Create pem directory if necessary" + ansible.builtin.file: + dest: "{{ item.logstash_ca_path }}" + state: "directory" + owner: "root" + group: "root" + mode: "0755" + loop: "{{ filebeat_instances }}" + when: item.logstash_ca_path is defined + +- name: "Create pem file if necessary" + ansible.builtin.template: + dest: "{{ item.logstash_ca }}" + src: "ca_cert.j2" + owner: "root" + group: "root" + mode: "0644" + loop: "{{ filebeat_instances }}" + when: item.logstash_ca is defined + notify: "Restart filebeat" + +- name: "Create custom systemd files in /etc/systemd/system" + ansible.builtin.template: + dest: "/etc/systemd/system/{{ item.name }}.service" + src: "filebeat.item.service.j2" + owner: "root" + group: "root" + mode: "0755" + loop: "{{ filebeat_instances }}" notify: - - restart filebeat + - "Restart filebeat" + - "Reload systemd" + +- name: "Create systemd file in /etc/systemd/system for managing all filebeat services" + ansible.builtin.template: + dest: "/etc/systemd/system/filebeat_all.target" + src: "filebeat.target.j2" + owner: "root" + group: "root" + mode: "0644" + notify: + - "Restart filebeat" + - "Reload systemd" + +- name: "Disable and stop service filebeat" # Because we have custom instances + ansible.builtin.service: + name: "filebeat" + state: "stopped" + enabled: false + +- name: Enable filebeat instances services + ansible.builtin.service: + name: "{{ item.name }}" + enabled: true + loop: "{{ filebeat_instances }}" -- name: Enable and start filebeat - service: name=filebeat state=started enabled=yes +- name: Enable and start service filebeat_all + ansible.builtin.service: + name: filebeat_all.target + state: started + enabled: true diff --git a/roles/filebeat/templates/ca_cert.j2 b/roles/filebeat/templates/ca_cert.j2 new file mode 100644 index 000000000..e33a5fd59 --- /dev/null +++ b/roles/filebeat/templates/ca_cert.j2 @@ -0,0 +1 @@ +{{ item.cacert_content | default ("") }} \ No newline at end of file diff --git a/roles/filebeat/templates/elastic.list.j2 b/roles/filebeat/templates/elastic.list.j2 new file mode 100644 index 000000000..33285265c --- /dev/null +++ b/roles/filebeat/templates/elastic.list.j2 @@ -0,0 +1 @@ +deb [signed-by=/etc/apt/keyrings/elasticsearch.gpg] {{ filebeat_apt_url }} stable main \ No newline at end of file diff --git a/roles/filebeat/templates/filebeat.item.service.j2 b/roles/filebeat/templates/filebeat.item.service.j2 new file mode 100644 index 000000000..259198b85 --- /dev/null +++ b/roles/filebeat/templates/filebeat.item.service.j2 @@ -0,0 +1,14 @@ +[Unit] +Description={{ item.description }} +Documentation=https://www.elastic.co/products/beats/filebeat +PartOf=filebeat_all.target + +[Service] +Environment="BEAT_LOG_OPTS=-e" +Environment="BEAT_CONFIG_OPTS=-c /etc/{{ item.name }}/filebeat.yml" +Environment="BEAT_PATH_OPTS=--path.home /usr/share/filebeat --path.config /etc/{{ item.name }} --path.data /var/lib/{{ item.name }} --path.logs /var/log/{{ item.name }}" +ExecStart=/usr/share/filebeat/bin/filebeat $BEAT_LOG_OPTS $BEAT_CONFIG_OPTS $BEAT_PATH_OPTS +Restart=always + +[Install] +WantedBy=filebeat_all.target diff --git a/roles/filebeat/templates/filebeat.target.j2 b/roles/filebeat/templates/filebeat.target.j2 new file mode 100644 index 000000000..d4fabf018 --- /dev/null +++ b/roles/filebeat/templates/filebeat.target.j2 @@ -0,0 +1,6 @@ +[Unit] +Description=Filebeat services group +After=network.target + +[Install] +WantedBy=multi-user.target diff --git a/roles/filebeat/templates/filebeat.yml.j2 b/roles/filebeat/templates/filebeat.yml.j2 index 3ad227cdd..871709574 100644 --- a/roles/filebeat/templates/filebeat.yml.j2 +++ b/roles/filebeat/templates/filebeat.yml.j2 @@ -1,29 +1,40 @@ -filebeat.prospectors: +# filebeat.inputs: +# - type: log +# allow_deprecated_use: true +# enabled: true +# paths: +# - /var/log/*.log +# +# output.file: +# path: "/tmp/filebeat-output" +# filename: filebeat.json -{% if filebeat_eblog %} +filebeat.inputs: - type: log paths: - - /var/log/messages - include_lines: ["EBLOG"] - fields: - prog: EBLOG - env: {{ env }} - fields_under_root: true -{% endif %} + {%- for logpath in item.logpaths %} + + - {{ logpath -}} + {% endfor %} -- type: log - paths: - - /var/log/messages - include_lines: ['EBAUTH'] - exclude_lines: ['influxd'] fields: - prog: EBAUTH - env: {{ env }} - fields_under_root: true + {%- for field in item.fields %} + {{ field -}} + {% endfor %} + fields_under_root: true +filebeat.config.modules: + path: ${path.config}/modules.d/*.yml + reload.enabled: false +setup.template.settings: + index.number_of_shards: 1 +setup.kibana: +processors: + - drop_fields: + fields: ["host"] output.logstash: - hosts: ["logstash.{{ base_domain }}:5044"] - {% if filebeat_tls %} - ssl.certificate_authorities: ["/etc/pki/filebeat/filebeat_ca.pem"] - {% endif %} + hosts: {{ item.logstash_hosts }} +{% if item.logstash_ca is defined %} + ssl.certificate_authorities: ["{{ item.logstash_ca }}"] +{% endif %} diff --git a/roles/galera/tasks/cluster_nodes.yml b/roles/galera/tasks/cluster_nodes.yml index 398c829a5..c93de8062 100644 --- a/roles/galera/tasks/cluster_nodes.yml +++ b/roles/galera/tasks/cluster_nodes.yml @@ -220,7 +220,7 @@ mysql_user: name: "{{ mariadb_cluster_user }}" password: "{{ mariadb_cluster_password }}" - priv: "{{ mariadb_cluster_user_privs | default('*.*:RELOAD,PROCESS,LOCK TABLES,BINLOG MONITOR,SLAVE MONITOR') }}" + priv: "{{ mariadb_cluster_user_privs | default('*.*:RELOAD, PROCESS, LOCK TABLES, BINLOG MONITOR, SUPER') }}" state: present login_user: root login_password: "{{ mariadb_root_password }}" diff --git a/roles/rsyslog/tasks/main.yml b/roles/rsyslog/tasks/main.yml index 0eef86d46..e4fc916b2 100644 --- a/roles/rsyslog/tasks/main.yml +++ b/roles/rsyslog/tasks/main.yml @@ -13,7 +13,7 @@ name: - python3-dateutil state: present - when: "'sysloghost' in group_names and ansible_distribution_major_version > '7'" + when: "'centrallog_servers' in group_names and ansible_distribution_major_version > '7'" notify: - "restart rsyslog" @@ -23,7 +23,7 @@ enabled: true - name: Forwarding journalctl to rsyslog forward syslog to central logserver - when: "'sysloghost' not in group_names" + when: "'centrallog_servers' not in group_names" block: # journald forwards logs to rsyslog @@ -110,10 +110,12 @@ # central logserver -- name: Include tasks for central syslog server - ansible.builtin.include_tasks: rsyslog_central.yml - when: "'sysloghost' in group_names" +- name: Include tasks for configuring the central log server + when: "'centrallog_servers' in group_names" + block: + - name: Include tasks for central syslog server + ansible.builtin.include_tasks: rsyslog_central.yml -- name: Include tasks for authentication log processing - ansible.builtin.include_tasks: process_auth_logs.yml - when: "'auth_processor' in group_names" + - name: Include tasks for authentication log processing + ansible.builtin.include_tasks: process_auth_logs.yml + when: "'auth_processor' in group_names" diff --git a/roles/rsyslog/templates/rsyslog.conf.j2 b/roles/rsyslog/templates/rsyslog.conf.j2 index d0973e866..f77ef1068 100644 --- a/roles/rsyslog/templates/rsyslog.conf.j2 +++ b/roles/rsyslog/templates/rsyslog.conf.j2 @@ -39,7 +39,7 @@ $MarkMessagePeriod 600 $PreserveFQDN on # Order is important here: First the templates, then rules, then listerers, then forwarders -{% if 'sysloghost' in group_names %} +{% if 'centrallog_servers' in group_names %} # This directory contains templates for a central syslog host $IncludeConfig /etc/rsyslog.d/templates/*.conf {% endif %} @@ -71,7 +71,7 @@ uucp,news.crit /var/log/spooler # Save boot messages also to boot.log local7.* /var/log/boot.log -{% if 'sysloghost' in group_names %} +{% if 'centrallog_servers' in group_names %} # Make the logs readable $DirCreateMode 0775 $FileCreateMode 0640 @@ -88,7 +88,7 @@ module(load="imudp") input(type="imudp" port="514") -{% if 'sysloghost' in group_names %} +{% if 'centrallog_servers' in group_names %} # Now we include all the listeners module(load="imrelp" ) $IncludeConfig /etc/rsyslog.d/listeners/*.conf @@ -101,7 +101,7 @@ $IncludeConfig /etc/rsyslog.d/listeners/*.conf # Remote Logging (we use TCP for reliable delivery) # -{% if rsyslog_remote_server_relp is defined and 'sysloghost' not in group_names %} +{% if rsyslog_remote_server_relp is defined and 'centrallog_servers' not in group_names %} # Forward all logs to the central logging server using relp module(load="omrelp") action(type="omrelp" diff --git a/roles/rsyslog/templates/rsyslog_onlyforward.conf.j2 b/roles/rsyslog/templates/rsyslog_onlyforward.conf.j2 index 874db8c97..bd612f534 100644 --- a/roles/rsyslog/templates/rsyslog_onlyforward.conf.j2 +++ b/roles/rsyslog/templates/rsyslog_onlyforward.conf.j2 @@ -27,7 +27,7 @@ $PreserveFQDN on $MaxMessageSize {{ rsyslog_maxmessagesize }} {% endif %} -{% if 'sysloghost' not in group_names %} +{% if 'centrallog_servers' not in group_names %} {% for relp_host in relp_remote %} # Logs are forwarded to {{ relp_host.name }} action(type="omrelp"