Ansible Escaping in Shell Module

ansible

I was trying to configure an application to connect to ldap and noticed it was failing authentication, so I thought I would check the two commands that get executed to set this up to see what the shell command that ansible executes looks like.
So I disabled the mqsichangeproperties and mqsisetdbparms commands on the server and created the below little test playbook to see what the command string looks like… I run the playbook expecting an error of mqsisetdbparms: command not found
but this would allow me to see cmd and _raw_params keys when running with verbose output.

I noticed that the command for the first task is in the form that I expect:

"cmd": "mqsichangeproperties QM -b webadmin -o server -n ldapAuthenticationUri –v \"ldap://abc.company.com:389/OU=Users,OU=City,OU=Country,DC=company,DC=com\""

However, the command for the second task contains additional blackslashes, resulting in the incorrect username and password being set for the application…

Incorrect command form:

"cmd": "mqsisetdbparms QM -n ldap::company.com -u \"DOMAIN\\username\" -p \"pwd@pwd\""

Expected command form:

"cmd": "mqsisetdbparms QM -n ldap::company.com -u "DOMAIN\username" -p "pwd@pwd""

I feel as if have tried all possible options such as

  • using double quotes for the variables

  • escaping in the variables

  • combination of single and double quotes with the variables and the shell command string

  • Escaping the backslash in the ldap_usr variable

The test playbook I am using is below…

---
# file: test.yml
# desc: Test playbook
#
- hosts: target
  gather_facts: no
  vars:
    ldap_server: "ldap://abc.company.com"
    ldap_port: 389
    ldap_baseDN: "OU=Users,OU=City,OU=Country,DC=company,DC=com"
    ldap_usr: 'DOMAIN\username'
    ldap_pwd: 'pwd@pwd'
    ldap_auth_uri: "\"{{ldap_server}}:{{ldap_port}}/{{ldap_baseDN}}\""
  tasks:
#    - name: test setting URI
#      shell: "mqsichangeproperties QM -b webadmin -o server -n ldapAuthenticationUri -v {{ldap_auth_uri}}"
    - name: test setting user
      shell: "mqsisetdbparms QM -n ldap::company.com -u \"{{ldap_usr}}\" -p \"{{ldap_pwd}}\""

Using Ansible Version 2.2.0.0

Best Answer

Looks to me like the following should work:

ldap_usr: 'DOMAIN\\username'
shell: mqsisetdbparms QM -n ldap::company.com -u \"{{ldap_usr}}\" -p \"{{ldap_pwd}}\"

When I echo the resulting string to a file with:

shell: echo mqsisetdbparms QM -n ldap::company.com -u \"{{ldap_usr}}\" -p \"{{ldap_pwd}}\" > ./check.txt

or

shell: printf "mqsisetdbparms QM -n ldap::company.com -u \"{{ldap_usr}}\" -p \"{{ldap_pwd}}\"" > ./check.txt

I get:

mqsisetdbparms QM -n ldap::company.com -u "DOMAIN\username" -p "pwd@pwd"

which is what you requested.


By the way, you shouldn't rely on the Ansible log to determine what is the real command, as it prints escaped JSON.

Related Topic