Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to view/decrypt Ansible vault credentials files from within a Python script?

I'm trying to figure out how to provide the following facilities to a Python script so that it can:

  1. Import Ansible Python modules
  2. Open up my defined ansible.cfg and read vault_password_file variable
  3. Read vault_password_file and temporarily store in a Python variable
  4. Decrypt a referenced Ansible vaulted file

I found this code via google but it did not appear to work when I tried it:

import ansible.utils

bar = dict()

bar = ansible.utils._load_vars_from_path("secrets.yml", results=bar, vault_password="password")

print bar

Throws this error:

$ python ansible-vault-ex.py
Traceback (most recent call last):
  File "ansible-vault-ex.py", line 5, in <module>
    bar = ansible.utils._load_vars_from_path("credentials.vault", results=bar, vault_password="password")
AttributeError: 'module' object has no attribute '_load_vars_from_path'

When I investigated this I saw no indications of this function in any Ansible related files, leading me to believe that this method no longer worked with some newer version(s) of Ansible.

Bottom line is that I'd like some method for importing Ansible libraries/modules from a Python script, so that I can interact with ansible-vault managed files programmatically from Python.

like image 405
slm Avatar asked May 23 '17 18:05

slm


2 Answers

Consider using the the ansible-vault package

Install it by:

$ pip install ansible-vault

and then it is as simple as:

from ansible_vault import Vault

vault = Vault('password')
print vault.load(open('/path/to/your/vault.yml').read())

To use the ansible code directly look at the source of that package. The simplest would be:

Ansible <= 2.3

from ansible.parsing.vault import VaultLib

vault = VaultLib('password')
print(vault.decrypt(open('/path/to/vault.yml').read()))

Ansible >= 2.4

from ansible.constants import DEFAULT_VAULT_ID_MATCH
from ansible.parsing.vault import VaultLib, VaultSecret

vault = VaultLib([(DEFAULT_VAULT_ID_MATCH, VaultSecret('password'.encode()))])
print(vault.decrypt(open('/path/to/vault.yml').read()))

The amount of source code is equal but the package provides automatic yaml parsing + handling of both Ansible versions.

like image 141
Kuba Avatar answered Sep 20 '22 11:09

Kuba


If you have configured a vault_password_file in ansible.cfg, you can pass the password to VaultLib as followed

Import :

from ansible import constants as C
from ansible.parsing.vault import VaultLib
from ansible.cli import CLI
from ansible.parsing.dataloader import DataLoader

And then, you can call :

loader = DataLoader()
vault_secret = CLI.setup_vault_secrets(
    loader=loader,
    vault_ids=C.DEFAULT_VAULT_IDENTITY_LIST
)
vault = VaultLib(vault_secret)
vault.decrypt(open('/path/to/vault.yml').read())
like image 21
broferek Avatar answered Sep 22 '22 11:09

broferek