In this post, I want to leave here an example of how to get a secret from Hashicorp Vault, from an Ansible playbook.
The example is very simple, I will use the Vault already created here in another post, I will use Approle authentication for the example and retrieve a secret that I have been using in the examples. https://devops-db.com/vault-authentication-methods/
The full code is at: https://github.com/faustobranco/devops-db/tree/master/knowledge-base/ansible/vault
An important point, this Ansible plugin uses the hvac module for python, so first of all, you need to install it on your ansible server.
pip3 install hvac
Regardless of the other files you will find in the repository, the important ones are the main tasks, which I show below.
- name: Read the latest version of a kv2 secret from Vault via the remote host with userpass auth
community.hashi_vault.vault_kv2_get:
url: 'https://vault.devops-db.internal:8200/'
validate_certs: false
path: 'infrastructure/jenkins/test-secret01'
auth_method: 'approle'
role_id: '{{ vault_role_id }}'
secret_id: '{{ vault_secret_id }}'
register: vault_response
- name: Display the results
ansible.builtin.debug:
msg:
- "Secret: {{ vault_response.secret }}"
- "Data: {{ vault_response.data }} (contains secret data & metadata in kv2)"
- "Metadata: {{ vault_response.metadata }}"
- "Full vault_response: {{ vault_response.raw }}"
- "Value of key 'pwd' in the secret: {{ vault_response.secret.pwd }}"
- "Value of key 'username' in the secret: {{ vault_response.secret.username }}"
Then it is passed as a parameter, the Vault url, we have the validate_certs configuration because our certificate is self-signed, the authentication type, role_id and secret_id (which are both in the global variables file).
The path indicates where the secret you want to get is, in our case: secrets/infrastructure/jenkins/test-secret01, in the parameter, you don’t need the root “secrets”.
Just below in “Display the results”, I show an example of how to return variables.
I run the playbook and the result.
ansible-playbook -i /work/vault/hosts /work/vault/get_creds.yaml --extra-vars='cluster_group=jenkins_Hosts' --vault-id prod@/root/.vault_password.sec
PLAY [jenkins_Hosts] ***************************************************************************************************************************************************************************************************************************
TASK [Gathering Facts] *************************************************************************************************************************************************************************************************************************
[WARNING]: Platform linux on host srv-infrastructure-jenkins-master-01 is using the discovered Python interpreter at /usr/bin/python3.10, but future installation of another Python interpreter could change the meaning of that path. See
https://docs.ansible.com/ansible-core/2.17/reference_appendices/interpreter_discovery.html for more information.
ok: [srv-infrastructure-jenkins-master-01]
TASK [get_credentials : Read the latest version of a kv2 secret from Vault via the remote host with userpass auth] *****************************************************************************************************************************
ok: [srv-infrastructure-jenkins-master-01]
TASK [get_credentials : Display the results] ***************************************************************************************************************************************************************************************************
ok: [srv-infrastructure-jenkins-master-01] => {
"msg": [
"Secret: {'pwd': '1234qwer', 'username': 'usr-test01'}",
"Data: {'data': {'pwd': '1234qwer', 'username': 'usr-test01'}, 'metadata': {'created_time': '2025-02-06T15:25:13.602525363Z', 'custom_metadata': None, 'deletion_time': '', 'destroyed': False, 'version': 1}} (contains secret data & metadata in kv2)",
"Metadata: {'created_time': '2025-02-06T15:25:13.602525363Z', 'custom_metadata': None, 'deletion_time': '', 'destroyed': False, 'version': 1}",
"Full vault_response: {'request_id': 'c74c4942-aeca-d477-9faa-3018cefed509', 'lease_id': '', 'renewable': False, 'lease_duration': 0, 'data': {'data': {'pwd': '1234qwer', 'username': 'usr-test01'}, 'metadata': {'created_time': '2025-02-06T15:25:13.602525363Z', 'custom_metadata': None, 'deletion_time': '', 'destroyed': False, 'version': 1}}, 'wrap_info': None, 'warnings': None, 'auth': None, 'mount_type': 'kv'}",
"Value of key 'pwd' in the secret: 1234qwer",
"Value of key 'username' in the secret: usr-test01"
]
}
PLAY RECAP *************************************************************************************************************************************************************************************************************************************
srv-infrastructure-jenkins-master-01 : ok=3 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0