Molecule: [Question] Hashed password in ansible variable, in molecule.yml

Created on 9 Oct 2017  路  8Comments  路  Source: ansible-community/molecule

Issue Type

  • Bug report

Molecule and Ansible details

ansible --version

ansible 2.3.1.0
  config file = /etc/ansible/ansible.cfg
  configured module search path = Default w/o overrides
  python version = 2.7.12 (default, Nov 19 2016, 06:48:10) [GCC 5.4.0 20160609]

molecule --version

molecule, version 2.2.1
  • Molecule installation method: pip
  • Ansible installation method: pip

Desired Behaviour

Be able to put hashed password via the molecule.yml file.
For example:

provisioner:
  name: ansible
  inventory:
    host_vars:
      sftp:
        sftp_users:
          - user_name: user
            # password: user
            password: $6$8I5Cfmpr$kGZBjaQVzj7zd5bJyIx9X8gzo1G10fb7J2FF8nL8KYJflHKeraczF7SAdLs83a4QMDI4h.9jfE5T12Du7MGnz.
            uid: 5000
            gid: 5000
  options:
    D: True
  lint:
    name: ansible-lint

Actual Behaviour (Bug report only)

When I launch whatever molecule command, I get this output:

Traceback (most recent call last):
  File "/usr/local/bin/molecule", line 11, in <module>
    sys.exit(main())
  File "/usr/local/lib/python2.7/dist-packages/click/core.py", line 722, in __call__
    return self.main(*args, **kwargs)
  File "/usr/local/lib/python2.7/dist-packages/click/core.py", line 697, in main
    rv = self.invoke(ctx)
  File "/usr/local/lib/python2.7/dist-packages/click/core.py", line 1066, in invoke
    return _process_result(sub_ctx.command.invoke(sub_ctx))
  File "/usr/local/lib/python2.7/dist-packages/click/core.py", line 895, in invoke
    return ctx.invoke(self.callback, **ctx.params)
  File "/usr/local/lib/python2.7/dist-packages/click/core.py", line 535, in invoke
    return callback(*args, **kwargs)
  File "/usr/local/lib/python2.7/dist-packages/click/decorators.py", line 17, in new_func
    return f(get_current_context(), *args, **kwargs)
  File "/usr/local/lib/python2.7/dist-packages/molecule/command/login.py", line 151, in login
    base.get_configs(args, command_args), scenario_name)
  File "/usr/local/lib/python2.7/dist-packages/molecule/command/base.py", line 119, in get_configs
    ansible_args=ansible_args, ) for c in glob.glob(MOLECULE_GLOB)
  File "/usr/local/lib/python2.7/dist-packages/molecule/config.py", line 90, in __init__
    self.config = self._combine()
  File "/usr/local/lib/python2.7/dist-packages/molecule/config.py", line 248, in _combine
    interpolated_config = i.interpolate(stream.read())
  File "/usr/local/lib/python2.7/dist-packages/molecule/interpolation.py", line 61, in interpolate
    raise InvalidInterpolation(string)
molecule.interpolation.InvalidInterpolation

I tried to put the hash between quotes, but it's not working.

For information, I'm using the user module in Ansible.

EDIT: It's also not working when I comment the variable. So it seems so be related to some specific characters in the hash.

bug

Most helpful comment

That is due to the interpolation that occurs in molecule.yml.

You need to escape the $ with an additional $.

The following is generated with a molecule.yml such as:

inventory:
  host_vars:
    sftp:
      sftp_users:
        - user_name: user
          password: $$6$$8I5Cfmpr$$kGZBjaQVzj7zd5bJyIx9X8gzo1G10fb7J2FF8nL8KYJflHKeraczF7SAdLs83a4QMDI4h.9jfE5T12Du7MGnz.
[jodewey:~/git/molecule_2/test/scenarios/driver/docker] [venv] master(+11/-4)+ 卤 cat molecule/default/.molecule/host_vars/sftp
# Molecule managed

---
sftp_users:
  - password: $6$8I5Cfmpr$kGZBjaQVzj7zd5bJyIx9X8gzo1G10fb7J2FF8nL8KYJflHKeraczF7SAdLs83a4QMDI4h.9jfE5T12Du7MGnz.
    user_name: user

All 8 comments

That is due to the interpolation that occurs in molecule.yml.

