Using Hashicorp Vault with Ansible
I found my self storing credentials for applications I was deploying with Ansible. I then ran into Handling secrets in your Ansible playbooks which gave a lot of different approaches and I wanted to give it a shot.
Setting up Vault
My previous post describes how you can deploy Vault really quick on Kubernetes. There is also a cloud offering from Hashicorp and they have a trial. After it’s deployed we can login and configure it:
> kubectl exec -it vault-0 -- /bin/ash
/ $ vault status
Key Value
--- -----
Seal Type shamir
Initialized true
Sealed false
Total Shares 5
Threshold 3
Version 1.9.2
Storage Type file
Cluster Name vault-cluster-9ff92283
Cluster ID 93572f29-2xxxxx
HA Enabled false
If you would like, you can also connect remotely. First install the cli, in my case I was using Fedora (From Install Vault):
> sudo dnf install -y dnf-plugins-core
> sudo dnf config-manager --add-repo https://rpm.releases.hashicorp.com/fedora/hashicorp.repo
> sudo dnf -y install vault
Then we configure the creds and url:
export VAULT_ADDR="http://vault.kar.int:8200"
export VAULT_TOKEN="s.7z1Vxxxxx"
vault status
Configuring Token for Ansible
Now we can create a token for ansible.
Change Default max_lease_ttl
I wanted to create a token that was valid for a year and we could refresh every 30 days (There are a lot of different tokens you can create and they are all covered in the Tokens page). By default the maximum TTL for a token is 32 days:
~ $ vault read sys/auth/token/tune
Key Value
--- -----
default_lease_ttl 768h
description token based credentials
force_no_cache false
max_lease_ttl 768h
token_type default-service
So let’s go ahead and increase that:
~ $ vault write sys/auth/token/tune max_lease_ttl=8760h
Success! Data written to: sys/auth/token/tune
Enable kv-v2 Secrets Engine and Create a secret
Now let’s enable the kv-v2 secret engine:
~ $ vault secrets enable -path=apps kv-v2
Success! Enabled the kv-v2 secrets engine at: apps/
Now let’s put some creds in there:
~ $ vault kv put apps/my-app username="user"
~ $ vault kv patch apps/my-app password="password"
You can then see both values:
~ $ vault kv get apps/my-app
======= Metadata =======
Key Value
--- -----
created_time 2021-12-24T19:44:38.586835116Z
custom_metadata <nil>
deletion_time n/a
destroyed false
version 3
====== Data ======
Key Value
--- -----
username user
password password
Or you can get one field at a time:
~ $ vault kv get -field=username apps/my-app
user
~ $ vault kv get -field=password apps/my-app
password
Create a Policy
Now let’s create a policy to allow to read the secret:
~ $ cat app-policy.hcl
path "apps/*" {
capabilities = ["read"]
}
Now let’s apply it:
~ $ vault policy write app-reader app-policy.hcl
Success! Uploaded policy: app-reader
Create a Token and attach to a Policy
Now let’s create a token and make sure it’s attached to the above policy:
~ $ vault token create -display-name app-reader -explicit-max-ttl 8760h -policy app-reader -ttl 720h -renewable
Key Value
--- -----
token s.7z1Vxxx
token_accessor RJb1xxx
token_duration 720h
token_renewable true
token_policies ["app-reader" "default"]
identity_policies []
policies ["app-reader" "default"]
You can also confirm you can read the secret:
~ $ vault token capabilities s.7z1xxxx apps/my-app
read
Get Secret from Vault with Ansible
Reading over the new documentation from Ansible, I ended up with the following line to get the secret:
"{{ lookup('hashi_vault', 'secret=apps/data/my-app token=s.7z1Vxxx url=https://vault.kar.int')['data']['username'] }}"
And it actually worked out :) I needed to install a python module but other than that it was good to go:
pip3 install hvac --user