1

I have a requirement where I should not store any passwords in the script files in plain text. So I have created an Ansible vault file called "vault.yml" which contains username and password.

Is there some kind of API that I can use to look up this value from python script called for example "test.py"?

What I would like in test.py is something like this:

username = ansible_api_get(key=username)
password = ansible_api_get(key=password)

P.S. - I don't have to use Ansible Vault, but that is preferred option as we would like to use all sensitive info with Vault and we want to integrate our scripts as much as possible.

Daniel Mann
  • 57,011
  • 13
  • 100
  • 120
james koo
  • 43
  • 6
  • Just be aware that you need the password for the Vault at one point - you'll still have to have that somewhere... Otherwise, have you looked at this? https://github.com/tomoh1r/ansible-vault/blob/master/ansible_vault/api.py Or at the (unsupported, since internal) Ansible Python API: https://docs.ansible.com/ansible/2.7/dev_guide/developing_api.html – nwinkler Dec 04 '18 at 07:29
  • 1
    There are plenty of secrets management software (most notable Hashicorp Vault and Conjur by CyberArk) that will do this in a responsible and enterprise way. Ansible-Vault is really more for dev and experiments. – Matthew Schuchard Dec 04 '18 at 12:47

1 Answers1

0

Yes, ansible-vault is the Python library that you can use for this purpose.

vault.py

#!/usr/bin/env python3
''' get secrets from ansible-vault file with gpg-encrypted password '''
import os
import sys
from subprocess import check_output
import yaml
from ansible_vault import Vault

vault_file = sys.argv[1]
if os.path.exists(vault_file):
    get_vault_password = os.environ['ANSIBLE_VAULT_PASSWORD_FILE']
    if os.path.exists(get_vault_password):
        PASSWORD = check_output(get_vault_password).strip().decode("utf-8")
        secrets = yaml.safe_load(Vault(PASSWORD).load_raw(open(vault_file, encoding='utf-8').read()))
        print(secrets['username'])
        print(secrets['password'])
else:
    raise FileNotFoundError

As @nwinkler wisely says, you'll still have to have the password for the Ansible vault. As a developer you're probably familiar with signing your commits in Git, the good news is that you can use the same GPG keys to encrypt/decrypt the file that stores the password, and this can work transparently.

If the environment variable ANSIBLE_VAULT_PASSWORD_FILE points to an executable, then Ansible will run that executable to get to the password required to decrypt a vault file. If it's not executable, then someone can store plain-text secrets there. The executable in this example needs just one line of shell to decrypt a file named vault_pw.gpg. Create this file with the vault-password on one line and encrypt it with your GPG key, remove the plain-text file.

~/.bash_profile

I setup my shell to do this, and also launch the gpg-agent (for caching).

export ANSIBLE_VAULT_PASSWORD_FILE=~/.ansible_vault_password_exe
gpg-agent --daemon --write-env-file "${HOME}/.gpg-agent-info"'
export GPG_TTY=$(tty)

~/.bashrc

This will ensure that only one gpg-agent is running:

if [ -f "${HOME}/.gpg-agent-info" ]
then
    . "${HOME}/.gpg-agent-info"
fi

~/.ansible_vault_password_exe

#!/bin/sh
exec gpg -q -d ${HOME}/vault_pw.gpg
bbaassssiiee
  • 6,013
  • 2
  • 42
  • 55