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: yesto 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.
passwd: "{{ password | regex_escape() }}"withpasswd: "{{ 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.