diff --git a/README.md b/README.md index a6be0f6e8c68e08b571a4354ef1d344a8818d239..a09500cf2252a5adb4f2eff17c310e21681cc3ed 100644 --- a/README.md +++ b/README.md @@ -35,11 +35,22 @@ graylog_sidecar_server_api_token: ## Node Certificates For node certificates to be generated you will need to create an additional host group -named `sidecar-ca` with a single host, that stores the CA certificate that should be -used for client certificate generation. +named `sidecar-ca` with a single host (or multiple but only the first will be used), +that stores the CA certificate that should be used for client certificate generation. -The CA file must be available at: `/etc/graylog/sidecar/sidecar-ca.pem` -The CA file's key must be available at: `/etc/graylog/sidecar/sidecar-ca.key` +In addition, the CA certificate that was used to create the certificates for the Graylog +nodes themselves must also be available to be distributed, as it is required for TLS +communication of `filebeat` for example. Therefore, make the graylog nodes available +via a host group called `graylog-nodes`. + +You may also use a completely separate host to store the CA files for Graylog and the +Sidecar service. If this is the case, you need to set the `use_central_ca_host` variable +to `true` and provide a host group called `ca-store`. The other groups mentioned earlier +may be omitted. + +The log node CA file must be available at: `/etc/graylog/graylog-ca.pem` +The sidecar CA file must be available at: `/etc/graylog/sidecar/sidecar-ca.pem` +The sidecar CA file's key must be available at: `/etc/graylog/sidecar/sidecar-ca.key` The location of the files can be configured via variable. The name of the files however must be as specified. The following variables are available in regard to the node @@ -49,9 +60,16 @@ certificates. # Whether to generate node certificates (default: true) generate_node_certs: true +# Whether to use a central host to obtain the required certificates from (default: false) +use_central_ca_host: false + # The local directory where certs are stored before being uploaded tmp_cert_dir: "/tmp/graylog-sidecar-certs" +# The path where the CA certificate of the graylog nodes should be +# fetched from the remote machine specified in the 'graylog-nodes' host group +gl_node_ca_path: "/etc/graylog/" + # The path where the CA certificate and key should be fetched from # the remote machine specified in the 'sidecar-ca' host group gl_sidecar_ca_path: "/etc/graylog/sidecar" diff --git a/defaults/main.yml b/defaults/main.yml index bc9969e18a73ea3ede70f9fe3d09cb00e193b79a..74e7a336b708cdb13d22019a07fb6beec4eb556d 100644 --- a/defaults/main.yml +++ b/defaults/main.yml @@ -12,7 +12,6 @@ filebeat_repo_urls: # --- OTHER --- generate_node_certs: true -tmp_cert_dir: "/tmp/graylog-sidecar-certs" # local directory gl_sidecar_ca_path: "/etc/graylog/sidecar" sidecar_cert_dir: "/etc/graylog/sidecar" cert_valid_days: 1095 diff --git a/tasks/filebeat.yml b/tasks/filebeat.yml index 174651e13c3115946a9f795a24fbf5157d806677..e94f359a8c594ae7738428ca65649cbb9f3c2ca5 100644 --- a/tasks/filebeat.yml +++ b/tasks/filebeat.yml @@ -1,39 +1,37 @@ -- name: Run filebeat tasks - when: (groups['sidecar-ca'] is defined | ternary(inventory_hostname not in groups['sidecar-ca'], true)) +--- +- name: Add filebeat repository (Debian | Ubuntu) + become: true + when: ansible_os_family == 'Debian' block: - - name: Add filebeat repository (Debian | Ubuntu) - become: true - when: ansible_os_family == 'Debian' - block: - - name: Ensure Apt Can Use Https - ansible.builtin.apt: - name: apt-transport-https - state: present - - - name: Ensure ES Signing Key Is Present - ansible.builtin.apt_key: - url: 'https://artifacts.elastic.co/GPG-KEY-elasticsearch' - id: '46095ACC8548582C1A2699A9D27D666CD88E42B4' - state: present^ + - name: Ensure Apt Can Use Https + ansible.builtin.apt: + name: apt-transport-https + state: present - - name: Ensure ES Repo Is Enabled - ansible.builtin.apt_repository: - repo: "deb {{ filebeat_repo_urls['Debian'] }} stable main" - state: present + - name: Ensure ES Signing Key Is Present + ansible.builtin.apt_key: + url: 'https://artifacts.elastic.co/GPG-KEY-elasticsearch' + id: '46095ACC8548582C1A2699A9D27D666CD88E42B4' + state: present^ - - name: Add filebeat repository (RedHat) - ansible.builtin.yum_repository: - name: elastic-8.x - description: Elastic Yum Repo 8.x - baseurl: "{{ filebeat_repo_urls['RedHat'] }}" - gpgcheck: true - gpgkey: 'https://artifacts.elastic.co/GPG-KEY-elasticsearch' + - name: Ensure ES Repo Is Enabled + ansible.builtin.apt_repository: + repo: "deb {{ filebeat_repo_urls['Debian'] }} stable main" state: present - when: ansible_os_family == 'RedHat' - become: true - - name: Install filebeat package - ansible.builtin.package: - name: filebeat - state: present - become: true +- name: Add filebeat repository (RedHat) + ansible.builtin.yum_repository: + name: elastic-8.x + description: Elastic Yum Repo 8.x + baseurl: "{{ filebeat_repo_urls['RedHat'] }}" + gpgcheck: true + gpgkey: 'https://artifacts.elastic.co/GPG-KEY-elasticsearch' + state: present + when: ansible_os_family == 'RedHat' + become: true + +- name: Install filebeat package + ansible.builtin.package: + name: filebeat + state: present + become: true diff --git a/tasks/main.yml b/tasks/main.yml index 25aa8268f16b937c90a6f0e2da1429f6aed7e007..a372e1049edcc76772f632b422d16988bf5cd485 100644 --- a/tasks/main.yml +++ b/tasks/main.yml @@ -5,13 +5,64 @@ changed_when: false become: true -- name: Include sidecar tasks - ansible.builtin.include_tasks: sidecar.yml - when: (groups['sidecar-ca'] is defined | ternary(inventory_hostname not in groups['sidecar-ca'], true)) +- name: Verify that host groups are available if not using a single host + when: not use_central_ca_host + block: + - name: Fail if 'sidecar-ca' host group is missing # noqa: run_once[task] + ansible.builtin.fail: + msg: "Please add a host group 'sidecar-ca' with the host(s) storing the CA file first" + run_once: true + when: "not (groups['sidecar-ca'] is defined)" -- name: Include filebeat tasks - ansible.builtin.import_tasks: filebeat.yml - when: install_filebeat and (groups['sidecar-ca'] is defined | ternary(inventory_hostname not in groups['sidecar-ca'], true)) + - name: Fail if 'graylog-nodes' host group is missing # noqa: run_once[task] + ansible.builtin.fail: + msg: "Please add a host group 'graylog-nodes' with the host(s) storing the log node CA file first" + run_once: true + when: "not (groups['graylog-nodes'] is defined)" + +- name: Fail if 'ca-store' host group is missing while using opetion 'use_central_ca_host' # noqa: run_once[task] + ansible.builtin.fail: + msg: "Please add a host group 'sidecar-ca' with the host(s) storing the CA file first" + run_once: true + when: "(not (groups['ca-store'] is defined)) and use_central_ca_host" + +- name: Include tasks when not using single ca-host + when: not use_central_ca_host + block: + - name: Include sidecar tasks (when not using a single ca store) + ansible.builtin.include_tasks: sidecar.yml + when: > + (inventory_hostname not in groups['sidecar-ca']) and + (inventory_hostname not in groups['graylog-nodes']) + + - name: Include filebeat tasks + ansible.builtin.include_tasks: filebeat.yml + when: > + install_filebeat and + (inventory_hostname not in groups['sidecar-ca']) and + (inventory_hostname not in groups['graylog-nodes']) + +- name: Include tasks when using single ca-host + when: use_central_ca_host + block: + - name: Include sidecar tasks (when using a single ca store) + ansible.builtin.include_tasks: sidecar.yml + when: > + ((groups['sidecar-ca'] is defined) and (groups['graylog-nodes'] is defined) | ternary( + (inventory_hostname not in groups['sidecar-ca']) and + (inventory_hostname not in groups['graylog-nodes']) + , true)) and + (inventory_hostname not in groups['ca-store']) + + - name: Include filebeat tasks + ansible.builtin.include_tasks: filebeat.yml + when: > + install_filebeat and + ((groups['sidecar-ca'] is defined) and (groups['graylog-nodes'] is defined) | ternary( + (inventory_hostname not in groups['sidecar-ca']) and + (inventory_hostname not in groups['graylog-nodes']) + , true)) and + (inventory_hostname not in groups['ca-store']) - name: Switch back to default policy ansible.builtin.command: diff --git a/tasks/node-certs.yml b/tasks/node-certs.yml index 2f190396ac756e5328e9c9e56bf5af421c1190e7..21840ad483b8d81c57730e2bb5336024be95f8d3 100644 --- a/tasks/node-certs.yml +++ b/tasks/node-certs.yml @@ -1,17 +1,11 @@ --- -- name: Fail if 'sidecar-ca' host group is missing # noqa: run_once[task] - ansible.builtin.fail: - msg: "Please add a host group 'sidecar-ca' with the host(s) storing the CA file first" - run_once: true - when: "not (groups['sidecar-ca'] is defined)" - - name: Node Certificates | Create temporary directopry for certificates # noqa: run_once[task] - ansible.builtin.file: - path: "{{ tmp_cert_dir }}" + ansible.builtin.tempfile: state: directory - mode: 0755 + prefix: "graylog." run_once: true delegate_to: localhost + register: tmp_cert_dir - name: Node Certificates | Fetch Sidecar CA Cert ansible.builtin.fetch: @@ -21,13 +15,21 @@ with_items: - "{{ gl_sidecar_ca_path }}/sidecar-ca.pem" - "{{ gl_sidecar_ca_path }}/sidecar-ca.key" - delegate_to: "{{ groups['sidecar-ca'] | first }}" + delegate_to: "{{ groups[use_central_ca_host | bool | ternary('ca-store', 'sidecar-ca')] | first }}" + become: true + run_once: true + +- name: Node Certificates | Fetch Graylog Node CA Cert + ansible.builtin.fetch: + src: "{{ gl_node_ca_path }}/graylog-ca.pem" + dest: "{{ tmp_cert_dir }}/" + flat: true + delegate_to: "{{ groups[use_central_ca_host | bool | ternary('ca-store', 'graylog-nodes')] | first }}" become: true run_once: true - name: Node Certificates delegate_to: localhost - when: (groups['sidecar-ca'] is defined | ternary(inventory_hostname not in groups['sidecar-ca'], true)) block: - name: Node Certificates | Generate private keys community.crypto.openssl_privatekey: @@ -55,7 +57,6 @@ - name: Node Certificates | Copy Certificates become: true - when: (groups['sidecar-ca'] is defined | ternary(inventory_hostname not in groups['sidecar-ca'], true)) block: - name: Node Certificates | Copy Node certificates ansible.builtin.copy: @@ -66,3 +67,4 @@ - { file: "sidecar-{{ inventory_hostname }}.key", mode: "0600" } - { file: "sidecar-{{ inventory_hostname }}.pem", mode: "0644" } - { file: "sidecar-ca.pem", mode: "0644" } + - { file: "graylog-ca.pem", mode: "0644" } diff --git a/templates/sidecar.yml.j2 b/templates/sidecar.yml.j2 index 82b2c31c80d87759af8516e33ea195a95f808a86..f55db498091db756f5ea264a098d939368420da2 100644 --- a/templates/sidecar.yml.j2 +++ b/templates/sidecar.yml.j2 @@ -2,4 +2,4 @@ server_url: {{ graylog_sidecar_server_url }} server_api_token: {{ graylog_sidecar_server_api_token }} -node_id: {{ graylog_sidecar_node_id }} \ No newline at end of file +node_id: {{ graylog_sidecar_node_id }}