Repository: ansible/ansible

Issue:
Always run a task with --diff
##### ISSUE TYPE
<!--- Pick one below and delete the rest: -->
 - Feature Idea

##### COMPONENT NAME
<!--- Name of the plugin/task/feature -->
task

##### ANSIBLE VERSION
<!--- Paste verbatim output from “ansible --version” between quotes below -->
```
ansible 2.2.0.0
  config file = /etc/ansible/ansible.cfg
  configured module search path = Default w/o overrides
```

##### CONFIGURATION
<!---
Mention any settings you have changed/added/removed in ansible.cfg
(or using the ANSIBLE_* environment variables).
-->

##### OS / ENVIRONMENT
<!---
Mention the OS you are running Ansible from, and the OS you are
managing, or say “N/A” for anything that is not platform-specific.
-->

##### SUMMARY
<!--- Explain the problem briefly -->
Running ansible-playbook with "--diff" adds more details to a register for a file that is templated, specifically I'm interested in ['diff']['after']
I would like to have an option to always run a specific task with --diff - so that I can use the output of the --diff without having to always run with --diff.

##### STEPS TO REPRODUCE
<!---
For bugs, show exactly how to reproduce the problem.
For new features, show how the feature would be used.
-->

<!--- Paste example playbooks or commands between quotes below -->
What I need to run to get the --diff in the variable:
```
ansible-playbook -i tests/inventory tests/test.yml -vvv -D --connection=local 
```

What I would like to run:
```
ansible-playbook -i tests/inventory tests/test.yml -vvv --connection=local 
```

<!--- You can also paste gist.github.com links for larger files -->

##### EXPECTED RESULTS
<!--- What did you expect to happen when running the steps above? -->

```
TASK [ansible-role-slurm : print reg_slurm_conf_template] **********************
[1;30mtask path: /ansible-role-slurm/tasks/common.yml:46[0m
[0;32mok: [localhost] => {
    "reg_slurm_conf_template": {
        "changed": true, 
        "checksum": "f1b303fe0833358e41f27949db4b7ae9eae665b5", 
        "dest": "/etc/slurm/slurm.conf", 
        "diff": {
            "after": "# FGCI slurm.conf\n# Example slurm.conf file. Please run configurator.html\n# (in doc/html) to build a configuration file customized\n# for your environment.\n#\n#\n# slurm.conf file generated by configurator.html.\n#\n# See the slurm.conf man page for more information.\n#\nClusterName=io\nControlMachine=2d6055600598\nSlurmUser=slurm\nSlurmctldPort=6817\nSlurmdPort=6818\nAuthType=auth/munge\nStateSaveLocation=/opt/slurmdb/tmp\nSwitchType=switch/none\nMpiDefault=none\nMpiParams=ports=12000-12999\nSlurmctldPidFile=/var/run/slurmctld.pid\nSlurmdPidFile=/var/run/slurmd.pid\nProctrackType=proctrack/cgroup\nCacheGroups=1\nFirstJobId=2230000\nReturnToService=1\nMaxJobCount=30000\nMaxArraySize=10001\nPropagateResourceLimitsExcept=MEMLOCK\nEnforcePartLimits=YES\nEpilog=/usr/local/libexec/slurm/epilog.d/*\nTaskEpilog=/usr/bin/epilog\nTaskPlugin=task/cgroup\nUsePAM=1\nRebootProgram=/sbin/reboot\nHealthCheckInterval=300\nHealthCheckProgram=/usr/sbin/nhc\nGresTypes=gpu\n\n# TIMERS\nSlurmctldTimeout=300\nSlurmdTimeout=600\nInactiveLimit=0\nMinJobAge=30\nMessageTimeout=30\nKillWait=30\nCompleteWait=12\nWaittime=0\nKillOnBadExit=1\nKeepAliveTime=60\nOverTimeLimit=60\n\n# SCHEDULING\nSchedulerType=sched/backfill\nSchedulerParameters=bf_max_job_test=300,bf_max_job_part=200,bf_max_job_user=30,defer,bf_continue,bf_window=7200,bf_resolution=1800,pack_serial_at_end\nSchedulerPort=7321\nSelectType=select/cons_res\nSelectTypeParameters=CR_Core_Memory\nFastSchedule=2\nPriorityType=priority/multifactor\nPriorityFlags=FAIR_TREE,SMALL_RELATIVE_TO_TIME,MAX_TRES\nPriorityDecayHalfLife=14-0\nPriorityFavorSmall=NO\nPriorityWeightFairshare=10000000\nPriorityWeightAge=10000\nPriorityWeightPartition=0\nPriorityWeightJobSize=10000\nPriorityWeightQOS=10000\nPriorityMaxAge=7\n\n# LOGGING\nSlurmctldDebug=3\nSlurmdDebug=3\nJobCompLoc=/var/log/slurm/slurm_jobcomp.log\nJobCompType=jobcomp/filetxt\n\n# ACCOUNTING\nJobAcctGatherType=jobacct_gather/linux\nJobAcctGatherFrequency=energy=60,task=60\nAcctGatherEnergyType=acct_gather_energy/rapl\nAcctGatherNodeFreq=60\nAccountingStorageType=accounting_storage/slurmdbd\nAccountingStorageHost=2d6055600598\nAccountingStorageLoc=slurm_acct_db\nAccountingStorageUser=slurm\nAccountingStorageEnforce=safe,qos\nAccountingStorageTRES=gres/gpu:teslak80\n\n# TOPOLOGY\n#TopologyPlugin=topology/tree\n\n# COMPUTE NODES\nNodeName=2d6055600598 RealMemory=126000 Sockets=2 CoresPerSocket=12 ThreadsPerCore=2 State=UNKNOWN\n# If slurm_with_gpu is True then add some nodes and a partition for them.\nNodeName=gpu Gres=gpu:teslak80:8 RealMemory=126000 Sockets=2 CoresPerSocket=12 ThreadsPerCore=2 State=UNKNOWN\n\n# partitions\nPartitionName=normal Nodes=2d6055600598,gpu Default=YES MaxTime=7-00:00:00 State=UP DefaultTime=2:00:00\nPartitionName=test Nodes=2d6055600598 Default=NO MaxTime=7-00:00:00 State=UP DefaultTime=2:00:00\nPartitionName=grid Nodes=2d6055600598 Default=NO MaxTime=7-00:00:00 State=UP DefaultTime=2:00:00\n\n# Slurm Extra Parameters\nTrackWCKey=no\nTreeWidth=50\n", 
            "after_header": "dynamically generated", 
            "before": ""
        }, 
        "gid": 0, 
        "group": "root", 
        "md5sum": "fdcc9f5b68ca61e9c47a568ccab5ea1a", 
        "mode": "0644", 
        "owner": "root", 
        "size": 2904, 
        "src": "/root/.ansible/tmp/ansible-tmp-1478504807.2-247995833558548/source", 
        "state": "file", 
        "uid": 0
    }
}[0m
```

