How to escape backslash and double quote in Ansible (script module)

Don't be confused by the fact that ansible-playbook prints debug messages in JSON encoded form, so some characters are escaped.

set_fact:
  arg: \(-name "{{foo}}" \)

You have correct syntax. This will set arg to \(-name "bar" \) if foo's value is bar.
But the debug message in this case will look like this:

ok: [localhost] => {
    "arg": "\\(-name \"bar\" \\)"
}

Note that special characters for JSON (" and \) are escaped.

But there may be some issues with passing this as parameter.
If you call your script like this

script: path/somescript.sh "{{arg}}"

Parameter string will look like this "\(-name "bar" \)" which is actually 3 concatenated strings in bash: \(-name +bar+ \), so you will lose double quotes around the bar.

If you want to preserve those double quotes, use:

script: path/somescript.sh '{{arg}}'

You're very close. I think you want to set a variable, not a fact, and I would suggest you use the shell module instead of the script module. shell is more forgiving when it comes to escaping and quoting complex shell commands.

---
- hosts: localhost
  vars:
    foo: test.yml
    arg: \( -name "{{ foo }}" \)
  tasks:
    - debug: var=arg
    - shell: find . {{ arg }}
      register: find
    - debug: var=find.stdout_lines

And the output:

$ ansible-playbook test.yml 

PLAY [localhost] ***************************************************************

TASK [debug] *******************************************************************
ok: [localhost] => {
    "arg": "\\( -name \"test.yml\" \\)"
}

TASK [command] *****************************************************************
changed: [localhost]

TASK [debug] *******************************************************************
ok: [localhost] => {
    "find.stdout_lines": [
        "./test.yml"
    ]
}

PLAY RECAP *********************************************************************
localhost                  : ok=3    changed=1    unreachable=0    failed=0   

Tags:

Ansible