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

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())

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.


broferek's answer works if your entire yaml file is encrypted. if your yaml file is unencrypted but contains encrypted variables, it'll complain. This should work either way:

import:

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

then use the DataLoader class to read the file in to a dict

cfgfile = "/path/to/yaml/file.yml"
loader = DataLoader()
vault_secrets = CLI.setup_vault_secrets(loader=loader,
            vault_ids=C.DEFAULT_VAULT_IDENTITY_LIST)
loader.set_vault_secrets(vault_secrets)
data = loader.load_from_file(cfgfile)
pprint.pprint(data)

Extending Kuba's answer, ansible-vault is a wrapper around VaultLib. It nicely handles the pre Ansible 2.4 version of Vaultlib along with the post 2.4 version.

The ansible-vault load() method not only decrypts the file, but it also parses it and returns the contents as a dict. If you want the contents without parsing, it is probably easiest to just extend ansible-vault with something like:

from ansible_vault import Vault

class MyVault(Vault):
    def load_raw(self, stream):
        return self.vault.decrypt(stream)

    def dump_raw(self, text, stream=None):
        encrypted = self.vault.encrypt(text)
        if stream:
            stream.write(encrypted)
        else:
            return encrypted