Keeping secrets in Hashicorp Vault for Ansible

Ivan Piskunov
3 min readJun 22, 2022

Ansible has its own mechanism for storing secrets securely, but we may need to use a centralized solution. In this case, there is a solution for integrating Hashicorp Vault and Ansible. Our instructions are suitable for systems based on Deb (Ubuntu, Debian) or RPM (Rocky Linux, Red Hat, CentOS).

Configuring Hashicorp Vault

On the Hashicorp Vault side, you must create:

  1. The secret storage path for Ansible and the secret itself.
  2. Access policy for the created secret.
  3. Token for the ability to connect with a link to the created policy.

1. First, we create a secret storage path using the key-value mechanism:

vault secrets enable -path=ansible kv

* in this example, the path will start with ansible.

Creating a secret:

vault kv put ansible/projects/test-project/database \
username=my_user \
password=password135 \
host=mariadb.dmosk.local \
dbname=testdb

* in this example, a secret will be created along the path ansible/projects/test-project/database, which will contain records for connecting to the database (for example, mariadb).

Let’s see what happened:

vault kv get ansible/projects/test-project/database

The team should return something similar to this to us:

====== Data ======
Key Value
— — — — -
dbname testdb
host mariadb.dmosk.local
password password135
username my_user

* we need to get the data that we added to the secret.

2. Creating a policy:

vault policy write test-project-ansible — <<EOF
path “ansible/projects/test-project/*” {
capabilities = [ “read” ]
}
EOF

* in this example, we named the policy test-project-ansible. According to our rule, we allow reading along the ansible/projects/test-project path.

3. Creating a token for our policy:

vault token create -policy=”test-project-ansible”

We should see something like this:

Key Value
— — — — -
token s.E1jqoGhkgcMcZtbOLENSsW21
token_accessor E9TGHoaDYw1q8HPpyWZy9xkf
token_duration 768h
token_renewable true
token_policies [“default” “test-project-ansible”]
identity_policies []
policies [“default” “test-project-ansible”]

We write down the token — we will need its value later.

Configuring Ansible

Go to Ansible. Installing the python hvac module:

pip3 install hvac

Creating a playbook where we need to access Vault, for example:

vi /etc/ansible/vault-playbook.yml

— -

- hosts: test_servers
user: dmosk
become: true
become_method: su
become_user: root

vars:
vault_url: https://vault.dmosk.local:8200
vault_token: s.E1jqoGhkgcMcZtbOLENSsW21
vault_secret: ansible/projects/test-project/database
database_arr: “{{ lookup(‘hashi_vault’, ‘secret={{ vault_secret }} token={{ vault_token }} url={{ vault_url }} validate_certs=False’) }}”

tasks:
- name: Echo Vars
ansible.builtin.debug:
msg: “Database host: {{ database_arr.host }}, dbname: {{ database_arr.dbname }}, username: {{ database_arr.username }}, password: {{ database_arr.password }}”

* where:

  • vault_url-link for requests to the Vault server. This can be the server name or IP address.
  • vault_token — token to connect to. We’ll use the one we created in the first part of the instructions.
  • vault_secret — full path to the secret created in Vault.
  • database_arr-a variable in which we will write values for each of the rows of our secret.

As a result of testing this playbook, the screen should display the values of our secret. In this particular example, we will get 4 variables that we can use in Ansible scripts at our own request:

  1. database_arr.host
  2. database_arr.dbname
  3. database_arr.username
  4. database_arr.password

Note that the part after the dot corresponds to the name of the parameter in the secret.

To do this, launch our playbook:

ansible-playbook /etc/ansible/vault-playbook.yml -kK

We should get something like:

{“ data-translation=”ok: [192.168.0.15] => {“ data-ch=”0" data-type=”trSpan” style=”font-size: inherit !important;”>ok: [192.168.0.15] => {
“msg”: “Database host: mariadb.dmosk.local, dbname: testdb, username: my_user, password: password135”
}

The goal is achieved — we can read secrets from Hashicorp Vault using Ansible.

--

--

Ivan Piskunov

DevSecOps expert, Security Evangelist, Researcher, Speaker, Book’s author