##### ACTUAL RESULTS
<!--- What actually happened? If possible run with extra verbosity (-vvvv) -->

<!--- Paste verbatim command output between quotes below -->
```
TASK [ansible-role-slurm : print reg_slurm_conf_template] **********************
[1;30mtask path: /ansible-role-slurm/tasks/common.yml:46[0m
[0;32mok: [localhost] => {
    "reg_slurm_conf_template": {
        "changed": true, 
        "checksum": "5bf543fe263067447526f43977ab7d395abc61a9", 
        "dest": "/etc/slurm/slurm.conf", 
        "gid": 0, 
        "group": "root", 
        "md5sum": "4c30b7ad45fb426a101e9f1fe4bbb0df", 
        "mode": "0644", 
        "owner": "root", 
        "size": 2904, 
        "src": "/root/.ansible/tmp/ansible-tmp-1478500886.03-211443945610238/source", 
        "state": "file", 
        "uid": 0
    }
}[0m
```



Discussion:
Related to https://github.com/ansible/ansible/issues/16073


Resolving patch:
diff --git a/lib/ansible/constants.py b/lib/ansible/constants.py
--- a/lib/ansible/constants.py
+++ b/lib/ansible/constants.py
@@ -343,6 +343,7 @@ def load_config_file():
 
 # diff
 DIFF_CONTEXT = get_config(p, 'diff', 'context', 'ANSIBLE_DIFF_CONTEXT', 3, value_type='integer')
+DIFF_ALWAYS = get_config(p, 'diff', 'always', 'ANSIBLE_DIFF_ALWAYS', False, value_type='bool')
 
 # non-configurable things
 MODULE_REQUIRE_ARGS       = ['command', 'win_command', 'shell', 'win_shell', 'raw', 'script']
diff --git a/lib/ansible/playbook/play_context.py b/lib/ansible/playbook/play_context.py
--- a/lib/ansible/playbook/play_context.py
+++ b/lib/ansible/playbook/play_context.py
@@ -203,7 +203,7 @@ class PlayContext(Base):
     _force_handlers   = FieldAttribute(isa='bool', default=False)
     _start_at_task    = FieldAttribute(isa='string')
     _step             = FieldAttribute(isa='bool', default=False)
-    _diff             = FieldAttribute(isa='bool', default=False)
+    _diff             = FieldAttribute(isa='bool', default=C.DIFF_ALWAYS)
 
     def __init__(self, play=None, options=None, passwords=None, connection_lockfd=None):
 


Test patch: