From 0acba684434e5dfe7e4a232a66c0ccece5215e91 Mon Sep 17 00:00:00 2001 From: ace Date: Thu, 28 Jul 2022 17:14:26 +0300 Subject: [PATCH] first commit --- .gitignore | 1 + defaults/main.yaml | 30 ++++++++++++++++++++++++ handlers/main.yaml | 8 +++++++ meta/main.yaml | 0 tasks/Debian/main.yaml | 45 ++++++++++++++++++++++++++++++++++++ tasks/RedHat/main.yaml | 35 ++++++++++++++++++++++++++++ tasks/bootstrap.yaml | 52 ++++++++++++++++++++++++++++++++++++++++++ tasks/config.yaml | 34 +++++++++++++++++++++++++++ tasks/join.yaml | 3 +++ tasks/main.yaml | 42 ++++++++++++++++++++++++++++++++++ tasks/pre_check.yaml | 33 +++++++++++++++++++++++++++ vars/Debian.yaml | 8 +++++++ vars/RedHat.yaml | 1 + vars/main.yaml | 1 + 14 files changed, 293 insertions(+) create mode 100644 .gitignore create mode 100644 defaults/main.yaml create mode 100644 handlers/main.yaml create mode 100644 meta/main.yaml create mode 100644 tasks/Debian/main.yaml create mode 100644 tasks/RedHat/main.yaml create mode 100644 tasks/bootstrap.yaml create mode 100644 tasks/config.yaml create mode 100644 tasks/join.yaml create mode 100644 tasks/main.yaml create mode 100644 tasks/pre_check.yaml create mode 100644 vars/Debian.yaml create mode 100644 vars/RedHat.yaml create mode 100644 vars/main.yaml diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..ba6d390 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +.galaxy_install_info diff --git a/defaults/main.yaml b/defaults/main.yaml new file mode 100644 index 0000000..6919c34 --- /dev/null +++ b/defaults/main.yaml @@ -0,0 +1,30 @@ +consul_version: 1.12.2 +consul_config_path: "/etc/consul.d" +consul_data_path: "/opt/consul" +consul_user: consul +consul_group: consul +consul_install_repo: yes + +consul_cluster_group: consul +consul_server_group: consul_server +consul_agent_group: consul_agent + +consul_config: [] +consul_default_config: + server: "{{ true if inventory_hostname in groups[consul_server_group] else false }}" + ui_config: + enabled: "{{ true if inventory_hostname in groups[consul_server_group] else false }}" + log_level: info + retry_join: "{{ groups[consul_server_group] | default([])}}" + retry_interval: 30s + datacenter: "main" + bootstrap_expect: "{{ groups[consul_server_group]|length|int if inventory_hostname in groups[consul_server_group] else omit }}" + performance: + raft_multiplier: 1 + acl: + enabled: false + default_policy: deny + down_policy: extend-cache + enable_token_persistence: true + +is_virtualenv: "{{ lookup('env','VIRTUAL_ENV') | default('') }}" diff --git a/handlers/main.yaml b/handlers/main.yaml new file mode 100644 index 0000000..45313be --- /dev/null +++ b/handlers/main.yaml @@ -0,0 +1,8 @@ +- block: + - name: Restart consul + throttle: 1 + ansible.builtin.systemd: + state: restarted + name: consul + daemon_reload: yes + when: not consul_setup.changed diff --git a/meta/main.yaml b/meta/main.yaml new file mode 100644 index 0000000..e69de29 diff --git a/tasks/Debian/main.yaml b/tasks/Debian/main.yaml new file mode 100644 index 0000000..5f05f23 --- /dev/null +++ b/tasks/Debian/main.yaml @@ -0,0 +1,45 @@ +- name: Add gpg package + apt: + name: gpg + +- name: Add gpg keys for consul + ansible.builtin.apt_key: + url: "{{ item.url }}" + keyring: "{{ item.keyring }}" + loop: "{{ consul_apt_key }}" + +- name: Add Hashicorp repository + apt_repository: + repo: "{{ item.repo }}" + state: present + filename: "{{ item.filename }}" + update_cache: yes + loop: "{{ consul_apt_repository }}" + +- name: Check if Consul is installed + ansible.builtin.shell: dpkg-query -l {{ consul_package_name }} 2>&1 | grep {{ consul_version }} + ignore_errors: True + register: is_consul + changed_when: is_consul.rc != 0 + failed_when: False + +- name: Mask Consul before install + ansible.builtin.systemd: + name: "{{ consul_package_name }}" + masked: yes + when: is_consul.rc != 0 + +- name: "Install {{ consul_package_name }}-{{ consul_version }}" + apt: + name: "{{ consul_package }}" + update_cache: yes + register: consul_setup + when: is_consul.rc != 0 + +- name: Fix "/etc/consul.d/consul.env" + copy: + content: "" + dest: /etc/consul.d/consul.env + owner: consul + group: consul + diff --git a/tasks/RedHat/main.yaml b/tasks/RedHat/main.yaml new file mode 100644 index 0000000..e8208a3 --- /dev/null +++ b/tasks/RedHat/main.yaml @@ -0,0 +1,35 @@ +- name: Add Hashicorp repository + yum_repository: + name: hashicorp + description: Hashicorp Stable - $basearch + file: hashicorp + baseurl: https://rpm.releases.hashicorp.com/RHEL/$releasever/$basearch/stable + enabled: no + gpgcheck: yes + gpgkey: https://rpm.releases.hashicorp.com/gpg + when: consul_install_repo + +- name: "Install {{ consul_package_name }}-{{ consul_version }} from official repository" + dnf: + name: "{{ consul_package }}" + state: present + disable_gpg_check: yes + enablerepo: hashicorp + update_cache: yes + register: consul_setup + when: consul_install_repo + +- name: "Install {{ consul_package_name }}-{{ consul_version }}" + dnf: + name: "{{ consul_package }}" + state: present + disable_gpg_check: yes + register: consul_setup + when: not consul_install_repo + +- name: Fix "/etc/consul.d/consul.env" + copy: + content: "" + dest: /etc/consul.d/consul.env + owner: consul + group: consul diff --git a/tasks/bootstrap.yaml b/tasks/bootstrap.yaml new file mode 100644 index 0000000..4e4426f --- /dev/null +++ b/tasks/bootstrap.yaml @@ -0,0 +1,52 @@ +- name: Bootstrap encrypt + block: + - name: Get gossip encryption key on previously boostrapped server + block: + - name: Check for gossip encryption key on previously boostrapped server + slurp: + src: "{{ consul_config_path }}/consul.json" + register: consul_config_b64 + ignore_errors: true + + - name: Deserialize existing configuration + set_fact: + consul_config_local: "{{ consul_config_b64.content | b64decode | from_json }}" + when: consul_config_b64.content is defined + + - name: Save gossip encryption key from existing configuration + set_fact: + consul_raw_key: "{{ consul_config_local.encrypt }}" + delegate_to: "{{ item }}" + delegate_facts: true + run_once: true + loop: "{{ ansible_play_hosts_all }}" + when: consul_config_local.encrypt is defined and consul_config_local.encrypt | length != 0 + + no_log: false + when: + - consul_config.encrypt is not defined or consul_config.encrypt | length == 0 + - cluster_node_list != 0 + - hostvars[inventory_hostname]['ansible_host'] in cluster_node_list + + - name: Generate new key if none was found + block: + - name: Generate gossip encryption key + shell: "consul keygen" + register: consul_keygen + when: + - consul_raw_key is not defined + + - name: Save gossip encryption key as fact + set_fact: + consul_raw_key: "{{ consul_keygen.stdout }}" + delegate_to: "{{ item }}" + delegate_facts: true + loop: "{{ ansible_play_hosts_all }}" + when: + - hostvars[inventory_hostname]['consul_raw_key'] is not defined + no_log: false + run_once: true + when: + - consul_config.encrypt is not defined or consul_config.encrypt | length == 0 + + no_log: false diff --git a/tasks/config.yaml b/tasks/config.yaml new file mode 100644 index 0000000..d1dde2b --- /dev/null +++ b/tasks/config.yaml @@ -0,0 +1,34 @@ +--- +- name: Merge encrypt key with config for Consul + set_fact: + consul_config: "{{ consul_config | combine(consul_config_encrypt, recursive=true) }}" + vars: + consul_config_encrypt: + encrypt: "{{ consul_raw_key }}" + when: + - consul_config.encrypt is not defined + +- name: Merge config for Consul + set_fact: + consul_config_combined: "{{ consul_default_config | combine(consul_config, recursive=true) }}" + +- name: Propagate consul config + copy: + content: "{{ consul_config_combined | to_nice_json }}" + dest: "{{ consul_config_path }}/consul.json" + owner: "{{ consul_user }}" + group: "{{ consul_group }}" + mode: 0644 + register: consul_config_file + notify: Restart consul + +- name: Remove old files + file: + path: "{{ item }}" + state: absent + loop: + - "{{ consul_config_path }}/config.json" + - "{{ consul_data_path }}/serf/local.keyring" + - "{{ consul_data_path }}/serf/remote.keyring" + - "{{ consul_data_path }}/serf/local.snapshot" + when: consul_config_file.changed diff --git a/tasks/join.yaml b/tasks/join.yaml new file mode 100644 index 0000000..51770c0 --- /dev/null +++ b/tasks/join.yaml @@ -0,0 +1,3 @@ +--- +- name: "Join new node to existing cluster" + command: "consul join {{ cluster_node_list | join(' ') }}" diff --git a/tasks/main.yaml b/tasks/main.yaml new file mode 100644 index 0000000..2ff6585 --- /dev/null +++ b/tasks/main.yaml @@ -0,0 +1,42 @@ +- name: Make sure handlers are flushed immediately + meta: flush_handlers + +- name: Load a variable file based on the OS type + include_vars: "{{ lookup('first_found', params) }}" + vars: + params: + files: + - "{{ ansible_facts['distribution'] }}.yaml" + - "{{ ansible_facts['os_family'] }}.yaml" + paths: + - "vars" + +- name: Consul cluster pre-check + include_tasks: pre_check.yaml + when: inventory_hostname in groups[consul_server_group] + +- name: "Install Consul for {{ ansible_facts['os_family'] }}" + include_tasks: "{{ ansible_facts['os_family'] }}/main.yaml" + +- name: Bootstrap Consul + include_tasks: bootstrap.yaml + when: inventory_hostname in groups[consul_server_group] + +- name: Create Consul configuration + import_tasks: config.yaml + +- name: Enable and start Consul + systemd: + daemon_reload: true + name: consul + enabled: true + state: started + masked: no + tags: consul, consul_start + +- name: Join new server node to cluster + import_tasks: join.yaml + when: + - hostvars[inventory_hostname]['ansible_host'] not in cluster_node_list + - cluster_node_list | length != 0 + - inventory_hostname in groups[consul_server_group] diff --git a/tasks/pre_check.yaml b/tasks/pre_check.yaml new file mode 100644 index 0000000..edce063 --- /dev/null +++ b/tasks/pre_check.yaml @@ -0,0 +1,33 @@ +- block: + - name: Set var for cluster nodes list + set_fact: + cluster_node_list: [] + + - name: Get cluster nodes + command: curl http://127.0.0.1:8500/v1/status/peers + environment: + no_proxy: 127.0.0.1 + register: cluster_nodes + changed_when: false + no_log: true + + - name: Print cluster nodes + debug: + msg: "{{ cluster_nodes.stdout }}" + + - name: Print cluster nodes + debug: + msg: "{{ item }}" + loop: "{{ cluster_nodes.stdout | from_json }}" + + - name: Merge cluster nodes list + set_fact: + cluster_node_list: "{{ cluster_node_list + [item|split(':')|first] }}" + loop: "{{ cluster_nodes.stdout | from_json }}" + + - name: Print cluster nodes list + debug: + msg: "{{ cluster_node_list }}" + + run_once: true + ignore_errors: yes diff --git a/vars/Debian.yaml b/vars/Debian.yaml new file mode 100644 index 0000000..70b07e0 --- /dev/null +++ b/vars/Debian.yaml @@ -0,0 +1,8 @@ +consul_package: "{{ consul_package_name }}={{ consul_version }}" +consul_apt_key: + - name: com.hashicorp.gpg + url: "https://apt.releases.hashicorp.com/gpg" + keyring: /etc/apt/trusted.gpg.d/com.hashicorp.gpg +consul_apt_repository: + - repo: deb [arch=amd64] https://apt.releases.hashicorp.com {{ ansible_distribution_release }} main + filename: hashicorp diff --git a/vars/RedHat.yaml b/vars/RedHat.yaml new file mode 100644 index 0000000..c5d8e98 --- /dev/null +++ b/vars/RedHat.yaml @@ -0,0 +1 @@ +consul_package: "{{ consul_package_name }}-{{ consul_version }}" diff --git a/vars/main.yaml b/vars/main.yaml new file mode 100644 index 0000000..0147dfa --- /dev/null +++ b/vars/main.yaml @@ -0,0 +1 @@ +consul_package_name: consul