feat(consul): add initial simple consul cluster
This commit is contained in:
parent
8ce66d42a7
commit
00883b2dec
2
molecule/no_tls_multi_node/.vault_password
Executable file
2
molecule/no_tls_multi_node/.vault_password
Executable file
@ -0,0 +1,2 @@
|
|||||||
|
#! /bin/sh
|
||||||
|
vault kv get --field=password kv_hs/ansible/ansible_vault
|
8
molecule/no_tls_multi_node/ansible.cfg
Normal file
8
molecule/no_tls_multi_node/ansible.cfg
Normal 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
|
@ -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"
|
||||||
|
@ -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:
|
||||||
|
@ -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 }}"
|
|
||||||
|
@ -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:
|
||||||
|
31
playbooks/tasks/consul_vars.yml
Normal file
31
playbooks/tasks/consul_vars.yml
Normal 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
|
@ -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"
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
if client.sys.is_sealed():
|
||||||
|
module.fail_json(msg="Vault unsealing failed.")
|
||||||
|
else:
|
||||||
|
result["changed"] = True
|
||||||
|
|
||||||
except hvac.exceptions.VaultError as ve:
|
except hvac.exceptions.VaultError as ve:
|
||||||
module.fail_json(msg=f"Vault unsealing failed: {ve}")
|
module.fail_json(msg=f"Vault unsealing failed: {ve}")
|
||||||
|
|
||||||
if client.sys.is_sealed():
|
|
||||||
module.fail_json(msg="Vault unsealing failed.")
|
|
||||||
|
|
||||||
result["changed"] = True
|
|
||||||
module.exit_json(**result)
|
module.exit_json(**result)
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user