1

My company uses Ansible (which I am a novice at) and we have a playbook and a related role for joining new Linux machines to AD. Our admin accounts have their passwords rolled three times a day, and we can't set them ourselves. The Ansible playbook works so long as there is not a ' (single quote) in the password. There may be other characters that cause it to break, but I know that ' does it for sure.

Here are the relevant bits of the scripts:

cat setup-ad.yml --- - hosts: "{{ hosts }}" vars_prompt: - name: "username" prompt: "Enter admin account" private: no - name: "password" prompt: "Enter Password" unsafe: yes private: yes vars: domain: "{{ 'mycompany.com' }}" passwd: "{{ password | regex_escape() }}" roles: - join-ad 
grep -B2 -A3 'passwd' ./roles/join-ad/tasks/main.yml - name: join to active directory command: net ads join MYCOMPANY.COM -U {{ username }}@MYCOMPANY.COM%'{{ passwd }}' createcomputer=Restricted/Servers/Unix --request-timeout=120 --no-dns-updates no_log: false when: ansible_distribution_major_version >= 6 - name: join to active directory command: net ads join MYCOMPANY.COM -U {{ username }}@MYCOMPANY.COM%'{{ passwd }}' createcomputer=Restricted/Servers/Unix --request-timeout=120 no_log: false when: ansible_distribution_major_version <= 5 

The error we get is:

TASK [join-ad : join to active directory] ************************************************************************ An exception occurred during task execution. To see the full traceback, use -vvv. The error was: ValueError: No closing quotation fatal: [newserver.mycompany.com]: FAILED! => {"changed": false, "module_stderr": "Shared connection to newserver.mycompany.com closed.\r\n", "module_stdout": "Traceback (most recent call last):\r\n File \"/root/.ansible/tmp/ansible-tmp-1590785720.2-224244797633747/AnsiballZ_command.py\", line 102, in <module>\r\n _ansiballz_main()\r\n File \"/root/.ansible/tmp/ansible-tmp-1590785720.2-224244797633747/AnsiballZ_command.py\", line 94, in _ansiballz_main\r\n invoke_module(zipped_mod, temp_path, ANSIBALLZ_PARAMS)\r\n File \"/root/.ansible/tmp/ansible-tmp-1590785720.2-224244797633747/AnsiballZ_command.py\", line 40, in invoke_module\r\n runpy.run_module(mod_name='ansible.modules.commands.command', init_globals=None, run_name='__main__', alter_sys=True)\r\n File \"/usr/lib64/python2.7/runpy.py\", line 176, in run_module\r\n fname, loader, pkg_name)\r\n File \"/usr/lib64/python2.7/runpy.py\", line 82, in _run_module_code\r\n mod_name, mod_fname, mod_loader, pkg_name)\r\n File \"/usr/lib64/python2.7/runpy.py\", line 72, in _run_code\r\n exec code in run_globals\r\n File \"/tmp/ansible_command_payload_4D4oFT/ansible_command_payload.zip/ansible/modules/commands/command.py\", line 344, in <module>\r\n File \"/tmp/ansible_command_payload_4D4oFT/ansible_command_payload.zip/ansible/modules/commands/command.py\", line 263, in main\r\n File \"/usr/lib64/python2.7/shlex.py\", line 279, in split\r\n return list(lex)\r\n File \"/usr/lib64/python2.7/shlex.py\", line 269, in next\r\n token = self.get_token()\r\n File \"/usr/lib64/python2.7/shlex.py\", line 96, in get_token\r\n raw = self.read_token()\r\n File \"/usr/lib64/python2.7/shlex.py\", line 172, in read_token\r\n raise ValueError, \"No closing quotation\"\r\nValueError: No closing quotation\r\n", "msg": "MODULE FAILURE\nSee stdout/stderr for the exact error", "rc": 1} PLAY RECAP ******************************************************************************************************* newserver.mycompany.com : ok=9 changed=0 unreachable=0 failed=1 skipped=2 rescued=0 ignored=0 

Okay, so the issue is that at some point the ' is being interpreted as the beginning of a quoted series of characters, rather than as simply part of the password. My problem is I don't know how to get Ansible? Python? YAML? Jinja? to treat the string of characters the user inputs as nothing more than a string of characters. Is "string literal" the correct term here?

If I ssh to the target server and run the net ads join command manually, and let it prompt for my password, it will work even with a ' in it, so at the very least I know it's not the Samba command that's the issue.

The things I've tried (which haven't helped) are:

  • Add 'hard quotes' around {{ passwd }}
  • Add unsafe: yes to the password definition
  • Add passwd: "{{ password | regex_escape() }}" to escape metacharacters
  • Lots of internet searching on Stack and Google

Any and all help would be appreciated.

1
  • @Vladimir Botka thank you! Replacing passwd: "{{ password | regex_escape() }}" with passwd: "{{ password | quote }}", and surrounding the whole command line with "'s while removing the interior ''s like you suggested solved it for me! If you add your suggestions as an answer I will mark it as the chosen solution. Commented Jun 1, 2020 at 18:03

1 Answer 1

0

This might be what you're looking for

- command: "net ads join MYCOMPANY.COM -U {{ username }}@MYCOMPANY.COM%{{ passwd|quote }} createcomputer=Restricted/Servers/Unix --request-timeout=120" 

See YAML gotcha and String filters.

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.