ansibleyamlansible-vault

How do I specify encrypted strings in molecule group_vars? (could not determine a constructor for the tag '!vault')


I have these encrypted strings in my role's var/main.yml file ...

---
# vars 
wiki_password: !vault |
          $ANSIBLE_VAULT;1.1;AES256
          63343237 ... omitted for brevity ...

... and everything works fine. BUT I was told that I need to not define this in the my_role/vars/main.yml file but in the groups_vars. So for my unit test I updated my molecule/defaults/molecule.yml file:

... omitted ...

provisioner:
  name: ansible
  inventory:
    group_vars:
      all:
        ... other vars ...
        web_domain: "example.com"

        wiki_password: !vault |
          $ANSIBLE_VAULT;1.1;AES256
          63343237 ... omitted for brevity ...    
          
... omitted ...

But now when I run molecule test I get this error:

yaml.constructor.ConstructorError: could not determine a constructor for the tag '!vault'
  in "<unicode string>", line 50, column 28:
            wiki_password: !vault |

Solution

  • vault is an Ansible feature, not a molecule feature. Molecule needs to load and validate its configuration file and by the time it reaches your vault string, ansible has not come into play yet.

    One way to workaround your above problem is to use the links feature in the provisioner config (see the ansible provisioner documentation). In this case the variable will only be read by the time ansible launches and not when molecule is trying to create the corresponding inventory files.

    As an example, here is a test I just made from scratch:

    molecule init role acme.so_demo -d docker
    cd so_demo
    
    mkdir -p molecule/.inventory/group_vars/
    echo -en "---\ntoto: $(ansible-vault encrypt_string --encrypt-vault-id your_id some_value)" > molecule/.inventory/group_vars/all.yml
    

    Which gives as a result in molecule/.inventory/group_vars/all.yml

    ---
    toto: !vault |
              $ANSIBLE_VAULT;1.2;AES256;your_id
              38323137303132393932623963326164643834386333626166633734653338313331303331313638
              ...
    
    ---
    dependency:
      name: galaxy
    driver:
      name: docker
    platforms:
      - name: instance
        image: quay.io/centos/centos:stream8
        pre_build_image: true
    provisioner:
      name: ansible
      inventory:
        links:
          group_vars: ../.inventory/group_vars/
    verifier:
      name: ansible
    
    ---
    - name: Debug vault var
      ansible.builtin.debug:
        var: toto
    

    You can now run the example with

    molecule converge
    

    Which gives (abridged):

    PLAY [Converge] ****************************************************************
    
    TASK [Gathering Facts] *********************************************************
    ok: [instance]
    
    TASK [Include acme.so_demo] ****************************************************
    
    TASK [acme.so_demo : Debug vault var] ******************************************
    ok: [instance] => {
        "toto": "some_value"
    }
    
    PLAY RECAP *********************************************************************
    instance                   : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0