Skip to content

Instantly share code, notes, and snippets.

@yann2192
Last active July 20, 2022 10:58
Show Gist options
  • Save yann2192/b59310264e0728a5c6c5592f1a27863a to your computer and use it in GitHub Desktop.
Save yann2192/b59310264e0728a5c6c5592f1a27863a to your computer and use it in GitHub Desktop.
Parse YAML to decrypt ansible-vault encrypted string or encrypt standard string using ansible-vault
import subprocess
import sys
import yaml
class VaultTag(yaml.YAMLObject):
yaml_tag = "!vault"
def __init__(self, env_var):
self.env_var = env_var
def __repr__(self):
return "VaultTag({})".format(self.env_var)
@classmethod
def from_yaml(cls, loader, node):
return VaultTag(node.value)
@classmethod
def to_yaml(cls, dumper, data):
return dumper.represent_scalar(cls.yaml_tag, data.env_var, style='|')
def encrypt_string(obj):
if type(obj) is dict:
for k in obj.keys():
obj[k] = encrypt_string(obj[k])
return obj
elif type(obj) is str:
t = subprocess.check_output(['ansible-vault', 'encrypt_string', obj])
return yaml.load(t.decode(), Loader=yaml.Loader)
elif type(obj) is VaultTag:
t = subprocess.check_output(['ansible-vault', 'decrypt'], input=obj.env_var.encode())
return t.decode()
else:
raise RuntimeError("unknown type {}".format(type(obj)))
def replace(path):
try:
tmp = subprocess.check_output(['ansible-vault', 'view', path])
except:
with open(path, 'r') as f:
tmp = f.read()
data = yaml.load(tmp, Loader=yaml.Loader)
data = encrypt_string(data)
data = yaml.dump(data, Dumper=yaml.Dumper)
with open(path, 'w') as f:
f.write(data)
if __name__ == "__main__":
yaml.Loader.add_constructor('!vault', VaultTag.from_yaml)
yaml.Dumper.add_representer(VaultTag, VaultTag.to_yaml)
for i in sys.argv[1:]:
print(i)
replace(i)
@yakaviuk
Copy link

Hello @yann2192
Could you please provide an example how to run this script?
For example
bash$ python3 default.py --vault-password-file password.txt file_with_secret.yaml
or something like this.
Thanks in advance.

@yann2192
Copy link
Author

Hello,

This scripts is pretty basic.

$ python3 devault.py file.yaml

To give the password file to ansible-vault, you can use the environment variable ANSIBLE_VAULT_PASSWORD_FILE. For example :

$ export ANSIBLE_VAULT_PASSWORD_FILE=password.txt

@yakaviuk
Copy link

@yann2192 Could you help me please?
I created simple yaml:
https://gist.github.com/yakaviuk/0800d5277687f72209288fdb7668673e

$ANSIBLE_VAULT_PASSWORD_FILE is set.

I try to run:
# python3 default.py temp.yaml

but I get an error:

temp.yaml
ERROR! input is not vault encrypted datatemp.yaml is not a vault encrypted file for temp.yaml
Traceback (most recent call last):
  File "default.py", line 62, in <module>
    replace(i)
  File "default.py", line 49, in replace
    data = encrypt_string(data)
  File "default.py", line 28, in encrypt_string
    obj[k] = encrypt_string(obj[k])
  File "default.py", line 37, in encrypt_string
    raise RuntimeError("unknown type {}".format(type(obj)))
RuntimeError: unknown type <class 'float'>

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment