From 0929f25f5d235d8773527e0ff8ba20882f84aab5 Mon Sep 17 00:00:00 2001 From: Bertrand Lanson Date: Sun, 24 Dec 2023 18:09:08 +0100 Subject: [PATCH] feat(vault): start of unseal module, and start of default variables --- playbooks/deploy.yml | 12 ++- playbooks/group_vars/all.yml | 39 +++++++++- playbooks/preflight.yml | 30 +++++++- plugins/modules/vault_init.py | 135 ++++++++++++++++++++++++++++++++++ 4 files changed, 209 insertions(+), 7 deletions(-) create mode 100644 plugins/modules/vault_init.py diff --git a/playbooks/deploy.yml b/playbooks/deploy.yml index 3df68f6..43cdb3c 100644 --- a/playbooks/deploy.yml +++ b/playbooks/deploy.yml @@ -3,7 +3,13 @@ - name: "Deploy" hosts: all gather_facts: true + become: true tasks: - - name: "Debug" - ansible.builtin.debug: - msg: "{{ ansible_hostname }}" + # - name: "Include ednxzu.hashicorp_vault" + # ansible.builtin.include_role: + # name: ednxzu.hashicorp_vault + + - name: "Test module" + ednxzu.hashistack.vault_init: + name: "Test" + new: true diff --git a/playbooks/group_vars/all.yml b/playbooks/group_vars/all.yml index c0c3827..84cac72 100644 --- a/playbooks/group_vars/all.yml +++ b/playbooks/group_vars/all.yml @@ -28,7 +28,6 @@ hashistack_supported_distribution_versions: - "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: [] @@ -72,13 +71,47 @@ hashi_consul_configuration: {} # Vault options ########## ########################## +vault_cluster_name: vault +vault_storage_configuration: + raft: + path: "{{ hashi_vault_data_dir }}/data" + node_id: "{{ ansible_hostname }}" + retry_join: | + [ + {% for host in groups['vault_servers'] %} + { + 'leader_api_addr': 'http://{{ hostvars[host].api_interface_address }}:8200' + }{% if not loop.last %},{% endif %} + {% endfor %} + ] + +extra_vault_container_volumes: [] +default_container_extra_volumes: + - "/etc/timezone:/etc/timezone" + - "/etc/localtime:/etc/localtime" + hashi_vault_start_service: true hashi_vault_version: latest -hashi_vault_deploy_method: host # deployment method, either host or docker +hashi_vault_deploy_method: "{{ deployment_method }}" # deployment method, either host or docker hashi_vault_env_variables: {} hashi_vault_data_dir: "/opt/vault" hashi_vault_extra_files: false hashi_vault_extra_files_src: /tmp/extra_files hashi_vault_extra_files_dst: /etc/vault.d/extra_files +hashi_vault_extra_container_volumes: "{{ default_container_extra_volumes | union(extra_vault_container_volumes) | unique }}" #! vault configuration -hashi_vault_configuration: {} +hashi_vault_configuration: + cluster_name: "{{ vault_cluster_name }}" + cluster_addr: "http://{{ api_interface_address }}:8201" + api_addr: "http://{{ api_interface_address }}:8200" + ui: true + disable_mlock: false + disable_cache: false + listener: + tcp: + address: "0.0.0.0:8200" + tls_disable: true + #tls_disable_client_certs: true + #tls_cert_file: "{{ hashi_vault_data_dir }}/tls/cert.pem" + #tls_key_file: "{{ hashi_vault_data_dir }}/tls/key.pem" + storage: "{{ vault_storage_configuration }}" diff --git a/playbooks/preflight.yml b/playbooks/preflight.yml index 8fe509b..840532d 100644 --- a/playbooks/preflight.yml +++ b/playbooks/preflight.yml @@ -170,6 +170,26 @@ with_items: "{{ vault_port_results.results }}" when: vault_port_results.results | length > 0 + - name: "Checking if consul ports are available" + when: inventory_hostname in groups['consul_servers'] + block: + - name: "Checking if consul ports are available" + ansible.builtin.wait_for: + host: "{{ inventory_hostname }}" + port: "{{ item }}" + state: "stopped" + timeout: 5 + loop: "{{ consul_required_ports }}" + ignore_errors: true + register: consul_port_results + + - name: "Assert that consul ports are not currently in use" + ansible.builtin.assert: + that: + - item.failed == false + with_items: "{{ consul_port_results.results }}" + when: consul_port_results.results | length > 0 + - name: "Checking if system uses systemd" become: true ansible.builtin.assert: @@ -198,4 +218,12 @@ 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 + - name: "Debug" + ansible.builtin.debug: + msg: "{{ groups['vault_servers'] }}" + + - name: "Debug" + ansible.builtin.debug: + msg: "{{ hashi_vault_configuration.storage }}" + + # - ansible.builtin.fail: diff --git a/plugins/modules/vault_init.py b/plugins/modules/vault_init.py new file mode 100644 index 0000000..e4b2a93 --- /dev/null +++ b/plugins/modules/vault_init.py @@ -0,0 +1,135 @@ +#!/usr/bin/python + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type + +DOCUMENTATION = r''' +--- +module: my_test + +short_description: This is my test module + +# If this is part of a collection, you need to use semantic versioning, +# i.e. the version is of the form "2.5.0" and not "2.4". +version_added: "1.0.0" + +description: This is my longer description explaining my test module. + +options: + name: + description: This is the message to send to the test module. + required: true + type: str + new: + description: + - Control to demo if the result of this module is changed or not. + - Parameter description can be a list as well. + required: false + type: bool +# Specify this value according to your collection +# in format of namespace.collection.doc_fragment_name +# extends_documentation_fragment: +# - my_namespace.my_collection.my_doc_fragment_name + +author: + - Your Name (@yourGitHubHandle) +''' + +EXAMPLES = r''' +# Pass in a message +- name: Test with a message + my_namespace.my_collection.my_test: + name: hello world + +# pass in a message and have changed true +- name: Test with a message and changed output + my_namespace.my_collection.my_test: + name: hello world + new: true + +# fail the module +- name: Test failure of the module + my_namespace.my_collection.my_test: + name: fail me +''' + +RETURN = r''' +# These are examples of possible return values, and in general should use other names for return values. +original_message: + description: The original name param that was passed in. + type: str + returned: always + sample: 'hello world' +message: + description: The output message that the test module generates. + type: str + returned: always + sample: 'goodbye' +''' + +from ansible.module_utils.basic import AnsibleModule +import hvac + +def run_module(): + # define available arguments/parameters a user can pass to the module + module_args = dict( + api_url=dict(type='str', required=True), + key_shares=dict(type='int', required=False,default=5) + key_treshold=dict(type='int',required=False,default=3) + name=dict(type='str', required=True), + new=dict(type='bool', required=False, default=False) + ) + + # seed the result dict in the object + # we primarily care about changed and state + # changed is if this module effectively modified the target + # state will include any data that you want your module to pass back + # for consumption, for example, in a subsequent task + result = dict( + changed=False, + original_message='', + message='' + ) + + # the AnsibleModule object will be our abstraction working with Ansible + # this includes instantiation, a couple of common attr would be the + # args/params passed to the execution, as well as if the module + # supports check mode + module = AnsibleModule( + argument_spec=module_args, + supports_check_mode=True + ) + + # if the user is working with this module in only check mode we do not + # want to make any changes to the environment, just return the current + # state with no modifications + if module.check_mode: + module.exit_json(**result) + + # manipulate or modify the state as needed (this is going to be the + # part where your module will do what it needs to do) + result['original_message'] = module.params['name'] + result['message'] = 'goodbye' + + # use whatever logic you need to determine whether or not this module + # made any modifications to your target + if module.params['new']: + result['changed'] = True + + # during the execution of the module, if there is an exception or a + # conditional state that effectively causes a failure, run + # AnsibleModule.fail_json() to pass in the message and the result + if module.params['name'] == 'fail me': + module.fail_json(msg='You requested this to fail', **result) + + # in the event of a successful module execution, you will want to + # simple AnsibleModule.exit_json(), passing the key/value results + module.exit_json(**result) + + +def main(): + run_module() + + +if __name__ == '__main__': + main()