How to use Ansible with the Hashicorp Vault secret manager?

Hashicorp Vault is a secret storage solution for storing and managing secrets, such as passwords, tokens, certificates, and keys. In this post, we will go through how to use Ansible with Hashicorp Vault to retrieve secrets and use them in our Ansible playbooks.

This article does not cover the setup and usage of Hashicorp Vault, it is purely about using Ansible to look up information in a Vault secret store.

There are two main ways to use Ansible with Hashicorp Vault: using the community.hashi_vault.hashi_vault lookup plugin or using the Hashi_Vault collection’s vault_read module .

Let’s take a look at both methods!

Using the community.hashi_vault.hashi_vault lookup plugin

The hashi_vault lookup plugin allows us to query secrets from Hashicorp Vault using the lookup() function in our Ansible templates. To use this plugin, we need to install the hvac Python library on the Ansible control node:

pip install hvac

We need to set some environment variables to authenticate with Vault:

export VAULT_ADDR="http://127.0.0.1:8200"
export VAULT_TOKEN="s.xxxxxxxx"

Alternatively, we can pass these parameters as part of the lookup query.

The syntax of the lookup query is the following:

lookup('community.hashi_vault.hashi_vault', 'secret=secret/data/ansible:user')

For example, to retrieve the username and password of an ansible user from a Vault kv2 secret store, we can use the following method.

The structure of our data in the Vault is the following:

$ vault kv get -mount=secret ansible
=== Secret Path ===
secret/data/ansible

======= Metadata =======
Key                Value
---                -----
created_time       2023-03-31T11:16:12.898814501Z
custom_metadata    <nil>
deletion_time      n/a
destroyed          false
version            3

==== Data ====
Key     Value
---     -----
pw      verysecret
user    tmolnar

So we can create an Ansible template using this Vault data:

$ cat lookup.j2
Hello!

The ansible user is {{ lookup('community.hashi_vault.hashi_vault', 'secret=secret/data/ansible:user') }}.
The password of the user is {{ lookup('community.hashi_vault.hashi_vault', 'secret=secret/data/ansible:pw') }}.

Cheers,
The Test

Now we can use it in a playbook:

$ cat play-vault-test.yml
---
- name: Play test
  hosts: all

  tasks:
    - name: Test the hashi_vault lookup plugin with a template
      ansible.builtin.template:
        src: lookup.j2
        dest: lookup.txt
        owner: tmolnar
        group: tmolnar
        mode: u=rw,g=r,o=r

For more information on how to use the hashi_vault lookup plugin, see https://docs.ansible.com/ansible/latest/collections/community/hashivault/hashi_vault_lookup.html.

Using the vault_read module

The community.hashi_vault collection provides a set of Ansible modules that can be used to interact with Hashicorp Vault. To use this collection, we need to install it on the Ansible control node:

ansible-galaxy collection install community.hashi_vault

We also need to install the hvac and requests Python libraries on the Ansible control node.

The hvac module must be installed on the Hashicorp Vault server too!

pip install hvac requests

We can then use the modules in our Ansible playbooks by specifying the fully qualified collection name (FQCN):

---
- name: Play test 2
  hosts: all

  tasks:
    - name: Reading data with community.hashi_vault.vault_read
      community.hashi_vault.vault_read:
        url: http://127.0.0.1:8200
        path: secret/data/ansible
      register: secret_data

    - name: Echo the secret_data
      ansible.builtin.debug:
        msg: "{{ secret_data }}"

We will get the contents of the secret store and registered in the secret_data variable:

TASK [Echo the secret_data] ******************************************************************************************************************************************************************************************************************************
ok: [127.0.0.1] => {
    "msg": {
        "changed": false,
        "data": {
            "auth": null,
            "data": {
                "data": {
                    "pw": "verysecret",
                    "user": "tmolnar"
                },
                "metadata": {
                    "created_time": "2023-03-31T11:16:12.898814501Z",
                    "custom_metadata": null,
                    "deletion_time": "",
                    "destroyed": false,
                    "version": 3
                }
            },
            "lease_duration": 0,
            "lease_id": "",
            "renewable": false,
            "request_id": "5ab92cde-17eb-0737-d2f0-e8749cc95116",
            "warnings": null,
            "wrap_info": null
        },
        "failed": false
    }
}

The community.hashivault.hashivault_read module reads secrets from Vault and returns it as a result. We can then use the register keyword to store the result in a variable and use it in subsequent tasks.

For more information, see https://docs.ansible.com/ansible/latest/collections/community/hashi_vault/vault_read_module.html#ansible-collections-community-hashi-vault-vault-read-module.

Leave a comment