From 71ea3d1f76175e6c496ca725f59a431979d8a528 Mon Sep 17 00:00:00 2001 From: Bertrand Lanson Date: Mon, 2 Sep 2024 22:09:57 +0200 Subject: [PATCH 1/2] docs: add proper documentation to ansible modules --- plugins/modules/consul_acl_bootstrap.py | 12 ++-- plugins/modules/nomad_acl_bootstrap.py | 18 +++--- plugins/modules/vault_init.py | 4 +- plugins/modules/vault_unseal.py | 86 +++++++++++++------------ 4 files changed, 63 insertions(+), 57 deletions(-) diff --git a/plugins/modules/consul_acl_bootstrap.py b/plugins/modules/consul_acl_bootstrap.py index 9c955ff..e452c59 100644 --- a/plugins/modules/consul_acl_bootstrap.py +++ b/plugins/modules/consul_acl_bootstrap.py @@ -11,11 +11,11 @@ module: ednz_cloud.hashistack.consul_acl_bootstrap short_description: Bootstraps ACL for a Consul cluster. -version_added: "1.0.0" +version_added: "0.1.0" description: - This module bootstraps ACL (Access Control List) for a Consul cluster. It performs the ACL bootstrap operation, - creating the initial tokens needed for secure communication within the cluster. + creating the initial tokens needed for secure communication within the cluster. options: api_addr: @@ -40,10 +40,10 @@ author: EXAMPLES = r""" # Example: Bootstrap ACL for a Consul cluster - name: Bootstrap ACL for Consul cluster - ednz_cloud.hashistack.consul_acl_bootstrap: - api_addr: 127.0.0.1 - scheme: http - port: 8500 + ednz_cloud.hashistack.consul_acl_bootstrap: + api_addr: 127.0.0.1 + scheme: http + port: 8500 """ RETURN = r""" diff --git a/plugins/modules/nomad_acl_bootstrap.py b/plugins/modules/nomad_acl_bootstrap.py index 24b4a69..5265ae8 100644 --- a/plugins/modules/nomad_acl_bootstrap.py +++ b/plugins/modules/nomad_acl_bootstrap.py @@ -60,15 +60,15 @@ state: type: dict returned: always sample: - - AccessorID: "b780e702-98ce-521f-2e5f-c6b87de05b24", - - SecretID: "3f4a0fcd-7c42-773c-25db-2d31ba0c05fe", - - Name: "Bootstrap Token", - - Type: "management", - - Policies: null, - - Global: true, - - CreateTime: "2017-08-23T22:47:14.695408057Z", - - CreateIndex: 7, - - ModifyIndex: 7 + - AccessorID: "b780e702-98ce-521f-2e5f-c6b87de05b24", + - SecretID: "3f4a0fcd-7c42-773c-25db-2d31ba0c05fe", + - Name: "Bootstrap Token", + - Type: "management", + - Policies: null, + - Global: true, + - CreateTime: "2017-08-23T22:47:14.695408057Z", + - CreateIndex: 7, + - ModifyIndex: 7 """ from ansible.module_utils.basic import AnsibleModule diff --git a/plugins/modules/vault_init.py b/plugins/modules/vault_init.py index 2434647..c95d17b 100644 --- a/plugins/modules/vault_init.py +++ b/plugins/modules/vault_init.py @@ -11,11 +11,13 @@ module: ednz_cloud.hashistack.vault_init short_description: Manages the initialization of HashiCorp Vault. +version_added: "0.1.0" + description: - This module initializes HashiCorp Vault, ensuring that it is securely set up for use. requirements: - - C(hvac) (L(Python library,https://hvac.readthedocs.io/en/stable/overview.html)) + - C(hvac) (L(Python library,https://hvac.readthedocs.io/en/stable/overview.html)) options: api_url: diff --git a/plugins/modules/vault_unseal.py b/plugins/modules/vault_unseal.py index 16268d2..65b11ab 100644 --- a/plugins/modules/vault_unseal.py +++ b/plugins/modules/vault_unseal.py @@ -7,66 +7,70 @@ __metaclass__ = type DOCUMENTATION = r""" --- -module: my_test +module: ednz_cloud.hashistack.vault_unseal -short_description: This is my test module +short_description: Unseals a Vault cluster. -# 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" +version_added: "0.1.0" -description: This is my longer description explaining my test module. +description: + - This module unseals a Vault cluster by submitting the necessary unseal keys. It checks whether the Vault is sealed and performs the unseal operation if needed. The response will reflect the state after the last unseal key is submitted. + +requirements: +- C(hvac) (L(Python library,https://hvac.readthedocs.io/en/stable/overview.html)) options: - name: - description: This is the message to send to the test module. + api_url: + description: The URL of the Vault API. 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. + tls_verify: + description: Whether to verify TLS certificates. 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 + default: true + key_shares: + description: List of unseal keys required to unseal the Vault. + required: false + type: list + default: [] author: - - Your Name (@yourGitHubHandle) + - Bertrand Lanson (@ednz_cloud) """ EXAMPLES = r""" -# Pass in a message -- name: Test with a message - my_namespace.my_collection.my_test: - name: hello world +# Example: Unseal a Vault cluster +- name: Unseal Vault cluster + ednz_cloud.hashistack.vault_unseal: + api_url: "https://127.0.0.1:8200" + tls_verify: true + key_shares: + - "key1" + - "key2" + - "key3" -# 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 +# Example: Unseal Vault cluster with no TLS verification +- name: Unseal Vault cluster without TLS verification + ednz_cloud.hashistack.vault_unseal: + api_url: "https://127.0.0.1:8200" + tls_verify: false + key_shares: + - "key1" + - "key2" """ 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 +state: + description: Information about the state of the Vault unseal operation. + type: dict returned: always - sample: 'hello world' -message: - description: The output message that the test module generates. - type: str - returned: always - sample: 'goodbye' + sample: + sealed: true, + t: 3, + n: 5, + progress: 2, + version: "0.6.2" """ from ansible.module_utils.basic import AnsibleModule import traceback From 66a4f6b5daf5cb6072f3c12469d16db57f74a4db Mon Sep 17 00:00:00 2001 From: Bertrand Lanson Date: Mon, 2 Sep 2024 22:24:58 +0200 Subject: [PATCH 2/2] feat(vault): enable rolling restart with no full seal --- playbooks/tasks/vault/vault_control_plane.yml | 5 +++++ roles/vault/defaults/main.yml | 9 +++++++++ roles/vault/tasks/install.yml | 7 ++++--- roles/vault/tasks/main.yml | 12 +++++++----- roles/vault/tasks/recursive_copy_extra_dirs.yml | 4 ++-- roles/vault/tasks/rolling_restart.yml | 14 ++++++++++++++ 6 files changed, 41 insertions(+), 10 deletions(-) create mode 100644 roles/vault/tasks/rolling_restart.yml diff --git a/playbooks/tasks/vault/vault_control_plane.yml b/playbooks/tasks/vault/vault_control_plane.yml index c0ace90..7eb8c90 100644 --- a/playbooks/tasks/vault/vault_control_plane.yml +++ b/playbooks/tasks/vault/vault_control_plane.yml @@ -45,6 +45,11 @@ - name: "Include ednz_cloud.hashistack.vault" ansible.builtin.include_role: name: ednz_cloud.hashistack.vault + vars: + vault_enable_auto_unseal: true + vault_unseal_url: "{{ vault_configuration['api_addr'] }}" + vault_unseal_tls_verify: false + vault_unseal_keys: "{{ _credentials.vault['keys'] | default([]) }}" - name: "Vault | Initialize vault cluster" # noqa: run-once[task] ednz_cloud.hashistack.vault_init: diff --git a/roles/vault/defaults/main.yml b/roles/vault/defaults/main.yml index 5b9f5d9..c39380c 100644 --- a/roles/vault/defaults/main.yml +++ b/roles/vault/defaults/main.yml @@ -42,6 +42,15 @@ vault_storage_configuration: file: path: "{{ vault_data_dir }}" +############################# +# auto-unseal configuration # +############################# + +vault_enable_auto_unseal: false +vault_unseal_url: "https://127.0.0.1:8200" +vault_unseal_tls_verify: true +vault_unseal_keys: [] + ########################## # listener configuration # ########################## diff --git a/roles/vault/tasks/install.yml b/roles/vault/tasks/install.yml index 625651a..269dd4b 100644 --- a/roles/vault/tasks/install.yml +++ b/roles/vault/tasks/install.yml @@ -36,8 +36,10 @@ register: _vault_current_version - name: "Vault | Download and install vault binary" - when: _vault_current_version is not defined - or _vault_wanted_version != (_vault_current_version.content|default('')|b64decode) + when: + - _vault_current_version is not defined + or _vault_wanted_version != (_vault_current_version.content|default('')|b64decode) + - not ansible_check_mode block: - name: "Vault | Set vault package name to download" ansible.builtin.set_fact: @@ -77,7 +79,6 @@ until: _vault_binary_archive is succeeded retries: 5 delay: 2 - check_mode: false - name: "Vault | Create temporary directory for archive decompression" ansible.builtin.file: diff --git a/roles/vault/tasks/main.yml b/roles/vault/tasks/main.yml index e1af6da..6a0466d 100644 --- a/roles/vault/tasks/main.yml +++ b/roles/vault/tasks/main.yml @@ -36,8 +36,10 @@ when: _vault_service_need_reload - name: "Vault | Start service: {{ vault_service_name }}" - ansible.builtin.service: - name: "{{ vault_service_name }}" - state: restarted - throttle: 1 - when: _vault_service_need_restart + ansible.builtin.include_tasks: rolling_restart.yml + when: + - _vault_service_need_restart + - "hostvars[host_item].inventory_hostname == inventory_hostname" + with_items: "{{ ansible_play_batch }}" + loop_control: + loop_var: host_item diff --git a/roles/vault/tasks/recursive_copy_extra_dirs.yml b/roles/vault/tasks/recursive_copy_extra_dirs.yml index 22feb1f..147ea35 100644 --- a/roles/vault/tasks/recursive_copy_extra_dirs.yml +++ b/roles/vault/tasks/recursive_copy_extra_dirs.yml @@ -5,13 +5,13 @@ path: "{{ dir_source_item.dest }}" recurse: true state: directory - mode: "0775" + mode: "0755" - name: "Vault | Create extra directory sources" ansible.builtin.file: path: "{{ dir_source_item.dest }}/{{ item.path }}" state: directory - mode: "0775" + mode: "0755" with_community.general.filetree: "{{ dir_source_item.src }}/" when: item.state == 'directory' diff --git a/roles/vault/tasks/rolling_restart.yml b/roles/vault/tasks/rolling_restart.yml new file mode 100644 index 0000000..d4e3754 --- /dev/null +++ b/roles/vault/tasks/rolling_restart.yml @@ -0,0 +1,14 @@ +--- +- name: "Vault | Start service: {{ vault_service_name }}" + ansible.builtin.service: + name: "{{ vault_service_name }}" + state: restarted + +- name: "Vault | Unseal node" + ednz_cloud.hashistack.vault_unseal: + api_url: "{{ vault_unseal_url }}" + tls_verify: "{{ vault_unseal_tls_verify }}" + key_shares: "{{ vault_unseal_keys }}" + when: + - vault_enable_auto_unseal + - vault_unseal_keys|length > 0