Search code examples
pythonyamlpyyamlansible-vault

PyYAML error: Could not determine a constructor for the tag '!vault'


I am trying to read a YAML file that has the tag !vault in it. I get the error:

could not determine a constructor for the tag '!vault'

Upon reading a couple of blogs, I understood that I need to specify some constructors to resolve this issue, but I'm not clear on how to do it.

import yaml
from yaml.loader import SafeLoader
    
with open('test.yml' ) as stream:
    try:
        inventory_info = yaml.safe_load(stream)
    except yaml.YAMLError as exc:
        print(exc)

User = inventory_info['all']['children']['linux']['vars']['user']
key = inventory_info['all']['children']['linux']['vars']['key_file']

The YAML file I am using:

all:
  children:
    rhel:
      hosts: 172.18.144.98
    centos:
      hosts: 172.18.144.98  
    linux:
      children:
        rhel:
        centos:
      vars:
        user: "o9ansibleuser"
        key_file: "test.pem"
        ansible_password: !vault |
          $ANSIBLE_VAULT;2.1;AES256
          3234567899353936376166353

Solution

  • Either use the from_yaml utility function:

    from ansible.parsing.utils.yaml import from_yaml
    
    # inventory_info = yaml.safe_load(stream)  # Change this
    inventory_info = from_yaml(stream)         # to this
    

    Or add the constructor to yaml.SafeLoader:

    from ansible.parsing.yaml.objects import AnsibleVaultEncryptedUnicode
    
    
    def construct_vault_encrypted_unicode(loader, node):
        value = loader.construct_scalar(node)
        return AnsibleVaultEncryptedUnicode(value)
    
    
    yaml.SafeLoader.add_constructor(u'!vault', construct_vault_encrypted_unicode)
    
    
    inventory_info = yaml.safe_load(stream)