From 2c0515cfd79c7fdae87c9ecc7aa495916345c012 Mon Sep 17 00:00:00 2001 From: Bertrand Lanson Date: Sat, 23 Dec 2023 23:30:53 +0100 Subject: [PATCH] feat(preflight): consolidate preflight playbook --- molecule/no_tls_multi_node/molecule.yml | 18 +++ molecule/no_tls_multi_node/prepare.yml | 8 +- playbooks/bootstrap.yml | 22 +++ playbooks/{vars => group_vars}/all.yml | 34 +++- playbooks/preflight.yml | 198 +++++++++++++++++++++++- playbooks/prepare.yml | 9 -- 6 files changed, 267 insertions(+), 22 deletions(-) create mode 100644 playbooks/bootstrap.yml rename playbooks/{vars => group_vars}/all.yml (73%) delete mode 100644 playbooks/prepare.yml diff --git a/molecule/no_tls_multi_node/molecule.yml b/molecule/no_tls_multi_node/molecule.yml index 4e1da3c..c7e3776 100644 --- a/molecule/no_tls_multi_node/molecule.yml +++ b/molecule/no_tls_multi_node/molecule.yml @@ -12,14 +12,32 @@ platforms: box: generic/${MOLECULE_TEST_OS} cpus: 4 memory: 4096 + groups: + - vault_servers + - consul_servers + - nomad_servers + children: + - common - name: hashistack02 box: generic/${MOLECULE_TEST_OS} cpus: 4 memory: 4096 + groups: + - vault_servers + - consul_servers + - nomad_servers + children: + - common - name: hashistack03 box: generic/${MOLECULE_TEST_OS} cpus: 4 memory: 4096 + groups: + - vault_servers + - consul_servers + - nomad_servers + children: + - common provisioner: name: ansible config_options: diff --git a/molecule/no_tls_multi_node/prepare.yml b/molecule/no_tls_multi_node/prepare.yml index 8ba524c..b454482 100644 --- a/molecule/no_tls_multi_node/prepare.yml +++ b/molecule/no_tls_multi_node/prepare.yml @@ -1,6 +1,6 @@ --- -- name: Include a playbook from a collection - ansible.builtin.import_playbook: ednxzu.hashistack.preflight.yml +- name: Include bootstrap playbook + ansible.builtin.import_playbook: ednxzu.hashistack.bootstrap.yml -- name: Include a playbook from a collection - ansible.builtin.import_playbook: ednxzu.hashistack.prepare.yml +- name: Include preflight playbook + ansible.builtin.import_playbook: ednxzu.hashistack.preflight.yml diff --git a/playbooks/bootstrap.yml b/playbooks/bootstrap.yml new file mode 100644 index 0000000..ace6e8b --- /dev/null +++ b/playbooks/bootstrap.yml @@ -0,0 +1,22 @@ +--- +# hashistack prepare playbook +- name: "Bootstrap" + hosts: all + gather_facts: true + become: true + tasks: + - name: "Include ednxzu.install_docker" + ansible.builtin.include_role: + name: ednxzu.install_docker + vars: + install_docker_edition: ce + install_docker_auto_update: false + install_docker_start_service: true + install_docker_compose: false + install_docker_compose_version: latest + install_docker_python_packages: true + install_docker_python_packages_version: latest + install_docker_users: + - "{{ ansible_user }}" + install_docker_daemon_options: {} + when: deployment_method == 'docker' diff --git a/playbooks/vars/all.yml b/playbooks/group_vars/all.yml similarity index 73% rename from playbooks/vars/all.yml rename to playbooks/group_vars/all.yml index 0246919..c0c3827 100644 --- a/playbooks/vars/all.yml +++ b/playbooks/group_vars/all.yml @@ -3,14 +3,40 @@ # General options ######## ########################## +enable_vault: "yes" +enable_consul: "yes" +enable_nomad: "yes" +deployment_method: "docker" +api_interface: "eth0" +api_interface_address: "{{ ansible_facts[api_interface]['ipv4']['address'] }}" + +########################## +# Support options ######## +########################## + +hashistack_supported_distributions: + - ubuntu + - debian + +hashistack_supported_distribution_versions: + debian: + - "11" + - "12" + ubuntu: + - "20.04" + - "22.04" + +preflight_enable_host_ntp_checks: true + +vault_required_ports: [8200,8201] +consul_required_ports: [8300,8301,8302,8500,8501,8502,8503,8600] +nomad_required_ports: [] ########################## # Nomad options ########## ########################## -hashi_nomad_install: true -hashi_nomad_auto_update: false hashi_nomad_cni_plugins_install: true hashi_nomad_start_service: true hashi_nomad_cni_plugins_version: latest @@ -29,8 +55,6 @@ hashi_nomad_configuration: {} # Consul options ######### ########################## -hashi_consul_install: true -hashi_consul_auto_update: false hashi_consul_start_service: true hashi_consul_version: latest hashi_consul_deploy_method: host # deployment method, either host or docker. @@ -48,8 +72,6 @@ hashi_consul_configuration: {} # Vault options ########## ########################## -hashi_vault_install: true -hashi_vault_auto_update: false hashi_vault_start_service: true hashi_vault_version: latest hashi_vault_deploy_method: host # deployment method, either host or docker diff --git a/playbooks/preflight.yml b/playbooks/preflight.yml index 3c1ff7f..8fe509b 100644 --- a/playbooks/preflight.yml +++ b/playbooks/preflight.yml @@ -3,7 +3,199 @@ - name: "Preflight" hosts: all gather_facts: true + become: true tasks: - - name: "Debug" - ansible.builtin.debug: - msg: "{{ ansible_hostname }}" + - name: "Checking vault inventory" + ansible.builtin.assert: + that: + - groups['vault_servers'] is defined + - groups['vault_servers'] | length > 0 + fail_msg: >- + The variable `enable_vault` is set to yes, but the vault_servers + group is empty or undefined. You need to set the vault_servers group and populate it, + or set `enable_vault` to no. + when: + - enable_vault | bool + + - name: "Checking consul inventory" + ansible.builtin.assert: + that: + - groups['consul_servers'] is defined + - groups['consul_servers'] | length > 0 + fail_msg: >- + The variable `enable_consul` is set to yes, but the consul_servers + group is empty or undefined. You need to set the consul_servers group and populate it, + or set `enable_consul` to no. + when: + - enable_consul | bool + + - name: "Checking nomad inventory" + ansible.builtin.assert: + that: + - groups['nomad_servers'] is defined + - groups['nomad_servers'] | length > 0 + fail_msg: >- + The variable `enable_nomad` is set to yes, but the nomad_servers + group is empty or undefined. You need to set the nomad_servers group and populate it, + or set `enable_nomad` to no. + when: + - enable_nomad | bool + + - name: "Checking host OS distribution" + ansible.builtin.assert: + that: + - "(ansible_facts.distribution | lower) in hashistack_supported_distributions" + - "(ansible_facts.distribution_version) in hashistack_supported_distribution_versions[(ansible_facts.distribution | lower)]" + fail_msg: >- + Distribution: {{ ansible_facts.distribution }} + Release: {{ ansible_facts.distribution_release }} + Version: {{ ansible_facts.distribution_version }} + This distribution is not supported. + Supported releases are: + {{ hashistack_supported_distribution_versions[(ansible_facts.distribution | lower)] }} + + - name: "Verify host clocks" + when: preflight_enable_host_ntp_checks | bool + block: + - name: "Checking for a running NTP daemon on hosts" # noqa command-instead-of-module + vars: + preflight_host_ntp_daemons: + - chrony + - chronyd + - ntp + - ntpd + - systemd-timesyncd + become: true + ansible.builtin.command: + cmd: "systemctl is-active {{ preflight_host_ntp_daemons | join(' ') }}" + register: _ntp_daemons_active + changed_when: false + failed_when: false + check_mode: false + + - name: "Fail if a NTP daemon is not running" + ansible.builtin.fail: + msg: >- + No host NTP daemon is running. + Please install and configure a host NTP daemon. + Alternatively, set 'preflight_enable_host_ntp_checks' to 'false' to + disable this check if not using one of the following NTP daemons: + chrony, ntpd, systemd-timesyncd. + when: + - _ntp_daemons_active.rc != 0 + + - name: "Checking timedatectl status" + become: true + ansible.builtin.command: timedatectl status + register: timedatectl_status + changed_when: false + check_mode: false + + - name: "Fail if the clock is not synchronized" + ansible.builtin.fail: + msg: >- + timedatectl sees the system clock as unsynchronized. + Please wait for synchronization. + Alternatively, set 'preflight_enable_host_ntp_checks' to 'false' to + disable this check if your NTP daemon is not recognised by + 'timedatectl status'. + when: + - "'synchronized: yes' not in timedatectl_status.stdout" + + - name: "Ensure /etc/localtime exists" + ansible.builtin.stat: + path: /etc/localtime + register: _etc_localtime + + - name: "Fail if /etc/localtime is absent" + ansible.builtin.fail: + msg: >- + /etc/localtime is not found. This file is used for system-wide time + settings and needs to be mounted to containers. + when: not _etc_localtime.stat.exists + + - name: "Ensure /etc/timezone exists" + ansible.builtin.stat: + path: /etc/timezone + register: _etc_timezone + + - name: "Fail if /etc/timezone is absent" + ansible.builtin.fail: + msg: >- + /etc/timezone is not found. This file is used for system-wide timezone + settings and needs to be mounted to containers. + when: not _etc_timezone.stat.exists + + - name: "Checking the api_interface is present" + ansible.builtin.fail: + msg: "Please check the api_interface property - interface {{ api_interface }} not found" + when: api_interface not in ansible_facts.interfaces + + - name: "Verify api interface(s)" + when: inventory_hostname not in groups['deployment'] | default([]) + block: + - name: "Checking the api_interface is active" + ansible.builtin.fail: + msg: "Please check the api_interface settings - interface {{ api_interface }} is not active" + when: not hostvars[inventory_hostname].ansible_facts[api_interface]['active'] + + - name: "Debug" + ansible.builtin.debug: + msg: "{{ api_interface_address }}" + + - name: "Checking the api_interface ip address configuration" + ansible.builtin.fail: + msg: "Please check the api_interface settings - interface {{ api_interface }} ip address problem" + when: api_interface_address is not defined + + - name: "Verify required ports" + block: + - name: "Checking if vault ports are available" + when: inventory_hostname in groups['vault_servers'] + block: + - name: "Checking if vault ports are available" + ansible.builtin.wait_for: + host: "{{ inventory_hostname }}" + port: "{{ item }}" + state: "stopped" + timeout: 5 + loop: "{{ vault_required_ports }}" + ignore_errors: true + register: vault_port_results + + - name: "Assert that vault ports are not currently in use" + ansible.builtin.assert: + that: + - item.failed == false + with_items: "{{ vault_port_results.results }}" + when: vault_port_results.results | length > 0 + + - name: "Checking if system uses systemd" + become: true + ansible.builtin.assert: + that: + - "ansible_facts.service_mgr == 'systemd'" + when: inventory_hostname in groups['common'] + + # - name: "Checking that docker is installed" + # when: deployment_method == 'docker' + # block: + + - name: "Checking that python SDK for docker is installed" + when: deployment_method == 'docker' + vars: + wanted_docker_sdk_package: "python3-docker" + block: + - name: "Get packages facts" + ansible.builtin.package_facts: + manager: auto + + - name: "Checking that python SDK for docker is installed" + ansible.builtin.assert: + that: + - "wanted_docker_sdk_package in ansible_facts.packages" + fail_msg: >- + The python sdk for docker is really out of date, you need to install + a more recent version of it in order to use this tool. + + - ansible.builtin.fail: \ No newline at end of file diff --git a/playbooks/prepare.yml b/playbooks/prepare.yml deleted file mode 100644 index cdddbbd..0000000 --- a/playbooks/prepare.yml +++ /dev/null @@ -1,9 +0,0 @@ ---- -# hashistack prepare playbook -- name: "Prepare" - hosts: all - gather_facts: true - tasks: - - name: "Include ednxzu.install_docker" - ansible.builtin.include_role: - name: ednxzu.install_docker