Last active
March 28, 2023 20:39
-
-
Save filipenf/2cc72af47e3570afaa9d3bf2e71658c3 to your computer and use it in GitHub Desktop.
Script to convert an ansible vault into a yaml file with encrypted strings
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
#Vault password is 1 | |
echo "Converting vault to yaml format:" | |
ansible-vault decrypt --output - vault | python ./convert_vault.py > new-vault.yml | |
echo "Decrypting a variable from the converted vault" | |
ansible localhost -i localhost, -e @new-vault.yml -m debug -a 'var=secret' --ask-vault-pas |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import sys | |
import yaml | |
import argparse | |
from ansible.parsing.vault import VaultLib | |
from ansible.cli import CLI | |
from ansible import constants as C | |
from ansible.parsing.dataloader import DataLoader | |
from ansible.parsing.yaml.dumper import AnsibleDumper | |
from ansible.parsing.yaml.loader import AnsibleLoader | |
from ansible.parsing.yaml.objects import AnsibleVaultEncryptedUnicode | |
""" | |
This script reads a yaml file and dumps it back while encrypting | |
the values but keeping the keys plaintext. To convert an ansible | |
vault file format into yaml you can do: | |
ansible-vault decrypt --output - vault | \ | |
python ./convert_vault.py > new-vault | |
""" | |
def encrypt_string(decrypted_secret, vault_id=None): | |
""" | |
Encrypts string | |
""" | |
loader = DataLoader() | |
vault_secret = CLI.setup_vault_secrets( | |
loader=loader, | |
vault_ids=C.DEFAULT_VAULT_IDENTITY_LIST | |
) | |
vault = VaultLib(vault_secret) | |
return AnsibleVaultEncryptedUnicode( | |
vault.encrypt(decrypted_secret, | |
vault_id=vault_id)) | |
def encrypt_dict(d, vault_id=None): | |
for key in d: | |
value = d[key] | |
if isinstance(value, str): | |
d[key] = encrypt_string(value, vault_id) | |
elif isinstance(value, list): | |
for item in value: | |
encrypt_dict(item) | |
elif isinstance(value, dict): | |
encrypt_dict(value) | |
def main(): | |
parser = argparse.ArgumentParser() | |
parser.add_argument('--input-file', | |
help='File to read from', | |
default='-') | |
parser.add_argument('--vault-id', | |
help='Vault id used for the encryption') | |
args = parser.parse_args() | |
in_file = sys.stdin if args.input_file == '-' else open(args.input_file) | |
data = yaml.load(in_file, Loader=AnsibleLoader) | |
encrypt_dict(data, vault_id=args.vault_id) | |
print(yaml.dump(data, Dumper=AnsibleDumper)) | |
if __name__ == "__main__": | |
main() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
$ANSIBLE_VAULT;1.1;AES256 | |
32656465316437646133376138393234386439303536343631343763396661386339366431346263 | |
3036313832303437623834633363396333343338643930640a343266336434383434646530386664 | |
61623665363935373738366634613363626132613861666432396630396436306534303265303430 | |
3637306164666265380a386431363364636666626263653864613866323235366638386261353433 | |
30643765623033353435313230663933353931616530663735303437393138663738 |
Good stuff! Just what I was looking for.
@filipenf This is great, and saved me a ton of time! I'm not sure list handling is correct, so I used the following slightly modified version of encrypt_dict
.
def encrypt_dict(d, vault_id=None):
for key in d:
value = d[key]
if isinstance(value, str):
d[key] = encrypt_string(value, vault_id)
elif isinstance(value, list):
encrypted_list = []
for item in value:
encrypted_list.append(encrypt_string(item))
d[key] = encrypted_list
elif isinstance(value, dict):
encrypt_dict(value)
Thanks for this contribution. Really elegant and saved me some hours. I tweaked it a bit to support partial encryption, so I can keep the username plain but the password is still encrypted.
This was such a godsend. Thanks!
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Also note ansible/ansible#72703, this does not lookup the vault provided, just uses the default, and labels it with the vault-id provided as the label. Something very similar to the below is what I ended up using.