feat(consul): add initial simple consul cluster

This commit is contained in:
Bertrand Lanson 2024-01-25 22:40:44 +01:00
parent 8ce66d42a7
commit 00883b2dec
9 changed files with 170 additions and 26 deletions

View File

@ -0,0 +1,2 @@
#! /bin/sh
vault kv get --field=password kv_hs/ansible/ansible_vault

View File

@ -0,0 +1,8 @@
[defaults]
nocows = true
ansible_python_interpreter=/usr/bin/python3
pipelining = true
host_key_checking = false
deprecation_warnings = true
callbacks_enabled = profile_tasks, profile_roles
vault_password_file = .vault_password

View File

@ -117,3 +117,9 @@ hashi_vault_version: "latest"
# #tls_cert_file: "{{ hashi_vault_data_dir }}/tls/cert.pem" # #tls_cert_file: "{{ hashi_vault_data_dir }}/tls/cert.pem"
# #tls_key_file: "{{ hashi_vault_data_dir }}/tls/key.pem" # #tls_key_file: "{{ hashi_vault_data_dir }}/tls/key.pem"
# storage: "{{ vault_storage_configuration }}" # storage: "{{ vault_storage_configuration }}"
vault_extra_configuration:
user_lockout:
all:
lockout_duration: "10m"
lockout_counter_reset: "10m"

View File

@ -14,6 +14,7 @@
- name: hvac - name: hvac
version_constraint: latest version_constraint: latest
state: present state: present
when: "'vault_servers' in group_names"
- name: "Include ednxzu.install_docker" - name: "Include ednxzu.install_docker"
ansible.builtin.include_role: ansible.builtin.include_role:

View File

@ -18,8 +18,23 @@
ansible.builtin.debug: ansible.builtin.debug:
msg: "{{ hashi_vault_configuration }}" msg: "{{ hashi_vault_configuration }}"
- name: "Debug"
ansible.builtin.debug:
msg: "{{ hashi_consul_configuration }}"
# - ansible.builtin.fail: # - ansible.builtin.fail:
- name: "Consul"
when:
- enable_consul | bool
- "'consul_servers' in group_names"
tags:
- consul
block:
- name: "Include ednxzu.hashistack.hashicorp_consul"
ansible.builtin.include_role:
name: ednxzu.hashistack.hashicorp_consul
- name: "Vault" - name: "Vault"
when: when:
- enable_vault | bool - enable_vault | bool
@ -27,7 +42,7 @@
tags: tags:
- vault - vault
block: block:
- name: "Include ednxzu.hashicorp_vault" - name: "Include ednxzu.hashistack.hashicorp_consul"
ansible.builtin.include_role: ansible.builtin.include_role:
name: ednxzu.hashistack.hashicorp_vault name: ednxzu.hashistack.hashicorp_vault
@ -61,26 +76,15 @@
ednxzu.hashistack.vault_unseal: ednxzu.hashistack.vault_unseal:
api_url: "{{ hashi_vault_configuration['api_addr'] }}" api_url: "{{ hashi_vault_configuration['api_addr'] }}"
key_shares: "{{ _vault_cluster_config['keys'] }}" key_shares: "{{ _vault_cluster_config['keys'] }}"
# max_retries: "{{ (_vault_cluster_config['keys'] | length) - 1 }}"
run_once: true run_once: true
delegate_to: "{{ groups['vault_servers'] | first }}" delegate_to: "{{ groups['vault_servers'] | first }}"
when: _vault_init_secret.changed when: _vault_init_secret.changed
register: _vault_unseal_secret register: _vault_unseal_secret
- name: "Print unseal status"
ansible.builtin.debug:
msg: "{{ _vault_unseal_secret }}"
- name: "Unseal all vault nodes" - name: "Unseal all vault nodes"
ednxzu.hashistack.vault_unseal: ednxzu.hashistack.vault_unseal:
api_url: "{{ hashi_vault_configuration['api_addr'] }}" api_url: "{{ hashi_vault_configuration['api_addr'] }}"
key_shares: "{{ _vault_cluster_config['keys'] }}" key_shares: "{{ _vault_cluster_config['keys'] }}"
# max_retries: "{{ (_vault_cluster_config['keys'] | length) - 1 }}"
retries: 5 retries: 5
delay: 5 delay: 5
register: _unseal_status register: _unseal_status
until: _unseal_status.changed
- name: "Print unseal status"
ansible.builtin.debug:
msg: "{{ _unseal_status }}"

