diff --git a/defaults/main.yml b/defaults/main.yml index 185bfcc..5398209 100644 --- a/defaults/main.yml +++ b/defaults/main.yml @@ -1,7 +1,10 @@ --- # defaults file for ansible-consul +consul_bin_path: "/usr/local/bin" consul_server: True consul_ui: True +consul_config_path: "/etc/consul.d" +consul_bootstrap_state: "{{ consul_config_path }}/.consul_bootstrapped" consul_iface: "{{ ansible_default_ipv4.interface }}" consul_bind_address: "{{ hostvars[inventory_hostname]['ansible_'+ consul_iface | replace('-', '_')]['ipv4']['address']}}" consul_client_addr: "127.0.0.1" @@ -9,8 +12,7 @@ consul_bootstrap: False consul_domain: "consul" consul_data_dir: "/opt/consul" consul_datacenter: "dc1" -consul_gossip_encryption_key: - +consul_encrypt_enable: True consul_ansible_group: "consul" consul_servers_list: "\ {% set _consul_servers_list = [] %}\ diff --git a/tasks/main.yml b/tasks/main.yml index 6edd5e7..ead628f 100644 --- a/tasks/main.yml +++ b/tasks/main.yml @@ -1,4 +1,11 @@ --- +- name: Read bootstrapped state + stat: + path: "{{ consul_bootstrap_state }}" + register: bootstrap_state + ignore_errors: true + + - name: Include OS-specific variables include_vars: "{{ item }}" with_first_found: @@ -19,12 +26,93 @@ path: "{{ consul_data_dir }}" mode: 0755 +- block: + - block: + - name: Check for gossip encryption key on previously boostrapped server + slurp: + src: "{{ consul_config_path }}/config.json" + register: consul_config_b64 + ignore_errors: true + - debug: + msg: "{{consul_config_b64}}" + - name: Deserialize existing configuration + set_fact: + consul_config: "{{ consul_config_b64.content | b64decode | from_json }}" + when: consul_config_b64.content is defined and consul_config_b64.content != "" + + - name: Save gossip encryption key from existing configuration + set_fact: + consul_raw_key: "{{ consul_config.encrypt }}" + when: consul_config is defined + + when: + - consul_raw_key is not defined + - bootstrap_state.stat.exists | bool + - inventory_hostname in consul_servers_list + + # Key provided by extra vars or the above block + - name: Write gossip encryption key locally for use with new servers + copy: + content: "{{ consul_raw_key }}" + dest: '/tmp/consul_raw.key' + mode: 0600 + become: false + vars: + ansible_become: false + no_log: true + delegate_to: localhost + changed_when: false + when: consul_raw_key is defined + + # Generate new key if none was found + - block: + - name: Generate gossip encryption key + shell: "PATH={{ consul_bin_path }}:$PATH consul keygen" + register: consul_keygen + + - name: Write key locally to share with other nodes + copy: + content: "{{ consul_keygen.stdout }}" + dest: '/tmp/consul_raw.key' + become: false + vars: + ansible_become: false + delegate_to: localhost + + no_log: true + run_once: true + when: + # if files '/tmp/consul_raw.key' exist + - lookup('first_found', dict(files=['/tmp/consul_raw.key'], skip=true)) | ternary(false, true) + - not bootstrap_state.stat.exists | bool + + - name: Read gossip encryption key for servers that require it + set_fact: + consul_raw_key: "{{ lookup('file', '/tmp/consul_raw.key') }}" + no_log: true + when: + - consul_raw_key is not defined + + - name: Delete gossip encryption key file + file: + path: '/tmp/consul_raw.key' + state: absent + become: false + vars: + ansible_become: false + run_once: true + delegate_to: localhost + changed_when: false + #no_log: true + when: + - consul_encrypt_enable | bool + - name: apply config template block: - name: server template template: - src: config.hcl.j2 - dest: /etc/consul.d/config.hcl + src: config.json.j2 + dest: "{{ consul_config_path}}/config.json" owner: consul mode: 0644 notify: reload consul configuration @@ -45,11 +133,19 @@ job: "{{ consul_data_dir }}/cs-backup.sh {{ consul_backup_location }}" hour: "{{consul_cron_hour}}" when: consul_snapshot + - name: ensure service is started systemd: name: "{{ consul_service_name }}" state: started enabled: True +- name: Create bootstrapped state file + file: + dest: "{{ consul_bootstrap_state }}" + state: touch + mode: 0600 + when: not bootstrap_state.stat.exists + - include_tasks: dnsmasq.yml when: consul_dnsmasq_enable | bool diff --git a/templates/config.hcl.j2 b/templates/config.json.j2 similarity index 54% rename from templates/config.hcl.j2 rename to templates/config.json.j2 index 81a3b05..b17837b 100644 --- a/templates/config.hcl.j2 +++ b/templates/config.json.j2 @@ -1,35 +1,30 @@ - -bootstrap= {{consul_bootstrap|lower}} -server= {{consul_server|lower}} +{ +"bootstrap": {{consul_bootstrap|lower}}, +"server": {{consul_server|lower}}, {% if consul_server %} -bootstrap_expect= {{consul_bootstrap_expect}} +"bootstrap_expect": {{consul_bootstrap_expect}}, {% endif %} -domain= "{{consul_domain}}" +"domain": "{{consul_domain}}", {% if consul_bind_address %} -bind_addr="{{consul_bind_address}}" +"bind_addr":"{{consul_bind_address}}", {% endif %} {% if consul_client_addr %} -client_addr="{{consul_client_addr}}" -{% endif %} - -{%if consul_ui %} -ui_config { - enabled = true -} -{%endif%} - -{% if consul_gossip_encryption_key %} -encrypt= "{{consul_gossip_encryption_key}}" +"client_addr":"{{consul_client_addr}}", {% endif %} -datacenter= "{{consul_datacenter}}" -data_dir= "{{consul_data_dir}}" -acl { - enabled = false - default_policy = "allow" - enable_token_persistence = true -} +{% if consul_raw_key %} +"encrypt": "{{consul_raw_key}}", +{% endif %} + + +"datacenter": "{{consul_datacenter}}", +"data_dir": "{{consul_data_dir}}", +"acl": { + "enabled": false, + "default_policy": "allow", + "enable_token_persistence": true +}, {%if consul_retry_join_force %} {% for server in consul_retry_join_force %} {% set _ = consul_join.append(server) %} @@ -39,11 +34,15 @@ acl { {% set _ = consul_join.append(hostvars[server]['consul_bind_address'] | default(hostvars[server]['ansible_default_ipv4']['address'],true) | mandatory) %} {% endfor %} {% endif %} -retry_join= {{ consul_join | map('ipwrap') | list | to_json }} +"retry_join": {{ consul_join | map('ipwrap') | list | to_json }}, {% if _consul_wan_servercount | int > 0 %} {% for server in _consul_wan_servers %} {% set _ = consul_join_wan.append(hostvars[server]['consul_bind_address']|default(hostvars[server]['ansible_default_ipv4']['address'],true) | mandatory) %} {% endfor %} -retry_join_wan= {{ consul_join_wan | map('ipwrap') | list | to_json }} +"retry_join_wan": {{ consul_join_wan | map('ipwrap') | list | to_json }}, {% endif %} +"ui_config": { +"enabled": {{consul_ui|bool|to_json}} +} +}