From 4630686792617114353dadd52cc0cd5476023276 Mon Sep 17 00:00:00 2001 From: Frank Ketelaars Date: Sun, 17 May 2026 09:02:08 +0000 Subject: [PATCH 1/2] #1122 Deployer secrets handling --- .../tasks/hashicorp-exchange-token.yml | 12 +++ .../load-vault-config/tasks/main.yml | 28 +++---- .../load-vault-config/vars/main.yaml | 2 + .../validate-variables-destroy/tasks/main.yml | 4 +- .../validate-variables/tasks/main.yml | 4 +- .../tasks/connect-ansible-vault.yml | 18 ++--- .../vault/vault-connect/tasks/main.yaml | 34 ++++----- .../tasks/delete-secret-file.yml | 4 +- .../tasks/delete-secret-hashicorp-api-key.yml | 16 ---- .../delete-secret-hashicorp-certificate.yml | 20 ++--- .../tasks/delete-secret-hashicorp-token.yml | 27 +++++++ .../tasks/delete-secret.yml | 28 +++---- .../tasks/get-secret-ansible-vault.yml | 4 +- .../tasks/get-secret-file.yml | 6 +- .../tasks/get-secret-hashicorp-token.yml | 2 +- .../tasks/get-secret-hashicorp.yml | 25 +++--- .../vault-get-secret/tasks/get-secret.yml | 10 +-- .../vault/vault-group/tasks/main.yaml | 10 +-- .../tasks/has-secret-file.yml | 35 --------- .../tasks/has-secret-hashicorp-api-key.yml | 37 --------- .../has-secret-hashicorp-certificate.yml | 43 ----------- .../vault/vault-has-secret/tasks/main.yml | 76 +------------------ .../templates/get-secret-from-file.j2 | 1 - .../vault/vault-has-secret/vars/main.yml | 0 .../tasks/list-secrets-file.yml | 4 +- .../tasks/list-secrets-hashicorp-token.yml | 2 +- .../vault/vault-list-secrets/tasks/main.yml | 26 +++---- .../tasks/create-secret-ansible-vault.yml | 10 +-- .../create-secret-hashicorp-certificate.yml | 2 +- .../tasks/create-secret-hashicorp-token.yml | 2 +- .../tasks/create-secret-hashicorp.yml | 30 ++------ .../vault-set-secret/tasks/create-secret.yml | 10 +-- cp-deploy.sh | 22 +++++- docker-scripts/run_automation.sh | 6 ++ docs/src/30-reference/configuration/vault.md | 44 +++++++++-- .../cp4i-existing-ocp/config/sample-cp4i.yaml | 1 - .../config-samples/vault-file.yaml | 3 +- .../config-samples/vault-hashicorp-cert.yaml | 3 +- .../config-samples/vault-hashicorp-token.yaml | 5 +- .../sample-inventory/sample.inv | 3 - 40 files changed, 240 insertions(+), 379 deletions(-) create mode 100644 automation-roles/10-validation/load-vault-config/tasks/hashicorp-exchange-token.yml create mode 100644 automation-roles/10-validation/load-vault-config/vars/main.yaml delete mode 100644 automation-roles/99-generic/vault/vault-delete-secret/tasks/delete-secret-hashicorp-api-key.yml create mode 100644 automation-roles/99-generic/vault/vault-delete-secret/tasks/delete-secret-hashicorp-token.yml delete mode 100644 automation-roles/99-generic/vault/vault-has-secret/tasks/has-secret-file.yml delete mode 100644 automation-roles/99-generic/vault/vault-has-secret/tasks/has-secret-hashicorp-api-key.yml delete mode 100644 automation-roles/99-generic/vault/vault-has-secret/tasks/has-secret-hashicorp-certificate.yml delete mode 100644 automation-roles/99-generic/vault/vault-has-secret/templates/get-secret-from-file.j2 delete mode 100644 automation-roles/99-generic/vault/vault-has-secret/vars/main.yml diff --git a/automation-roles/10-validation/load-vault-config/tasks/hashicorp-exchange-token.yml b/automation-roles/10-validation/load-vault-config/tasks/hashicorp-exchange-token.yml new file mode 100644 index 000000000..963f8daf8 --- /dev/null +++ b/automation-roles/10-validation/load-vault-config/tasks/hashicorp-exchange-token.yml @@ -0,0 +1,12 @@ +--- +- name: Exchange Hashicorp Vault token + community.hashi_vault.vault_token_create: + url: "{{ VAULT_URL | default(vault.vault_url) }}" + auth_method: token + token: '{{ VAULT_PASSWORD }}' + ttl: 24h + orphan: True + register: _hashicorp_vault_token_create + +- set_fact: + _hashicorp_ephemeral_token: "{{ _hashicorp_vault_token_create.login.auth.client_token }}" \ No newline at end of file diff --git a/automation-roles/10-validation/load-vault-config/tasks/main.yml b/automation-roles/10-validation/load-vault-config/tasks/main.yml index 4e1f69539..fab3655ff 100644 --- a/automation-roles/10-validation/load-vault-config/tasks/main.yml +++ b/automation-roles/10-validation/load-vault-config/tasks/main.yml @@ -1,17 +1,19 @@ --- -# - name: Load yaml files for vault configuration -# include_vars: -# dir: "{{ config_dir }}/config" -# files_matching: '.*\.yaml$' - -- name: Read vault config - include_tasks: read-vault-config.yml - when: vault | default({}) != {} - - set_fact: - vault_type: "file-vault" - when: vault_type is not defined + vault: "{{ _vault_default }}" + when: vault | default({}) == {} - set_fact: - vault_authentication_type: "none" - when: vault_authentication_type is not defined \ No newline at end of file + vault: "{{ vault | combine({'vault_authentication_type':'none'}) }}" + when: vault.vault_authentication_type is not defined + +- fail: + msg: "For hashicorp-vault, either vault_url must be specified in the vault configuration, or VAULT_URL environment variable must be set" + when: + - vault.vault_type == 'hashicorp-vault' + - (VAULT_URL | default(vault.vault_url) | default(''))== '' + +- include_tasks: hashicorp-exchange-token.yml + when: + - vault.vault_type == 'hashicorp-vault' + - vault.vault_exchange_token | default(False) | bool \ No newline at end of file diff --git a/automation-roles/10-validation/load-vault-config/vars/main.yaml b/automation-roles/10-validation/load-vault-config/vars/main.yaml new file mode 100644 index 000000000..b697c971b --- /dev/null +++ b/automation-roles/10-validation/load-vault-config/vars/main.yaml @@ -0,0 +1,2 @@ +_vault_default: + vault_type: file-vault diff --git a/automation-roles/10-validation/validate-variables-destroy/tasks/main.yml b/automation-roles/10-validation/validate-variables-destroy/tasks/main.yml index 47722a7f7..00a1b0f61 100644 --- a/automation-roles/10-validation/validate-variables-destroy/tasks/main.yml +++ b/automation-roles/10-validation/validate-variables-destroy/tasks/main.yml @@ -2,8 +2,8 @@ - name: Validate mandatory variables are defined assert: that: - - vault_type is defined - - vault_authentication_type is defined + - vault.vault_type is defined + - vault.vault_authentication_type is defined - cloud_platform is defined - name: Validate cloud_platform is supported diff --git a/automation-roles/10-validation/validate-variables/tasks/main.yml b/automation-roles/10-validation/validate-variables/tasks/main.yml index 1355d4fac..c1f03cf40 100644 --- a/automation-roles/10-validation/validate-variables/tasks/main.yml +++ b/automation-roles/10-validation/validate-variables/tasks/main.yml @@ -2,8 +2,8 @@ - name: Validate mandatory variables are defined assert: that: - - vault_type is defined - - vault_authentication_type is defined + - vault.vault_type is defined + - vault.vault_authentication_type is defined - cloud_platform is defined - name: Validate cloud_platform is supported diff --git a/automation-roles/99-generic/vault/vault-connect/tasks/connect-ansible-vault.yml b/automation-roles/99-generic/vault/vault-connect/tasks/connect-ansible-vault.yml index 566d1e499..26a26127d 100644 --- a/automation-roles/99-generic/vault/vault-connect/tasks/connect-ansible-vault.yml +++ b/automation-roles/99-generic/vault/vault-connect/tasks/connect-ansible-vault.yml @@ -2,27 +2,27 @@ - name: Validate mandatory variables for Ansible Vault assert: that: - - vault_password_file is defined - - vault_password_file != '' + - vault.vault_password_file is defined + - vault.vault_password_file != '' fail_msg: "vault_password_file must be defined for ansible-vault type" - name: Check if Ansible Vault password file exists stat: - path: "{{ vault_password_file }}" - register: vault_password_file_stat + path: "{{ vault.vault_password_file }}" + register: _vault_password_file_stat - name: Fail if Ansible Vault password file does not exist fail: - msg: "Ansible Vault password file {{ vault_password_file }} does not exist" - when: not vault_password_file_stat.stat.exists + msg: "Ansible Vault password file {{ vault.vault_password_file }} does not exist" + when: not _vault_password_file_stat.stat.exists - name: Validate Ansible Vault password file is readable assert: that: - - vault_password_file_stat.stat.readable - fail_msg: "Ansible Vault password file {{ vault_password_file }} is not readable" + - _vault_password_file_stat.stat.readable + fail_msg: "Ansible Vault password file {{ vault.vault_password_file }} is not readable" - name: Successfully connected to Ansible Vault debug: - msg: "Successfully validated Ansible Vault password file: {{ vault_password_file }}" + msg: "Successfully validated Ansible Vault password file: {{ vault.vault_password_file }}" diff --git a/automation-roles/99-generic/vault/vault-connect/tasks/main.yaml b/automation-roles/99-generic/vault/vault-connect/tasks/main.yaml index 48feb3603..d8abb0434 100644 --- a/automation-roles/99-generic/vault/vault-connect/tasks/main.yaml +++ b/automation-roles/99-generic/vault/vault-connect/tasks/main.yaml @@ -1,23 +1,23 @@ --- - name: Validate vault_type is supported - fail: msg="Vault type {{ vault_type }} only support values {{ supported_vault_types }} " - when: "vault_type not in supported_vault_types" + fail: msg="Vault type {{ vault.vault_type }} only support values {{ supported_vault_types }} " + when: vault.vault_type not in supported_vault_types - name: Validate vault_authentication_type is supported - fail: msg="Vault Authentication type (vault_authentication_type) only support values {{ supported_vault_authentication_types }} " - when: "vault_authentication_type not in supported_vault_authentication_types" + fail: msg="Vault Authentication type (vault_authentication_type) only supports values {{ supported_vault_authentication_types }} " + when: vault.vault_authentication_type not in supported_vault_authentication_types - name: Login to Hashicorp vault block: - name: Validate mandatory variables are defined assert: that: - - vault_type is defined - - vault_authentication_type is defined + - vault.vault_type is defined + - vault.vault_authentication_type is defined - debug: - msg: "Hashicorp Vault URL: {{ vault_url }}" - when: "vault_type == 'hashicorp-vault'" + msg: "Hashicorp Vault URL: {{ VAULT_URL | default(vault.vault_url) }}" + when: vault.vault_type == 'hashicorp-vault' - name: Login to IBMCloud vault block: @@ -25,22 +25,22 @@ - name: Validate mandatory variables are defined assert: that: - - vault_type is defined - - vault_authentication_type is defined + - vault.vault_type is defined + - vault.vault_authentication_type is defined - include_tasks: connect-ibmcloud.yml vars: - ibmcloud_vault_address: "{{ vault_url }}" + ibmcloud_vault_address: "{{ vault.vault_url }}" ibmcloud_api_key: "{{ vault_api_key }}" ibmcloud_vault_group: "{{ vault_secret_group }}" - when: "vault_type == 'ibmcloud-vault'" + when: vault.vault_type == 'ibmcloud-vault' - name: Login to file vault block: - name: No login to file fault needed debug: msg: File vault directory is {{ status_dir }}/vault - when: "vault_type == 'file-vault'" + when: vault.vault_type == 'file-vault' - name: Login to Ansible vault block: @@ -48,12 +48,12 @@ - name: Validate mandatory variables are defined assert: that: - - vault_type is defined - - vault_authentication_type is defined + - vault.vault_type is defined + - vault.vault_authentication_type is defined - include_tasks: connect-ansible-vault.yml - when: vault_authentication_type == 'password-file' - when: "vault_type == 'ansible-vault'" + when: vault.vault_authentication_type == 'password-file' + when: vault.vault_type == 'ansible-vault' - set_fact: vault_login_success: "true" \ No newline at end of file diff --git a/automation-roles/99-generic/vault/vault-delete-secret/tasks/delete-secret-file.yml b/automation-roles/99-generic/vault/vault-delete-secret/tasks/delete-secret-file.yml index b517093fa..df5ceeb56 100644 --- a/automation-roles/99-generic/vault/vault-delete-secret/tasks/delete-secret-file.yml +++ b/automation-roles/99-generic/vault/vault-delete-secret/tasks/delete-secret-file.yml @@ -8,12 +8,12 @@ - name: Check that vault file {{ secret_group }} exists stat: path: "{{ status_dir }}/vault/{{ secret_group }}" - register: vault_file_details + register: _vault_file_details - name: Fail if the secret file was not found fail: msg: "File {{ status_dir }}/vault/{{ secret_group }} does not exist" - when: not vault_file_details.stat.exists + when: not v_ault_file_details.stat.exists - name: Add or replace secret in file {{ status_dir }}/vault/{{ secret_group }} lineinfile: diff --git a/automation-roles/99-generic/vault/vault-delete-secret/tasks/delete-secret-hashicorp-api-key.yml b/automation-roles/99-generic/vault/vault-delete-secret/tasks/delete-secret-hashicorp-api-key.yml deleted file mode 100644 index 72db57d29..000000000 --- a/automation-roles/99-generic/vault/vault-delete-secret/tasks/delete-secret-hashicorp-api-key.yml +++ /dev/null @@ -1,16 +0,0 @@ ---- -- name: Delete secret Validate mandatory variables are defined - assert: - that: - - hashicorp_vault_address is defined - - hashicorp_secret_name_path is defined - -- name: Delete secret - shell: | - vault kv delete \ - -address={{ hashicorp_vault_address }} \ - {{ hashicorp_secret_name_path }} - -- name: Successfully deleted secret - debug: - msg: "Secret {{ hashicorp_secret_name_path }} deleted..." \ No newline at end of file diff --git a/automation-roles/99-generic/vault/vault-delete-secret/tasks/delete-secret-hashicorp-certificate.yml b/automation-roles/99-generic/vault/vault-delete-secret/tasks/delete-secret-hashicorp-certificate.yml index 7c8ac8f0a..db7b9e06d 100644 --- a/automation-roles/99-generic/vault/vault-delete-secret/tasks/delete-secret-hashicorp-certificate.yml +++ b/automation-roles/99-generic/vault/vault-delete-secret/tasks/delete-secret-hashicorp-certificate.yml @@ -8,15 +8,11 @@ - VAULT_CERT_CERT_FILE is defined - hashicorp_secret_name_path is defined -- name: Delete the secret - shell: | - vault kv delete \ - -ca-cert={{ VAULT_CERT_CA_FILE }} \ - -client-cert={{ VAULT_CERT_CERT_FILE }} \ - -client-key={{ VAULT_CERT_KEY_FILE }} \ - -address={{ hashicorp_vault_address }} \ - {{ hashicorp_secret_name_path }} - -- name: Successfully deleted secret - debug: - msg: "Secret {{ hashicorp_secret_name_path }} deleted..." \ No newline at end of file +- name: Delete secret {{ hashicorp_secret_name_path }} + community.hashi_vault.vault_kv2_delete: + url: "{{ hashicorp_vault_address }}" + path: "{{ hashicorp_secret_name_path }}" + auth_method: cert + ca_cert: "{{ VAULT_CERT_CA_FILE }}" + cert_auth_private_key: "{{ VAULT_CERT_KEY_FILE }}" + cert_auth_public_key: "{{ VAULT_CERT_CERT_FILE }}" \ No newline at end of file diff --git a/automation-roles/99-generic/vault/vault-delete-secret/tasks/delete-secret-hashicorp-token.yml b/automation-roles/99-generic/vault/vault-delete-secret/tasks/delete-secret-hashicorp-token.yml new file mode 100644 index 000000000..08b6dbf85 --- /dev/null +++ b/automation-roles/99-generic/vault/vault-delete-secret/tasks/delete-secret-hashicorp-token.yml @@ -0,0 +1,27 @@ +--- +- name: Delete secret Validate mandatory variables are defined + assert: + that: + - hashicorp_vault_address is defined + - hashicorp_secret_name_path is defined + +- name: Get all versions for secret {{ hashicorp_secret_name_path }} + community.hashi_vault.vault_read: + url: "{{ hashicorp_vault_address }}" + path: "secret/metadata/{{ secret_group}}/{{ _secret_name }}" + auth_method: token + token: '{{ _hashicorp_ephemeral_token | default(VAULT_PASSWORD) }}' + register: _hashicorp_read_secret_results + failed_when: false + +- set_fact: + _secret_versions: "{{ range(1,_hashicorp_read_secret_results.data.data.current_version+1) }}" + when: _hashicorp_read_secret_results.data.data.current_version | default(0) != 0 + +- name: Delete secret {{ hashicorp_secret_name_path }} + community.hashi_vault.vault_kv2_delete: + url: "{{ hashicorp_vault_address }}" + path: "{{ hashicorp_secret_name_path }}" + auth_method: token + token: '{{ _hashicorp_ephemeral_token | default(VAULT_PASSWORD) }}' + versions: "{{ _secret_versions | default(omit) }}" \ No newline at end of file diff --git a/automation-roles/99-generic/vault/vault-delete-secret/tasks/delete-secret.yml b/automation-roles/99-generic/vault/vault-delete-secret/tasks/delete-secret.yml index f17c7de01..6203b2bc3 100644 --- a/automation-roles/99-generic/vault/vault-delete-secret/tasks/delete-secret.yml +++ b/automation-roles/99-generic/vault/vault-delete-secret/tasks/delete-secret.yml @@ -4,7 +4,7 @@ - name: Validate mandatory variables are defined for Hashicorp Vault assert: that: - - vault_secret_path is defined + - vault.vault_secret_path is defined - set_fact: _secret_name: "{{ secret_name }}" @@ -14,46 +14,46 @@ when: _secret_name is search("/") - set_fact: - _hashicorp_secret_name_path: "{{ vault_secret_path }}/{{ secret_group}}/{{ _secret_name }}" + _hashicorp_secret_name_path: "{{ secret_group}}/{{ _secret_name }}" when: - - (vault_secret_path_append_group | default(True) | bool) + - (vault.vault_secret_path_append_group | default(True) | bool) - not _secret_name is search("/") - set_fact: - _hashicorp_secret_name_path: "{{ vault_secret_path }}/{{ _secret_name }}" + _hashicorp_secret_name_path: "{{ vault.vault_secret_path }}/{{ _secret_name }}" when: - - not (vault_secret_path_append_group | default(True) | bool) + - not (vault.vault_secret_path_append_group | default(True) | bool) - not _secret_name is search("/") - - name: Delete Secret Hashicorp vault (API Key), path {{ _hashicorp_secret_name_path }} + - name: Delete Secret Hashicorp vault (token), path {{ _hashicorp_secret_name_path }} include_tasks: delete-secret-hashicorp-token.yml vars: - hashicorp_vault_address: "{{ vault_url }}" + hashicorp_vault_address: "{{ VAULT_URL | default(vault.vault_url) }}" hashicorp_secret_name_path: "{{ _hashicorp_secret_name_path }}" - when: vault_authentication_type == 'token' + when: vault.vault_authentication_type == 'token' - name: Delete Secret Hashicorp vault (Certificate), path {{ _hashicorp_secret_name_path }} include_tasks: delete-secret-hashicorp-certificate.yml vars: - hashicorp_vault_address: "{{ vault_url }}" + hashicorp_vault_address: "{{ VAULT_URL | default(vault.vault_url) }}" hashicorp_secret_name_path: "{{ _hashicorp_secret_name_path }}" - when: vault_authentication_type == 'certificate' - when: "vault_type == 'hashicorp-vault'" + when: vault.vault_authentication_type == 'certificate' + when: vault.vault_type == 'hashicorp-vault' - name: Delete Secret from Vault IBM Cloud block: - name: Delete secret from Vault IBMCloud include_tasks: delete-secret-ibmcloud.yml vars: - ibmcloud_vault_address: "{{ vault_url }}" + ibmcloud_vault_address: "{{ vault.vault_url }}" ibm_cloud_secret_name: "{{ secret_name }}" - when: "vault_type == 'ibmcloud-vault'" + when: vault.vault_type == 'ibmcloud-vault' - name: Delete Secret from Vault file block: - name: Get secret in Vault file include_tasks: delete-secret-file.yml - when: "vault_type == 'file-vault'" + when: vault.vault_type == 'file-vault' - name: Secret {{ secret_group }}/{{ secret_name }} was deleted debug: diff --git a/automation-roles/99-generic/vault/vault-get-secret/tasks/get-secret-ansible-vault.yml b/automation-roles/99-generic/vault/vault-get-secret/tasks/get-secret-ansible-vault.yml index e21884e99..c3233facf 100644 --- a/automation-roles/99-generic/vault/vault-get-secret/tasks/get-secret-ansible-vault.yml +++ b/automation-roles/99-generic/vault/vault-get-secret/tasks/get-secret-ansible-vault.yml @@ -4,7 +4,7 @@ that: - secret_group is defined - secret_name is defined - - vault_password_file is defined + - vault.vault_password_file is defined - name: Fail if a secret field was specified for a vault other than Hashicorp fail: @@ -27,7 +27,7 @@ - name: Decrypt Ansible Vault file command: > ansible-vault decrypt - --vault-password-file {{ vault_password_file }} + --vault-password-file {{ vault.vault_password_file }} --output {{ temp_decrypted_file.path }} {{ status_dir }}/vault/{{ secret_group }} register: decrypt_result diff --git a/automation-roles/99-generic/vault/vault-get-secret/tasks/get-secret-file.yml b/automation-roles/99-generic/vault/vault-get-secret/tasks/get-secret-file.yml index 4c7541476..964b6417b 100644 --- a/automation-roles/99-generic/vault/vault-get-secret/tasks/get-secret-file.yml +++ b/automation-roles/99-generic/vault/vault-get-secret/tasks/get-secret-file.yml @@ -13,7 +13,7 @@ - name: Check that vault file {{ secret_group }} exists stat: path: "{{ status_dir }}/vault/{{ secret_group }}" - register: vault_file_details + register: _vault_file_details - name: Show command to retrieve secret from file debug: @@ -21,11 +21,11 @@ - set_fact: _secret_value_b64: "{{ lookup('ansible.builtin.pipe', lookup('template','get-secret-from-file.j2')) }}" - when: vault_file_details.stat.exists + when: _vault_file_details.stat.exists - set_fact: secret_value: "{{ _secret_value_b64 | b64decode }}" - when: vault_file_details.stat.exists + when: _vault_file_details.stat.exists - include_tasks: write-secret-to-file.yml when: secret_file | default("") != '' \ No newline at end of file diff --git a/automation-roles/99-generic/vault/vault-get-secret/tasks/get-secret-hashicorp-token.yml b/automation-roles/99-generic/vault/vault-get-secret/tasks/get-secret-hashicorp-token.yml index 2d5410ee9..0b660e5ad 100644 --- a/automation-roles/99-generic/vault/vault-get-secret/tasks/get-secret-hashicorp-token.yml +++ b/automation-roles/99-generic/vault/vault-get-secret/tasks/get-secret-hashicorp-token.yml @@ -10,6 +10,6 @@ url: "{{ hashicorp_vault_address }}" path: "{{ hashicorp_secret_name_path }}" auth_method: token - token: '{{ VAULT_PASSWORD }}' + token: '{{ _hashicorp_ephemeral_token | default(VAULT_PASSWORD) }}' register: hashicorp_vault_get_secret_result failed_when: False \ No newline at end of file diff --git a/automation-roles/99-generic/vault/vault-get-secret/tasks/get-secret-hashicorp.yml b/automation-roles/99-generic/vault/vault-get-secret/tasks/get-secret-hashicorp.yml index 3a164dbb5..793679141 100644 --- a/automation-roles/99-generic/vault/vault-get-secret/tasks/get-secret-hashicorp.yml +++ b/automation-roles/99-generic/vault/vault-get-secret/tasks/get-secret-hashicorp.yml @@ -1,13 +1,13 @@ - name: Validate mandatory variables are defined for Hashicorp Vault assert: that: - - vault_secret_path is defined - - vault_secret_field is defined + - vault.vault_secret_path is defined + - vault.vault_secret_field is defined - secret_name is defined - secret_group is defined - set_fact: - _secret_field: "{{ vault_secret_field }}" + _secret_field: "{{ vault.vault_secret_field }}" - set_fact: _secret_field: "{{ secret_name.split(',')[1] }}" @@ -23,38 +23,31 @@ - set_fact: _hashicorp_secret_name_path: "{{ secret_group}}/{{ _secret_name }}" when: - - (vault_secret_path_append_group | default(True) | bool) + - (vault.vault_secret_path_append_group | default(True) | bool) - not _secret_name is search("/") - set_fact: _hashicorp_secret_name_path: "{{ _secret_name }}" when: - - not (vault_secret_path_append_group | default(True) | bool) + - not (vault.vault_secret_path_append_group | default(True) | bool) - not _secret_name is search("/") - include_tasks: get-secret-hashicorp-token.yml vars: - hashicorp_vault_address: "{{ vault_url }}" + hashicorp_vault_address: "{{ VAULT_URL | default(vault.vault_url) }}" hashicorp_secret_name_path: "{{ _hashicorp_secret_name_path }}" when: - - vault_authentication_type == 'token' + - vault.vault_authentication_type == 'token' - include_tasks: get-secret-hashicorp-certificate.yml vars: - hashicorp_vault_address: "{{ vault_url }}" + hashicorp_vault_address: "{{ VAULT_URL | default(vault.vault_url) }}" hashicorp_secret_name_path: "{{ _hashicorp_secret_name_path }}" when: - - vault_authentication_type == 'certificate' + - vault.vault_authentication_type == 'certificate' - set_fact: secret_value: "{{ hashicorp_vault_get_secret_result['data']['data'][_secret_field] | default('') | b64decode }}" - when: - - vault.vault_secret_base64 | default(True) | bool - -- set_fact: - secret_value: "{{ hashicorp_vault_get_secret_result['data']['data'][_secret_field] | default('') }}" - when: - - not (vault.vault_secret_base64 | default(True) | bool) - include_tasks: write-secret-to-file.yml when: secret_file | default("") != '' \ No newline at end of file diff --git a/automation-roles/99-generic/vault/vault-get-secret/tasks/get-secret.yml b/automation-roles/99-generic/vault/vault-get-secret/tasks/get-secret.yml index b64b92ec4..957741a14 100644 --- a/automation-roles/99-generic/vault/vault-get-secret/tasks/get-secret.yml +++ b/automation-roles/99-generic/vault/vault-get-secret/tasks/get-secret.yml @@ -3,15 +3,15 @@ secret_value: "" - include_tasks: get-secret-hashicorp.yml - when: "vault_type == 'hashicorp-vault'" + when: "vault.vault_type == 'hashicorp-vault'" - name: Get Secret from IBM Cloud vault block: - include_tasks: get-secret-ibmcloud.yml vars: - ibmcloud_vault_address: "{{ vault_url }}" + ibmcloud_vault_address: "{{ vault.vault_url }}" ibm_cloud_secret_name: "{{ secret_name }}" - when: "vault_type == 'ibmcloud-vault'" + when: vault.vault_type == 'ibmcloud-vault' rescue: #Re-connect to vault - include_role: @@ -21,12 +21,12 @@ - name: Get Secret from Vault file include_tasks: get-secret-file.yml - when: "vault_type == 'file-vault'" + when: vault.vault_type == 'file-vault' - name: Get Secret from Ansible Vault block: - include_tasks: get-secret-ansible-vault.yml - when: "vault_type == 'ansible-vault'" + when: vault.vault_type == 'ansible-vault' rescue: #Re-connect to vault - include_role: diff --git a/automation-roles/99-generic/vault/vault-group/tasks/main.yaml b/automation-roles/99-generic/vault/vault-group/tasks/main.yaml index 8ec616f7d..193d0e6d7 100644 --- a/automation-roles/99-generic/vault/vault-group/tasks/main.yaml +++ b/automation-roles/99-generic/vault/vault-group/tasks/main.yaml @@ -3,14 +3,14 @@ - name: Validate mandatory variables are defined assert: that: - - vault_type is defined - - vault_authentication_type is defined + - vault.vault_type is defined + - vault.vault_authentication_type is defined - secret_group is defined - name: Get or create Group IBMCloud include_tasks: group-ibmcloud.yml vars: - ibmcloud_vault_address: "{{ vault_url }}" - ibmcloud_api_key: "{{ vault_api_key }}" + ibmcloud_vault_address: "{{ vault.vault_url }}" + ibmcloud_api_key: "{{ vault.vault_api_key }}" ibmcloud_secret_group_name: "{{ secret_group }}" - when: "vault_type == 'ibmcloud-vault'" + when: "vault.vault_type == 'ibmcloud-vault'" diff --git a/automation-roles/99-generic/vault/vault-has-secret/tasks/has-secret-file.yml b/automation-roles/99-generic/vault/vault-has-secret/tasks/has-secret-file.yml deleted file mode 100644 index 9380475be..000000000 --- a/automation-roles/99-generic/vault/vault-has-secret/tasks/has-secret-file.yml +++ /dev/null @@ -1,35 +0,0 @@ ---- -- name: Get secret Validate mandatory variables are defined - assert: - that: - - secret_group is defined - - secret_name is defined - -- name: Create directory {{ status_dir }}/vault if not existent - file: - path: "{{ status_dir }}/vault" - state: directory - -- name: Create file-vault file {{ status_dir }}/vault/{{ secret_group }} if not existent - file: - path: "{{ status_dir }}/vault/{{ secret_group }}" - state: touch - -- name: Show command to retrieve secret from file - debug: - msg: "{{ lookup('template','get-secret-from-file.j2') }}" - -- set_fact: - _secret_value_b64: "{{ lookup('ansible.builtin.pipe', lookup('template','get-secret-from-file.j2')) }}" - -- set_fact: - has_secret: false - when: (_secret_value_b64 | length) == 0 - -- set_fact: - has_secret: true - when: (_secret_value_b64 | length) != 0 - -- name: Result of determining if secret exists - debug: - msg: "Secret {{ secret_name }} lookup resulted in: {{ has_secret }}" \ No newline at end of file diff --git a/automation-roles/99-generic/vault/vault-has-secret/tasks/has-secret-hashicorp-api-key.yml b/automation-roles/99-generic/vault/vault-has-secret/tasks/has-secret-hashicorp-api-key.yml deleted file mode 100644 index c71abed11..000000000 --- a/automation-roles/99-generic/vault/vault-has-secret/tasks/has-secret-hashicorp-api-key.yml +++ /dev/null @@ -1,37 +0,0 @@ ---- -- name: Has secret Validate mandatory variables are defined - assert: - that: - - hashicorp_vault_address is defined - - hashicorp_secret_name_path is defined - - hashicorp_secret_field is defined - -- name: Validate if secret is available - shell: | - vault kv get \ - -address={{ hashicorp_vault_address }} \ - -field={{ hashicorp_secret_field }} \ - {{ hashicorp_secret_name_path }} - ignore_errors: yes - no_log: true - register: hashicorp_vault_get_secret_result - -- set_fact: - has_secret: true - when: "hashicorp_vault_get_secret_result.rc == 0" - -- set_fact: - has_secret: false - when: - - "not hashicorp_vault_get_secret_result.rc == 0" - - "hashicorp_vault_get_secret_result.stderr.startswith('No value found')" - -- fail: - msg: Hashicorp kv get failed - when: - - "not hashicorp_vault_get_secret_result.rc == 0" - - "not hashicorp_vault_get_secret_result.stderr.startswith('No value found')" - -- name: Result of checking if secret exists - debug: - msg: "Secret {{ hashicorp_secret_name_path }} field {{ hashicorp_secret_field }} lookup resulted in {{ has_secret }}" \ No newline at end of file diff --git a/automation-roles/99-generic/vault/vault-has-secret/tasks/has-secret-hashicorp-certificate.yml b/automation-roles/99-generic/vault/vault-has-secret/tasks/has-secret-hashicorp-certificate.yml deleted file mode 100644 index 1d81eac23..000000000 --- a/automation-roles/99-generic/vault/vault-has-secret/tasks/has-secret-hashicorp-certificate.yml +++ /dev/null @@ -1,43 +0,0 @@ ---- -- name: Has secret Validate mandatory variables are defined - assert: - that: - - hashicorp_vault_address is defined - - VAULT_CERT_CA_FILE is defined - - VAULT_CERT_KEY_FILE is defined - - VAULT_CERT_CERT_FILE is defined - - hashicorp_secret_name_path is defined - - hashicorp_secret_field is defined - -- name: Validate if secret is available - shell: | - vault kv get \ - -ca-cert={{ VAULT_CERT_CA_FILE }} \ - -client-cert={{ VAULT_CERT_CERT_FILE }} \ - -client-key={{ VAULT_CERT_KEY_FILE }} \ - -address={{ hashicorp_vault_address }} \ - -field={{ hashicorp_secret_field }} \ - {{ hashicorp_secret_name_path }} - ignore_errors: yes - no_log: true - register: hashicorp_vault_get_secret_result - -- set_fact: - has_secret: true - when: "hashicorp_vault_get_secret_result.rc == 0" - -- set_fact: - has_secret: false - when: - - "not hashicorp_vault_get_secret_result.rc == 0" - - "hashicorp_vault_get_secret_result.stderr.startswith('No value found')" - -- fail: - msg: Hashicorp kv get failed - when: - - "not hashicorp_vault_get_secret_result.rc == 0" - - "not hashicorp_vault_get_secret_result.stderr.startswith('No value found')" - -- name: Result of checking if secret exists - debug: - msg: "Secret {{ hashicorp_secret_name_path }} field {{ hashicorp_secret_field }} lookup resulted in {{ has_secret }}" \ No newline at end of file diff --git a/automation-roles/99-generic/vault/vault-has-secret/tasks/main.yml b/automation-roles/99-generic/vault/vault-has-secret/tasks/main.yml index 7dfaa52ff..62c913716 100644 --- a/automation-roles/99-generic/vault/vault-has-secret/tasks/main.yml +++ b/automation-roles/99-generic/vault/vault-has-secret/tasks/main.yml @@ -1,64 +1,10 @@ --- -- name: Has Secret from Vault Hashicorp - block: - - name: Validate mandatory variables are defined for Hashicorp Vault - assert: - that: - - secret_name is defined - - vault_secret_path is defined - - vault_secret_field is defined - - secret_group is defined - - - set_fact: - _secret_field: "{{ vault_secret_field }}" - - - set_fact: - _secret_field: "{{ secret_name.split(',')[1] }}" - when: secret_name is search(",") - - - set_fact: - _secret_name: "{{ secret_name.split(',')[0] }}" - - - set_fact: - _hashicorp_secret_name_path: "{{ _secret_name }}" - when: _secret_name is search("/") - - - set_fact: - _hashicorp_secret_name_path: "{{ vault_secret_path }}/{{ secret_group}}/{{ _secret_name }}" - when: - - (vault_secret_path_append_group | default(True) | bool) - - not _secret_name is search("/") - - - set_fact: - _hashicorp_secret_name_path: "{{ vault_secret_path }}/{{ _secret_name }}" - when: - - not (vault_secret_path_append_group | default(True) | bool) - - not _secret_name is search("/") - - - name: Has Secret Hashicorp vault (API Key), path {{ _hashicorp_secret_name_path }} - include_tasks: has-secret-hashicorp-token.yml - vars: - hashicorp_vault_address: "{{ vault_url }}" - hashicorp_secret_name_path: "{{ _hashicorp_secret_name_path }}" - hashicorp_secret_field: "{{ _secret_field }}" - when: vault_authentication_type == 'token' - - - name: Has Secret Hashicorp vault (Certificate), path {{ _hashicorp_secret_name_path }} - include_tasks: has-secret-hashicorp-certificate.yml - vars: - hashicorp_vault_address: "{{ vault_url }}" - hashicorp_secret_name_path: "{{ _hashicorp_secret_name_path }}" - hashicorp_secret_field: "{{ _secret_field }}" - when: vault_authentication_type == 'certificate' - when: "vault_type == 'hashicorp-vault'" - - name: Has Secret from Vault IBM Cloud block: - name: Validate mandatory variables are defined for Vault IBM Cloud assert: that: - secret_name is defined - - vault_url is defined - secret_group is defined - name: Fail if a secret field was specified for a vault other than Hashicorp @@ -69,24 +15,6 @@ - name: Has secret in Vault IBMCloud include_tasks: has-secret-ibmcloud.yml vars: - ibmcloud_vault_address: "{{ vault_url }}" + ibmcloud_vault_address: "{{ vault.vault_url }}" ibm_cloud_secret_name: "{{ secret_name }}" - when: "vault_type == 'ibmcloud-vault'" - -- name: Has Secret from Vault file - block: - - - name: Validate mandatory variables are defined for Vault file - assert: - that: - - secret_name is defined - - - name: Fail if a secret field was specified for a vault other than Hashicorp - fail: - msg: "Secret name {{ secret_name }} can only have a secret field specification for Hashicorp Vault" - when: secret_name is search(",") - - - name: Has secret in Vault file - include_tasks: has-secret-file.yml - - when: "vault_type == 'file-vault'" + when: "vault.vault_type == 'ibmcloud-vault'" \ No newline at end of file diff --git a/automation-roles/99-generic/vault/vault-has-secret/templates/get-secret-from-file.j2 b/automation-roles/99-generic/vault/vault-has-secret/templates/get-secret-from-file.j2 deleted file mode 100644 index 6fa544e77..000000000 --- a/automation-roles/99-generic/vault/vault-has-secret/templates/get-secret-from-file.j2 +++ /dev/null @@ -1 +0,0 @@ -grep -E "^{{ secret_name }}=" {{ status_dir }}/vault/{{ secret_group }} | cut -d "=" -f 2- \ No newline at end of file diff --git a/automation-roles/99-generic/vault/vault-has-secret/vars/main.yml b/automation-roles/99-generic/vault/vault-has-secret/vars/main.yml deleted file mode 100644 index e69de29bb..000000000 diff --git a/automation-roles/99-generic/vault/vault-list-secrets/tasks/list-secrets-file.yml b/automation-roles/99-generic/vault/vault-list-secrets/tasks/list-secrets-file.yml index 0c287da7f..338e9d4d0 100644 --- a/automation-roles/99-generic/vault/vault-list-secrets/tasks/list-secrets-file.yml +++ b/automation-roles/99-generic/vault/vault-list-secrets/tasks/list-secrets-file.yml @@ -7,11 +7,11 @@ - name: Check that vault file {{ secret_group }} exists stat: path: "{{ status_dir }}/vault/{{ secret_group }}" - register: vault_file_details + register: _vault_file_details - set_fact: secret_list: [] - when: not vault_file_details.stat.exists + when: not _vault_file_details.stat.exists - set_fact: temp_list: "{{ lookup('file', status_dir + '/vault/' + secret_group).splitlines() }}" diff --git a/automation-roles/99-generic/vault/vault-list-secrets/tasks/list-secrets-hashicorp-token.yml b/automation-roles/99-generic/vault/vault-list-secrets/tasks/list-secrets-hashicorp-token.yml index bec72d24c..a1285e44f 100644 --- a/automation-roles/99-generic/vault/vault-list-secrets/tasks/list-secrets-hashicorp-token.yml +++ b/automation-roles/99-generic/vault/vault-list-secrets/tasks/list-secrets-hashicorp-token.yml @@ -10,7 +10,7 @@ url: "{{ hashicorp_vault_address }}" path: "{{ hashicorp_secret_name_path }}" auth_method: token - token: '{{ VAULT_PASSWORD }}' + token: '{{ _hashicorp_ephemeral_token | default(VAULT_PASSWORD) }}' register: hashicorp_vault_list_secrets_result - name: Result of listing secrets diff --git a/automation-roles/99-generic/vault/vault-list-secrets/tasks/main.yml b/automation-roles/99-generic/vault/vault-list-secrets/tasks/main.yml index c94f686fb..4c74110aa 100644 --- a/automation-roles/99-generic/vault/vault-list-secrets/tasks/main.yml +++ b/automation-roles/99-generic/vault/vault-list-secrets/tasks/main.yml @@ -5,7 +5,7 @@ - name: Validate mandatory variables are defined for Hashicorp Vault assert: that: - - vault_secret_path is defined + - vault.vault_secret_path is defined - secret_group is defined - set_fact: @@ -16,41 +16,41 @@ when: _secret_name is search("/") - set_fact: - _hashicorp_secret_name_path: "{{ vault_secret_path }}/metadata/{{ secret_group}}" + _hashicorp_secret_name_path: "{{ vault.vault_secret_path }}/metadata/{{ secret_group}}" when: - - (vault_secret_path_append_group | default(True) | bool) + - (vault.vault_secret_path_append_group | default(True) | bool) - not _secret_name is search("/") - set_fact: - _hashicorp_secret_name_path: "{{ vault_secret_path }}/metadata" + _hashicorp_secret_name_path: "{{ vault.vault_secret_path }}/metadata" when: - - not (vault_secret_path_append_group | default(True) | bool) + - not (vault.vault_secret_path_append_group | default(True) | bool) - not _secret_name is search("/") - name: List secrets in Hashicorp vault (API Key), path {{ _hashicorp_secret_name_path }} include_tasks: list-secrets-hashicorp-token.yml vars: - hashicorp_vault_address: "{{ vault_url }}" + hashicorp_vault_address: "{{ VAULT_URL | default(vault.vault_url) }}" hashicorp_secret_name_path: "{{ _hashicorp_secret_name_path }}" - when: vault_authentication_type == 'token' + when: vault.vault_authentication_type == 'token' - name: List secrets in Hashicorp vault (Certificate), path {{ _hashicorp_secret_name_path }} include_tasks: list-secrets-hashicorp-certificate.yml vars: - hashicorp_vault_address: "{{ vault_url }}" + hashicorp_vault_address: "{{ VAULT_URL | default(vault.vault_url) }}" hashicorp_secret_name_path: "{{ _hashicorp_secret_name_path }}" - when: vault_authentication_type == 'certificate' - when: "vault_type == 'hashicorp-vault'" + when: vault.vault_authentication_type == 'certificate' + when: vault.vault_type == 'hashicorp-vault' - name: List secrets from Vault IBM Cloud include_tasks: list-secrets-ibmcloud.yml vars: - ibmcloud_vault_address: "{{ vault_url }}" - when: "vault_type == 'ibmcloud-vault'" + ibmcloud_vault_address: "{{ vault.vault_url }}" + when: vault.vault_type == 'ibmcloud-vault' - name: List secrets from Vault file include_tasks: list-secrets-file.yml - when: "vault_type == 'file-vault'" + when: vault.vault_type == 'file-vault' - name: Secrets in group {{ secret_group }} debug: diff --git a/automation-roles/99-generic/vault/vault-set-secret/tasks/create-secret-ansible-vault.yml b/automation-roles/99-generic/vault/vault-set-secret/tasks/create-secret-ansible-vault.yml index 181dc6b0b..994e9aaae 100644 --- a/automation-roles/99-generic/vault/vault-set-secret/tasks/create-secret-ansible-vault.yml +++ b/automation-roles/99-generic/vault/vault-set-secret/tasks/create-secret-ansible-vault.yml @@ -5,7 +5,7 @@ - secret_group is defined - secret_name is defined - file_secret_payload is defined - - vault_password_file is defined + - vault.vault_password_file is defined - name: Fail if a secret field was specified for a vault other than Hashicorp fail: @@ -20,7 +20,7 @@ - name: Check if Ansible Vault file exists stat: path: "{{ status_dir }}/vault/{{ secret_group }}" - register: ansible_vault_file_stat + register: _ansible_vault_file_stat - name: Handle Ansible Vault file creation or update block: @@ -33,10 +33,10 @@ - name: Decrypt existing Ansible Vault file if it exists command: > ansible-vault decrypt - --vault-password-file {{ vault_password_file }} + --vault-password-file {{ vault.vault_password_file }} --output {{ temp_plaintext_file.path }} {{ status_dir }}/vault/{{ secret_group }} - when: ansible_vault_file_stat.stat.exists + when: _ansible_vault_file_stat.stat.exists changed_when: false - name: Add or replace secret in plaintext file @@ -50,7 +50,7 @@ - name: Encrypt plaintext file to Ansible Vault command: > ansible-vault encrypt - --vault-password-file {{ vault_password_file }} + --vault-password-file {{ vault.vault_password_file }} --output {{ status_dir }}/vault/{{ secret_group }} {{ temp_plaintext_file.path }} changed_when: true diff --git a/automation-roles/99-generic/vault/vault-set-secret/tasks/create-secret-hashicorp-certificate.yml b/automation-roles/99-generic/vault/vault-set-secret/tasks/create-secret-hashicorp-certificate.yml index fa880d340..fe2a73f3d 100644 --- a/automation-roles/99-generic/vault/vault-set-secret/tasks/create-secret-hashicorp-certificate.yml +++ b/automation-roles/99-generic/vault/vault-set-secret/tasks/create-secret-hashicorp-certificate.yml @@ -12,7 +12,7 @@ - set_fact: _hashicorp_secret_value: "{{ {} | combine({hashicorp_secret_field: hashicorp_secret_payload}) }}" -- name: Get value for secret {{ hashicorp_secret_name_path }} +- name: Set value for secret {{ hashicorp_secret_name_path }} community.hashi_vault.vault_kv2_write: url: "{{ hashicorp_vault_address }}" path: "{{ hashicorp_secret_name_path }}" diff --git a/automation-roles/99-generic/vault/vault-set-secret/tasks/create-secret-hashicorp-token.yml b/automation-roles/99-generic/vault/vault-set-secret/tasks/create-secret-hashicorp-token.yml index 1e0450d01..462c5bc26 100644 --- a/automation-roles/99-generic/vault/vault-set-secret/tasks/create-secret-hashicorp-token.yml +++ b/automation-roles/99-generic/vault/vault-set-secret/tasks/create-secret-hashicorp-token.yml @@ -14,5 +14,5 @@ url: "{{ hashicorp_vault_address }}" path: "{{ hashicorp_secret_name_path }}" auth_method: token - token: '{{ VAULT_PASSWORD }}' + token: '{{ _hashicorp_ephemeral_token | default(VAULT_PASSWORD) }}' data: "{{ _hashicorp_secret_value}}" \ No newline at end of file diff --git a/automation-roles/99-generic/vault/vault-set-secret/tasks/create-secret-hashicorp.yml b/automation-roles/99-generic/vault/vault-set-secret/tasks/create-secret-hashicorp.yml index cac68e031..e83df4e8b 100644 --- a/automation-roles/99-generic/vault/vault-set-secret/tasks/create-secret-hashicorp.yml +++ b/automation-roles/99-generic/vault/vault-set-secret/tasks/create-secret-hashicorp.yml @@ -1,11 +1,11 @@ - name: Validate mandatory variables are defined for Hashicorp Vault assert: that: - - vault_secret_path is defined - - vault_secret_field is defined + - vault.vault_secret_path is defined + - vault.vault_secret_field is defined - set_fact: - _secret_field: "{{ vault_secret_field }}" + _secret_field: "{{ vault.vault_secret_field }}" - set_fact: _secret_field: "{{ secret_name.split(',')[1] }}" @@ -27,50 +27,36 @@ - set_fact: _hashicorp_secret_name_path: "{{ _secret_name }}" when: - - not (vault_secret_path_append_group | default(True) | bool) + - not (vault.vault_secret_path_append_group | default(True) | bool) - not _secret_name is search("/") -- set_fact: - _secret_payload: "{{ secret_payload }}" - when: - - (secret_file | default("") == "") - - not (vault.vault_secret_base64 | default(True) | bool) - - set_fact: _secret_payload: "{{ secret_payload | b64encode }}" when: - (secret_file | default("") == "") - - (vault.vault_secret_base64 | default(True) | bool) - -- set_fact: - _secret_payload: "{{ lookup('file',secret_file) }}" - when: - - (secret_file | default("") != "") - - not (vault.vault_secret_base64 | default(True) | bool) - set_fact: _secret_payload: "{{ lookup('file',secret_file) | b64encode }}" when: - (secret_file | default("") != "") - - (vault.vault_secret_base64 | default(True) | bool) - include_tasks: create-secret-hashicorp-token.yml vars: - hashicorp_vault_address: "{{ vault_url }}" + hashicorp_vault_address: "{{ VAULT_URL | default(vault.vault_url) }}" hashicorp_secret_name_path: "{{ _hashicorp_secret_name_path }}" hashicorp_secret_field: "{{ _secret_field }}" hashicorp_secret_payload: "{{ _secret_payload }}" when: - - vault_authentication_type == 'token' + - vault.vault_authentication_type == 'token' - include_tasks: create-secret-hashicorp-certificate.yml vars: - hashicorp_vault_address: "{{ vault_url }}" + hashicorp_vault_address: "{{ VAULT_URL | default(vault.vault_url) }}" hashicorp_secret_name_path: "{{ _hashicorp_secret_name_path }}" hashicorp_secret_field: "{{ _secret_field }}" hashicorp_secret_payload: "{{ _secret_payload }}" when: - - vault_authentication_type == 'certificate' + - vault.vault_authentication_type == 'certificate' - name: Successfully set secret {{ _hashicorp_secret_name_path }} in Hashicorp Vault debug: diff --git a/automation-roles/99-generic/vault/vault-set-secret/tasks/create-secret.yml b/automation-roles/99-generic/vault/vault-set-secret/tasks/create-secret.yml index 733557ab5..7623134a5 100644 --- a/automation-roles/99-generic/vault/vault-set-secret/tasks/create-secret.yml +++ b/automation-roles/99-generic/vault/vault-set-secret/tasks/create-secret.yml @@ -17,17 +17,17 @@ when: (secret_file | default('')) == '' - include_tasks: create-secret-hashicorp.yml - when: vault_type == 'hashicorp-vault' + when: vault.vault_type == 'hashicorp-vault' - name: Set secret Vault IBM Cloud block: - include_tasks: create-secret-ibmcloud.yml vars: - ibmcloud_vault_address: "{{ vault_url }}" + ibmcloud_vault_address: "{{ vault.vault_url }}" ibm_cloud_secret_name: "{{ secret_name }}" ibm_vault_secret_payload: "{{ secret_value_to_set }}" - when: "vault_type == 'ibmcloud-vault'" + when: vault.vault_type == 'ibmcloud-vault' rescue: #Re-connect to vault - include_role: @@ -41,14 +41,14 @@ - include_tasks: create-secret-file.yml vars: file_secret_payload: "{{ secret_value_to_set }}" - when: "vault_type == 'file-vault'" + when: vault.vault_type == 'file-vault' - name: Set secret in Ansible Vault block: - include_tasks: create-secret-ansible-vault.yml vars: file_secret_payload: "{{ secret_value_to_set }}" - when: "vault_type == 'ansible-vault'" + when: vault.vault_type == 'ansible-vault' rescue: #Re-connect to vault - include_role: diff --git a/cp-deploy.sh b/cp-deploy.sh index d91979f8b..0d31a2e31 100755 --- a/cp-deploy.sh +++ b/cp-deploy.sh @@ -41,6 +41,7 @@ command_usage() { echo " --accept-all-licenses Accept all Cloud Pak licenses (\$CPD_ACCEPT_LICENSES)" echo " --ibm-cloud-api-key API key to authenticate to the IBM Cloud (\$IBM_CLOUD_API_KEY)" echo " --vault-password Password (Ansible) or token (Hashicorp Vault) to login to the vault (\$VAULT_PASSWORD)" + echo " --vault-url URL for HashiCorp Vault (\$VAULT_URL)" echo " --vault-cert-ca-file File with CA of login certificate (\$VAULT_CERT_CA_FILE)" echo " --vault-cert-key-file File with login certificate key (\$VAULT_CERT_KEYFILE)" echo " --vault-cert-cert-file File with login certificate (\$VAULT_CERT_CERT_FILE)" @@ -48,8 +49,8 @@ command_usage() { echo " --skip-infra Skip infrastructure provisioning and configuration (\$CPD_SKIP_INFRA)" echo " --skip-cp-install Skip installation of the Cloud Pak and finish after configuring the OpenShift cluster (\$SKIP_CP_INSTALL)" echo " --cp-config-only Skip all infrastructure provisioning and cloud pak deployment tasks and only run the Cloud Pak configuration tasks" - echo " --check-only Skip all provisioning and deployment tasks. Only run the validation and generation" - echo " --dry-run Only log the steps that will be performed, do not make any changes to the OpenShift cluster" + echo " --check-only Skip all provisioning and deployment tasks. Only run the validation and generation (\$CHECK_ONLY)" + echo " --dry-run Only log the steps that will be performed, do not make any changes to the OpenShift cluster (\$CPD_DRY_RUN)" echo " --air-gapped Only for environment subcommand; if specified the deployer is considered to run in an air-gapped environment (\$CPD_AIRGAP)" echo " --skip-mirror-images Pertains to env apply and env download. When specified, the mirroring of images to the private registry is skipped (\$CPD_SKIP_MIRROR)" echo " --skip-portable-registry Pertains to env download. When specified, no portable registry is used to transport the images (\$CPD_SKIP_PORTABLE_REGISTRY)" @@ -452,6 +453,19 @@ while (( "$#" )); do fi fi ;; + --vault-utl*) + if [[ "$1" =~ "=" ]] && [ ! -z "${1#*=}" ] && [ "${1#*=:0:1}" != "-" ];then + export VAULT_URL="${1#*=}" + shift 1 + else if [ -n "$2" ] && [ ${2:0:1} != "-" ];then + export VAULT_URL=$2 + shift 2 + else + echo "Error: Missing argument for --vault-url parameter." + command_usage 2 + fi + fi + ;; --vault-cert-ca-file*) if [[ "$1" =~ "=" ]] && [ ! -z "${1#*=}" ] && [ "${1#*=:0:1}" != "-" ];then export VAULT_CERT_CA_FILE="${1#*=}" @@ -1050,6 +1064,10 @@ if ! $INSIDE_CONTAINER;then fi done + if [ ! -z $VAULT_URL ];then + run_cmd+=" -e VAULT_URL=${VAULT_URL}" + fi + if [ ! -z $VAULT_PASSWORD ];then run_cmd+=" -e VAULT_PASSWORD=${VAULT_PASSWORD}" fi diff --git a/docker-scripts/run_automation.sh b/docker-scripts/run_automation.sh index 5c98f61f0..2b9bfd825 100755 --- a/docker-scripts/run_automation.sh +++ b/docker-scripts/run_automation.sh @@ -105,6 +105,9 @@ env|environment) run_cmd+=" --extra-vars IMAGE_ARCH=${IMAGE_ARCH}" run_cmd+=" --extra-vars OLM_UTILS_IMAGE=${OLM_UTILS_IMAGE}" + if [ ! -z $VAULT_URL ];then + run_cmd+=" --extra-vars VAULT_URL=${VAULT_URL}" + fi if [ ! -z $VAULT_PASSWORD ];then run_cmd+=" --extra-vars VAULT_PASSWORD=${VAULT_PASSWORD}" fi @@ -184,6 +187,9 @@ vault) run_cmd+=" --extra-vars status_dir=${STATUS_DIR}" run_cmd+=" --extra-vars ibmcloud_api_key=${IBM_CLOUD_API_KEY}" run_cmd+=" --extra-vars secret_group_param=${VAULT_GROUP}" + if [ ! -z $VAULT_URL ];then + run_cmd+=" --extra-vars VAULT_URL=${VAULT_URL}" + fi if [ ! -z $VAULT_PASSWORD ];then run_cmd+=" --extra-vars VAULT_PASSWORD=${VAULT_PASSWORD}" fi diff --git a/docs/src/30-reference/configuration/vault.md b/docs/src/30-reference/configuration/vault.md index ffca6d6ca..a93d5c2a9 100644 --- a/docs/src/30-reference/configuration/vault.md +++ b/docs/src/30-reference/configuration/vault.md @@ -22,7 +22,6 @@ Sample Vault config: ``` vault: vault_type: file-vault - vault_authentication_type: none ``` ### Properties for all vault implementations @@ -33,9 +32,7 @@ vault: ### Properties for `file-vault` -| Property | Description | Mandatory | Allowed values | -| -------- | -------------------------------------------------------------------- | --------- | -------------- | -| vault_authentication_type | Authentication method for the file vault | No | none | +None. ### Properties for `ansible-vault` @@ -66,9 +63,42 @@ vault: | Property | Description | Mandatory | Allowed values | | -------- | --------------------------------------------------------------------- | --------- | -------------- | | vault_authentication_type | Authentication method for the Hashicorp vault | Yes | token, certificate | -| vault_url | URL for the Hashicorp vault, this is typically https://hostname:8200 | Yes | | -| vault_api_key | When authentication type is api-key, the field to authenticate with | Yes | | +| vault_url | URL for the Hashicorp vault, this is typically https://hostname:8200 | No, if not specified value is taken from VAULT_URL environment variable | | | vault_secret_path | Default secret path to store and retrieve secrets into/from | Yes | | | vault_secret_field | Field to store or retrieve vault secrets | Yes | | | vault_secret_path_append_group | Determines whether or not the secrete group will be appended to the path | Yes | True (default), False | -| vault_secret_base64 | Depicts if secrets are stored in base64 format for Hashicorp Vault | No | True (default), False | \ No newline at end of file +| vault_exchange_token | Depicts if the VAULT_PASSWORD passed to deployer is exchanged with another token | No | False (default), True | + +##### Set up HashiCorp Vault for short-lived token creation + +To create the short-lived token, make sure there is a policy that can write to the secret path and to the token creation path. The `sample` path from the below example is taken from the `global_config.environment_id` property. + +``` +cat << EOF > /tmp/sample-policy.hcl +# Secrets access (KV Version 2) +path "secret/data/sample/*" { + capabilities = ["create", "read", "update", "delete"] +} + +# Metadata access for listing secrets (KV Version 2) +path "secret/metadata/sample/*" { + capabilities = ["list", "read"] +} + +# Allows this token to create child tokens attached to this same policy +path "auth/token/create" { + capabilities = ["create", "update","sudo"] +} +EOF + +vault policy write deployer-sample-policy /tmp/sample-policy.hcl +``` + +#### Create short-lived token + +``` +export VAULT_PASSWORD=$(vault token create -policy="deployer-sample-policy" -ttl="10m" -field=token) +echo ${VAULT_PASSWORD} +``` + +Then you can start Cloud Pak Deployer. \ No newline at end of file diff --git a/sample-configurations/cp4i-existing-ocp/config/sample-cp4i.yaml b/sample-configurations/cp4i-existing-ocp/config/sample-cp4i.yaml index 6364d1d2b..6210f8eb0 100644 --- a/sample-configurations/cp4i-existing-ocp/config/sample-cp4i.yaml +++ b/sample-configurations/cp4i-existing-ocp/config/sample-cp4i.yaml @@ -8,7 +8,6 @@ global_config: vault: vault_type: file-vault - vault_authentication_type: none openshift: - name: "{{ env_id }}" diff --git a/sample-configurations/sample-dynamic/config-samples/vault-file.yaml b/sample-configurations/sample-dynamic/config-samples/vault-file.yaml index 886c9f3a3..af7a2a115 100644 --- a/sample-configurations/sample-dynamic/config-samples/vault-file.yaml +++ b/sample-configurations/sample-dynamic/config-samples/vault-file.yaml @@ -1,4 +1,3 @@ --- vault: - vault_type: file-vault - vault_authentication_type: none \ No newline at end of file + vault_type: file-vault \ No newline at end of file diff --git a/sample-configurations/sample-dynamic/config-samples/vault-hashicorp-cert.yaml b/sample-configurations/sample-dynamic/config-samples/vault-hashicorp-cert.yaml index a3c6efa65..249d8e634 100644 --- a/sample-configurations/sample-dynamic/config-samples/vault-hashicorp-cert.yaml +++ b/sample-configurations/sample-dynamic/config-samples/vault-hashicorp-cert.yaml @@ -5,5 +5,4 @@ vault: vault_url: https://hcvault:8200 vault_secret_path: secret/ibm vault_secret_path_append_group: True - vault_secret_field: value - vault_secret_base64: True \ No newline at end of file + vault_secret_field: key \ No newline at end of file diff --git a/sample-configurations/sample-dynamic/config-samples/vault-hashicorp-token.yaml b/sample-configurations/sample-dynamic/config-samples/vault-hashicorp-token.yaml index c8f3c772c..649924be4 100644 --- a/sample-configurations/sample-dynamic/config-samples/vault-hashicorp-token.yaml +++ b/sample-configurations/sample-dynamic/config-samples/vault-hashicorp-token.yaml @@ -3,8 +3,7 @@ vault: vault_type: hashicorp-vault vault_authentication_type: token vault_url: http://10.215.26.181:8200 - vault_api_key: vaulttoken vault_secret_path: secret/ibm vault_secret_path_append_group: True - vault_secret_field: value - vault_secret_base64: True \ No newline at end of file + vault_secret_field: key + vault_exchange_token: False \ No newline at end of file diff --git a/sample-configurations/sample-dynamic/sample-inventory/sample.inv b/sample-configurations/sample-dynamic/sample-inventory/sample.inv index 805c5eade..bfff10bc4 100644 --- a/sample-configurations/sample-dynamic/sample-inventory/sample.inv +++ b/sample-configurations/sample-dynamic/sample-inventory/sample.inv @@ -43,7 +43,6 @@ vault_authentication_type=none #vault_secret_path=secret/ibm #vault_secret_path_append_group=True #vault_secret_field=value -#vault_secret_base64=True ######################################################## # Using Hashicorp Vault with vault token authentication @@ -51,8 +50,6 @@ vault_authentication_type=none #vault_type=hashicorp-vault #vault_authentication_type=token #vault_url=http://10.215.26.181:8200 -#vault_api_key=vaulttoken #vault_secret_path=secret/ibm #vault_secret_path_append_group=True #vault_secret_field=value -#vault_secret_base64=True From 4b4ff69c34938be5b4dbf3fbe23e8fee984ae0ad Mon Sep 17 00:00:00 2001 From: Frank Ketelaars Date: Tue, 19 May 2026 11:08:03 +0000 Subject: [PATCH 2/2] #1123 Don't fail if not --confirm-destroy and namespace no longer exists --- .../tasks/cp4d-cluster-delete.yml | 20 ++++++++++++++ .../cp4d/cp4d-cluster-delete/tasks/main.yml | 26 ++++++------------- 2 files changed, 28 insertions(+), 18 deletions(-) create mode 100644 automation-roles/50-install-cloud-pak/cp4d/cp4d-cluster-delete/tasks/cp4d-cluster-delete.yml diff --git a/automation-roles/50-install-cloud-pak/cp4d/cp4d-cluster-delete/tasks/cp4d-cluster-delete.yml b/automation-roles/50-install-cloud-pak/cp4d/cp4d-cluster-delete/tasks/cp4d-cluster-delete.yml new file mode 100644 index 000000000..cf1b24dcf --- /dev/null +++ b/automation-roles/50-install-cloud-pak/cp4d/cp4d-cluster-delete/tasks/cp4d-cluster-delete.yml @@ -0,0 +1,20 @@ +--- +- name: Fail if destroy was not confirmed + fail: + msg: "Destroy of Cloud Pak for Data cluster {{ _p_current_cp4d_cluster.project }} was not confirmed with --confirm-destroy parameter or via global_config confirm_destroy property" + when: + - _confirm_destroy | bool != True + - not cpd_dry_run + +- name: Login to the OpenShift cluster "{{ _p_current_cp4d_cluster.openshift_cluster_name }}" + include_role: + name: openshift-login + vars: + _p_openshift_cluster_name: "{{ _p_current_cp4d_cluster.openshift_cluster_name }}" + +- name: Delete Cloud Pak for Data instance {{ _p_current_cp4d_cluster.project }} and its operators, logs are in {{ status_dir }}/log/{{ _p_current_cp4d_cluster.project }}-destroy.log + shell: | + {{ playbook_dir }}/../scripts/cp4d/cp4d-delete-instance.sh {{ _p_current_cp4d_cluster.project }} | tee -a {{ status_dir }}/log/{{ _p_current_cp4d_cluster.project }}-destroy.log + environment: + CPD_CONFIRM_DELETE: "true" + CPD_DESTROY_CLUSTER_WIDE: "false" \ No newline at end of file diff --git a/automation-roles/50-install-cloud-pak/cp4d/cp4d-cluster-delete/tasks/main.yml b/automation-roles/50-install-cloud-pak/cp4d/cp4d-cluster-delete/tasks/main.yml index cf1b24dcf..cc2240657 100644 --- a/automation-roles/50-install-cloud-pak/cp4d/cp4d-cluster-delete/tasks/main.yml +++ b/automation-roles/50-install-cloud-pak/cp4d/cp4d-cluster-delete/tasks/main.yml @@ -1,20 +1,10 @@ --- -- name: Fail if destroy was not confirmed - fail: - msg: "Destroy of Cloud Pak for Data cluster {{ _p_current_cp4d_cluster.project }} was not confirmed with --confirm-destroy parameter or via global_config confirm_destroy property" - when: - - _confirm_destroy | bool != True - - not cpd_dry_run +- name: Check if {{ _p_current_cp4d_cluster.project }} still exists + kubernetes.core.k8s_info: + kind: namespace + name: "{{ _p_current_cp4d_cluster.project }}" + api_version: v1 + register: _cp4d_namespace -- name: Login to the OpenShift cluster "{{ _p_current_cp4d_cluster.openshift_cluster_name }}" - include_role: - name: openshift-login - vars: - _p_openshift_cluster_name: "{{ _p_current_cp4d_cluster.openshift_cluster_name }}" - -- name: Delete Cloud Pak for Data instance {{ _p_current_cp4d_cluster.project }} and its operators, logs are in {{ status_dir }}/log/{{ _p_current_cp4d_cluster.project }}-destroy.log - shell: | - {{ playbook_dir }}/../scripts/cp4d/cp4d-delete-instance.sh {{ _p_current_cp4d_cluster.project }} | tee -a {{ status_dir }}/log/{{ _p_current_cp4d_cluster.project }}-destroy.log - environment: - CPD_CONFIRM_DELETE: "true" - CPD_DESTROY_CLUSTER_WIDE: "false" \ No newline at end of file +- include_tasks: cp4d-cluster-delete.yml + when: (_cp4d_namespace.resources | default([])) != [] \ No newline at end of file