View File

@ -3,8 +3,8 @@
# General options ######## # General options ########
########################## ##########################
enable_vault: "yes" enable_vault: "no"
enable_consul: "no" enable_consul: "yes"
enable_nomad: "no" enable_nomad: "no"
deployment_method: "host" deployment_method: "host"
@ -65,17 +65,103 @@ hashi_nomad_configuration: {}
# Consul options ######### # Consul options #########
########################## ##########################
consul_domain: consul
consul_datacenter: dc1
consul_primary_datacenter: dc1
consul_leave_on_terminate: true
consul_rejoin_after_leave: true
consul_enable_script_checks: true
##############################
# consul address configuration
##############################
consul_address_configuration:
# The address to which Consul will bind client interfaces,
# including the HTTP and DNS servers.
client_addr: "0.0.0.0"
# The address that should be bound to for internal cluster communications.
bind_addr: "{{ api_interface_address }}"
# The advertise address is used to change the address that we advertise to other nodes in the cluster.
advertise_addr: "{{ api_interface_address }}"
##########################
# consul ACL configuration
##########################
consul_acl_configuration:
enabled: false
default_policy: "allow" # can be allow or deny
enable_token_persistence: true
#####################
# extra configuration
#####################
consul_extra_configuration: {}
##########################
# consul DNS configuration
##########################
consul_dns_configuration:
allow_stale: true
enable_truncate: true
only_passing: true
hashi_consul_start_service: true hashi_consul_start_service: true
hashi_consul_version: latest hashi_consul_version: latest
hashi_consul_deploy_method: host # deployment method, either host or docker. hashi_consul_deploy_method: "{{ deployment_method }}"
hashi_consul_env_variables: {} hashi_consul_env_variables: {}
hashi_cosul_config_dir: "/etc/consul.d"
hashi_consul_data_dir: "/opt/consul" hashi_consul_data_dir: "/opt/consul"
hashi_consul_extra_files: false hashi_consul_extra_files: false
hashi_consul_extra_files_src: /tmp/extra_files hashi_consul_extra_files_src: "{{ sub_configuration_directories.consul_servers }}/config"
hashi_consul_extra_files_dst: /etc/consul.d/extra_files hashi_consul_extra_files_dst: "{{ hashi_consul_config_dir }}/config"
hashi_consul_envoy_install: false hashi_consul_envoy_install: false
hashi_consul_envoy_version: latest hashi_consul_envoy_version: latest
hashi_consul_configuration: {} hashi_consul_configuration:
domain: "{{ consul_domain }}"
datacenter: "{{ consul_datacenter }}"
primary_datacenter: "{{ consul_primary_datacenter }}"
data_dir: "{{ hashi_consul_data_dir }}"
encrypt: "{{ 'mysupersecretgossipencryptionkey'|b64encode }}"
server: "{{ 'consul_servers' in group_names }}"
retry_join: "{{
groups['consul_servers'] |
map('extract', hostvars, ['consul_address_configuration', 'bind_addr']) |
list |
to_json |
from_json
}}"
ui_config:
enabled: true
connect:
enabled: false
leave_on_terminate: true
rejoin_after_leave: true
enable_script_checks: true
enable_syslog: true
log_level: INFO
acl: "{{ consul_acl_configuration }}"
dns_config: "{{ consul_dns_configuration }}"
ports:
dns: 8600
http: 8500
https: -1
grpc: 8502
grpc_tls: 8503
server: 8300
serf_lan: 8301
serf_wan: 8302
sidecar_min_port: 21000
sidecar_max_port: 21255
expose_min_port: 21500
expose_max_port: 21755
# this is used to circumvent jinja limitation to convert string to integer
hashi_consul_configuration_string: |
bootstrap_expect: {{ (groups['consul_servers'] | length) }}
########################## ##########################
# Vault options ########## # Vault options ##########
@ -123,6 +209,7 @@ vault_extra_listener_configuration: {}
###################### ######################
# service registration # service registration
###################### ######################
vault_enable_service_registration: false vault_enable_service_registration: false
vault_service_registration_configuration: vault_service_registration_configuration:
consul: consul:

