##### SUMMARY
no_log module argument processing can change 'changed' task field, which is probably an undesirable side-effect

##### ISSUE TYPE
- Bug Report

##### COMPONENT NAME
unsure, ansible core processing task responses

##### ANSIBLE VERSION
<!--- Paste verbatim output from "ansible --version" between quotes -->
```paste below
ansible 2.10.6
ansible 2.7.7
```

##### CONFIGURATION
<!--- Paste verbatim output from "ansible-config dump --only-changed" between quotes -->
```paste below
```

##### OS / ENVIRONMENT
<!--- Provide all relevant information below, e.g. target OS versions, network device firmware, etc. -->
Debian Linux 10 Buster

##### STEPS TO REPRODUCE
<!--- Describe exactly how to reproduce the problem, using a minimal test-case -->
use simple playbook using single htpasswd module

<!--- Paste example playbooks or commands between quotes below -->
```yaml
- hosts: localhost
  tasks:
    - htpasswd:
        path: /tmp/xx
        username: a
        password: a
```

<!--- HINT: You can paste gist.github.com links for larger files -->

##### EXPECTED RESULTS
<!--- Describe what you expected to happen when running the steps above -->

* subsequent calls to `ansible-playbook playbook.yml` yields to task changed=False

OR

* general notice in ansible documentation of such behavior


##### ACTUAL RESULTS
<!--- Describe what actually happened. If possible run with extra verbosity (-vvvv) -->

* every call of the playbook results in task changed=True
* the module 'changed' return value itself it correct according to runtime debugging
* the error depends on the actual value of the `no_log` module argument
* probably, there's an undocumented side-effect in general no_log processing, where it the edge case (value 'a') is found
  in several places of the module response and replaced as requested. the issue is that replacing takes place even in task.changed field which should not be touched (imho)


<!--- Paste verbatim command output between quotes -->
```paste below
TASK [htpasswd] **************************************************************************************************************************************************************************************************
task path: /a.yml:4
...
<127.0.0.1> EXEC /bin/sh -c '/usr/bin/python3 /root/.ansible/tmp/ansible-tmp-1613725466.4347775-207888894675995/AnsiballZ_htpasswd.py && sleep 0'
...
changed: [localhost] => {
    "changed": "VALUE_SPECIFIED_IN_NO_LOG_PARAMETER",     <<<<<<<<<<<<<<<<<<<<<<<<
    "invocation": {
        "module_args": {
            "attributes": null,
            "backup": null,
            "content": null,
            "create": true,
            "crypt_scheme": "********pr_md5_crypt",
            "delimiter": null,
            "directory_mode": null,
            "follow": "VALUE_SPECIFIED_IN_NO_LOG_PARAMETER",
            "force": null,
            "group": null,
            "mode": null,
            "name": "VALUE_SPECIFIED_IN_NO_LOG_PARAMETER",
            "owner": null,
            "password": "VALUE_SPECIFIED_IN_NO_LOG_PARAMETER",
            "path": "/tmp/xx",
            "regexp": null,
            "remote_src": null,
            "selevel": null,
            "serole": null,
            "setype": null,
            "seuser": null,
            "src": null,
            "state": "present",
            "unsafe_writes": null,
            "username": "VALUE_SPECIFIED_IN_NO_LOG_PARAMETER"
        }
    },
    "msg": "******** ********lre********dy present"
}
```

module trace
```paste below
> /root/.ansible/tmp/ansible-tmp-1613724872.5574055-221454552474871/debug_dir/__main__.py(266)main()
-> module.exit_json(msg=msg, changed=changed)
(Pdb) l
261  	        else:
262  	            module.fail_json(msg="Invalid state: %s" % state)
263  	
264  	        check_file_attrs(module, changed, msg)
265  	        breakpoint()
266  ->	        module.exit_json(msg=msg, changed=changed)
267  	    except Exception as e:
268  	        module.fail_json(msg=to_native(e))
269  	
270  	
271  	if __name__ == '__main__':
(Pdb) module
<ansible.module_utils.basic.AnsibleModule object at 0x7f50d5a34c50>
(Pdb) changed
False       <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
(Pdb) msg
'a already present'
(Pdb) s
```
:kw cwd: If given, working directory to run the command inside
        :kw use_unsafe_shell: See `args` parameter.  Default False
        :kw prompt_regex: Regex string (not a compiled regex) which can be
            used to detect prompts in the stdout which would otherwise cause
            the execution to hang (especially if no input data is specified)
        :kw environ_update: dictionary to *update* environ variables with
        :kw umask: Umask to be used when running the command. Default None
        :kw encoding: Since we return native strings, on python3 we need to
            know the encoding to use to transform from bytes to text.  If you
            want to always get bytes back, use encoding=None.  The default is
            "utf-8".  This does not affect transformation of strings given as
            args.
        :kw errors: Since we return native strings, on python3 we need to
            transform stdout and stderr from bytes to text.  If the bytes are
            undecodable in the ``encoding`` specified, then use this error
            handler to deal with them.  The default is ``surrogate_or_strict``
            which means that the bytes will be decoded using the
            surrogateescape error handler if available (available on all
            python3 versions we support) otherwise a UnicodeError traceback
            will be raised.  This does not affect transformations of strings
            given as args.
        :kw expand_user_and_vars: When ``use_unsafe_shell=False`` this argument
            dictates whether ``~`` is expanded in paths and environment variables
            are expanded before running the command. When ``True`` a string such as
            ``$SHELL`` will be expanded regardless of escaping. When ``False`` and
            ``use_unsafe_shell=False`` no path or variable expansion will be done.
        :kw pass_fds: When running on Python 3 this argument
            dictates which file descriptors should be passed
            to an underlying ``Popen`` constructor. On Python 2, this will
            set ``close_fds`` to False.