You need to escape the $ with an additional $.

The following is generated with a molecule.yml such as:

inventory:
  host_vars:
    sftp:
      sftp_users:
        - user_name: user
          password: $$6$$8I5Cfmpr$$kGZBjaQVzj7zd5bJyIx9X8gzo1G10fb7J2FF8nL8KYJflHKeraczF7SAdLs83a4QMDI4h.9jfE5T12Du7MGnz.
[jodewey:~/git/molecule_2/test/scenarios/driver/docker] [venv] master(+11/-4)+ 卤 cat molecule/default/.molecule/host_vars/sftp
# Molecule managed

---
sftp_users:
  - password: $6$8I5Cfmpr$kGZBjaQVzj7zd5bJyIx9X8gzo1G10fb7J2FF8nL8KYJflHKeraczF7SAdLs83a4QMDI4h.9jfE5T12Du7MGnz.
    user_name: user

Awesome, it works like a charm !

I'll report a better message...

I've got a nicer error message when this occurs in the future.

ERROR: parsing config file '/Users/jodewey/git/molecule_2/test/scenarios/driver/docker/molecule/default/molecule.yml'.

Invalid placeholder in string: line 11, col 11
---
dependency:
  name: galaxy
driver:
  name: docker
lint:
  name: yamllint
  options:
    config-file: ../../../resources/.yamllint
platforms:
  - name: $6$8I5Cfmpr$kGZB
    image: centos:latest
provisioner:
  name: ansible
  playbooks:
    create: ../../../../../resources/playbooks/docker/create.yml
    destroy: ../../../../../resources/playbooks/docker/destroy.yml
  env:
    ANSIBLE_ROLES_PATH: ../../../../../resources/roles/
  lint:
    name: ansible-lint
scenario:
  name: default
verifier:
  name: testinfra
  lint:
    name: flake8

Yes, this is really great, and at least, the user know where the error is. Because when it's the first time you see this, and you never use the variable substitution feature, I assure you don't really know what happen, and what you did wrong :laughing:.

Also, maybe add a hint in documentation (in interpolation part), when using encrypted password. Because I was looking for encrypted and password in the website, but not for interpolation at first (maybe also because I'm not able to read correctly the error I guess, but well :sweat_smile:)
So, I didn't see this line:

If a literal dollar sign is needed in a configuration, use a double dollar sign ($$).

Maybe the fact to add in Variable Substitution part, something about encrypted password as an example could be great (because it will probably be the most used case, I guess).

For example:

If a literal dollar sign is needed in a configuration, use a double dollar sign ($$).

For example, if an encrypted password variable is needed in Ansible, double the dollar sign that way:
Original Ansible Variable: 
$6$8I5Cfmpr$kGZBjaQVzj7zd5bJyIx9X8gzo1G10fb7J2FF8nL8KYJflHKeraczF7SAdLs83a4QMDI4h.9jfE5T12Du7MGnz.

Variable in molecule.yml, with double dollars: 
$$6$$8I5Cfmpr$$kGZBjaQVzj7zd5bJyIx9X8gzo1G10fb7J2FF8nL8KYJflHKeraczF7SAdLs83a4QMDI4h.9jfE5T12Du7MGnz.

What do you think ?

It looks like as of:

molecule --version
molecule 3.0.2
   ansible==2.9.6 python==3.8

This started failing again.

For what it's worth, if you quad-escape the $ as $$$$ it stops erroring again, but I'm still trying to figure out if this results in the appropriate string or not.

Sure would be nice if there were a test to catch this sort of thing when it regresses.

This started failing again.

I can confirm this using

$ molecule --version
molecule 3.0.4
   ansible==2.9.8 python==3.7

For what it's worth, if you quad-escape the $ as $$$$ it stops erroring again, but I'm still trying to figure out if this results in the appropriate string or not.

Unfortunately, this does not result in a usable string as the four dollar signs result in two dollar signs.

Here is a workaround:

password_hash: "{{ lookup('file', 'myuserpassword_hash') }}"
Was this page helpful?
0 / 5 - 0 ratings

Related issues

mielas picture mielas  路  5Comments

decentral1se picture decentral1se  路  3Comments

brucellino picture brucellino  路  4Comments

ssbarnea picture ssbarnea  路  4Comments

surfer190 picture surfer190  路  3Comments