View File

@ -0,0 +1,31 @@
---
# hashistack configuration merging for consul
- name: "Consul | Merge stringified configuration"
vars:
_config_to_merge: "{{ hashi_consul_configuration_string }}"
ansible.builtin.set_fact:
hashi_consul_configuration: "{{
hashi_consul_configuration |
combine(_config_to_merge|from_yaml)
}}"
when: hashi_consul_configuration_string is defined
- name: "Consul | Merge addresses configuration"
vars:
_config_to_merge: "{{ consul_address_configuration }}"
ansible.builtin.set_fact:
hashi_consul_configuration: "{{
hashi_consul_configuration |
combine(_config_to_merge)
}}"
when: consul_address_configuration is defined
- name: "Consul | Merge extra configuration settings"
vars:
_config_to_merge: "{{ consul_extra_configuration }}"
ansible.builtin.set_fact:
hashi_consul_configuration: "{{
hashi_consul_configuration |
combine(_config_to_merge)
}}"
when: consul_extra_configuration is defined

View File

@ -64,6 +64,13 @@
loop_var: item loop_var: item
delegate_to: localhost delegate_to: localhost
- name: "Merge consul configurations"
ansible.builtin.import_tasks:
file: "consul_vars.yml"
when:
- enable_consul | bool
- "'consul_servers' in group_names"
- name: "Merge vault configurations" - name: "Merge vault configurations"
ansible.builtin.import_tasks: ansible.builtin.import_tasks:
file: "vault_vars.yml" file: "vault_vars.yml"

View File

@ -85,7 +85,6 @@ def run_module():
api_url=dict(type="str", required=True), api_url=dict(type="str", required=True),
key_shares=dict(type="list", required=False, default=[]), key_shares=dict(type="list", required=False, default=[]),
) )
result = dict(changed=False, state="") result = dict(changed=False, state="")
module = AnsibleModule(argument_spec=module_args, supports_check_mode=True) module = AnsibleModule(argument_spec=module_args, supports_check_mode=True)
@ -98,25 +97,24 @@ def run_module():
if module.check_mode: if module.check_mode:
module.exit_json(**result) module.exit_json(**result)
# Initialize HashiCorp Vault client
client = hvac.Client(url=module.params["api_url"]) client = hvac.Client(url=module.params["api_url"])
# Check if Vault is sealed
if not client.sys.is_sealed(): if not client.sys.is_sealed():
module.exit_json(**result) module.exit_json(**result)
# Unseal Vault
try: try:
key_shares = module.params["key_shares"] key_shares = module.params["key_shares"]
vault_unseal_result = client.sys.submit_unseal_keys(key_shares) vault_unseal_result = client.sys.submit_unseal_keys(key_shares)
result["state"] = vault_unseal_result result["state"] = vault_unseal_result
except hvac.exceptions.VaultError as ve:
module.fail_json(msg=f"Vault unsealing failed: {ve}")
if client.sys.is_sealed(): if client.sys.is_sealed():
module.fail_json(msg="Vault unsealing failed.") module.fail_json(msg="Vault unsealing failed.")
else:
result["changed"] = True result["changed"] = True
except hvac.exceptions.VaultError as ve:
module.fail_json(msg=f"Vault unsealing failed: {ve}")
module.exit_json(**result) module.exit_json(**result)