Repository: ansible/ansible

Issue:
Allow variable module arguments 
<!---
Verify first that your issue/request is not already reported on GitHub.
THIS FORM WILL BE READ BY A MACHINE, COMPLETE ALL SECTIONS AS DESCRIBED.
Also test if the latest release, and devel branch are affected too.
ALWAYS add information AFTER (OUTSIDE) these html comments.
Otherwise it may end up being automatically closed by our bot. -->



##### SUMMARY
<!--- Explain the problem briefly -->
Do not deprecate the feature to allow module arguments to come from variables. My proposal is to keep the warning, or even disable the feature, but at least keep it as a configuration option (e.g. ANSIBLE_ALLOW_MODULE_TEMPLATES)

Apart from the possible security issue regarding compromised facts, it is up the the playbook developer to use the correct arguments. That said, this feature simplifies a lot code examples like the ones below.

Discussion:

Refering to
https://groups.google.com/forum/#!topic/ansible-project/Qrq76VLIqKg



##### ISSUE TYPE
 - Feature Idea

##### COMPONENT NAME
<!--- Insert, BELOW THIS COMMENT, the name of the module, plugin, task or feature.
Do not include extra details here, e.g. "vyos_command" not "the network module vyos_command" or the full path-->
Core

##### ANSIBLE VERSION
<!--- Paste, BELOW THIS COMMENT, verbatim output from "ansible --version" between quotes below -->
```
ansible 2.5.5
  config file = /etc/ansible/ansible.cfg
  configured module search path = [u'/home/vgouv/.ansible/plugins/modules', u'/usr/share/ansible/plugins/modules']
  ansible python module location = /usr/lib/python2.7/dist-packages/ansible
  executable location = /usr/bin/ansible
  python version = 2.7.14 (default, Sep 23 2017, 22:06:14) [GCC 7.2.0]

```

##### CONFIGURATION
<!--- If using Ansible 2.4 or above, paste, BELOW THIS COMMENT, the results of "ansible-config dump --only-changed"
Otherwise, mention any settings you have changed/added/removed in ansible.cfg
(or using the ANSIBLE_* environment variables).-->

##### OS / ENVIRONMENT
<!--- Mention, BELOW THIS COMMENT, the OS you are running Ansible from, and the OS you are
managing, or say "N/A" for anything that is not platform-specific.
Also mention the specific version of what you are trying to control,
e.g. if this is a network bug the version of firmware on the network device.-->

##### STEPS TO REPRODUCE
<!--- For bugs, show exactly how to reproduce the problem, using a minimal test-case.
For new features, show how the feature would be used. -->

<!--- Paste example playbooks or commands between quotes below -->
```yaml

---

- name: Test
  hosts: all
  vars:
    link_list:
      - src: /etc/hosts
        dest: /tmp/2
        state: link
      - src: /etc/fstab
        dest: /tmp/1
        state: link
      - src: /etc/hostname
        dest: /tmp/3
        state: link
      - src: /etc/resolv.conf
        dest: /tmp/4
        state: link
  tasks:
    - file:
      args: "{{ item }}"
      with_items: "{{ link_list }}"

```


OR 

```yaml
  - name: change some lines 
    lineinfile: "{{ { 'path': '/etc/rsyslog.conf'} | combine(item) }}"
    vars: 
      xtra_args:
        path: "/etc/rsyslog.conf"
        backup: true
    loop:
    - { line: '# exclude something', insertbefore: '^\*\.\*;auth,authpriv\.none' }
...
```

Compare this to the current solution
```yaml
  - name: change some lines 
    lineinfile:
      line: "{{ item.line }}"
      regexp: "{{ item.regexp|default(omit) }}"
      backrefs: "{{ item.backrefs|default(omit) }}"
      insertbefore: "{{ item.insertbefore|default(omit) }}"
      insertafter: "{{ item.insertafter|default(omit) }}"
      state: "{{ item.state|default(omit) }}"
      path: "/etc/rsyslog.conf"
      backup: true
    loop:
    - { line: '# exclude something', insertbefore: '^\*\.\*;auth,authpriv\.none' }
 ...
```

<!--- You can also paste gist.github.com links for larger files -->

##### EXPECTED RESULTS
<!--- What did you expect to happen when running the steps above? -->

##### ACTUAL RESULTS
<!--- What actually happened? If possible run with extra verbosity (-vvvv) -->

<!--- Paste verbatim command output between quotes below -->
```
[DEPRECATION WARNING]: Using variables for task params is unsafe, especially if the variables come from an external source like 
facts. This feature will be removed in version 2.6. Deprecation warnings can be disabled by setting deprecation_warnings=False in 
ansible.cfg.

```



Discussion:
Unfortunately the feature is on the verge of removal (#41804). I was fighting for it to remain (#41295) but unfortunately it must be removed because of the security implications it has. I don't think that even make it optional is an acceptable solution.
I'm going to close this as a duplicate of https://github.com/ansible/ansible/pull/41295

Resolving patch:
diff --git a/lib/ansible/executor/task_executor.py b/lib/ansible/executor/task_executor.py
--- a/lib/ansible/executor/task_executor.py
+++ b/lib/ansible/executor/task_executor.py
@@ -518,7 +518,11 @@ def _execute(self, variables=None):
         if '_variable_params' in self._task.args:
             variable_params = self._task.args.pop('_variable_params')
             if isinstance(variable_params, dict):
-                raise AnsibleError("Using a variable for a task's 'args' is not allowed as it is unsafe, facts can come from untrusted sources.")
+                if C.INJECT_FACTS_AS_VARS:
+                    display.warning("Using a variable for a task's 'args' is unsafe in some situations "
+                                    "(see https://docs.ansible.com/ansible/devel/reference_appendices/faq.html#argsplat-unsafe)")
+                variable_params.update(self._task.args)
+                self._task.args = variable_params
 
         # get the connection and the handler for this execution
         if (not self._connection or


Test patch: