Repository: ansible-collections/community.general

Issue:
ini_file: inconsistent handling of 'value' with empty string and 'allow_no_value' set to false
### Summary

When adding an option with `value` set to the empty string in a non-existing section and `allow_no_value` is set to `false`, the section gets added at the bottom and the option is added as `option = `, whereas on the other hand when adding an option with `value` set to the empty string to already existing section and `allow_no_value` is set to `false` the option is not added.

That's inconsistent.

### Issue Type

Bug Report

### Component Name

ini_file

### Ansible Version

```console (paste below)
ansible 2.9.23
  config file = /etc/ansible/ansible.cfg
  configured module search path = ['/home/daniel/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /usr/lib/python3.9/site-packages/ansible
  executable location = /usr/bin/ansible
  python version = 3.9.6 (default, Jul 16 2021, 00:00:00) [GCC 11.1.1 20210531 (Red Hat 11.1.1-3)]

```


### Configuration

```console (paste below)
NO OUTPUT

```


### OS / Environment

Fedora 34

### Steps to Reproduce

<!--- Paste example playbooks or commands between quotes below -->
```yaml (paste below)
---
- hosts: localhost
  tasks:
    - name: create temporary directory
      tempfile:
        state: directory
        suffix: .test
      register: remote_tmp_dir

    - name: record temporary directory
      set_fact:
        remote_tmp_dir: "{{ remote_tmp_dir.path }}"

    - name: record the output directory
      set_fact: output_file={{ remote_tmp_dir }}/foo.ini

    - name: Test with empty string in non-existing section
      community.general.ini_file:
        path: "{{ output_file }}"
        section: section1
        option: var1
        value: ""

    - name: read content from output file
      slurp:
        src: "{{ output_file }}"
      register: output_content

    - name: set expected content and get current ini file content
      set_fact:
        expected: |+
          
          [section1]
          var1 = 
        content: "{{ output_content.content | b64decode }}"

    - debug: var=expected
    - debug: var=content

    - name: copy ini file
      copy:
        content: |+
          [section1]
          var1 = 
          var2=bbb
          var4 = 0
          [section2]
          var3=ccc

        dest: "{{ output_file }}"

    - name: Test with empty string in existing section 
      community.general.ini_file:
        path: "{{ output_file }}"
        section: section1
        option: var5
        value: ""

    - name: read content from output file
      slurp:
        src: "{{ output_file }}"
      register: output_content

    - name: set expected content and get current ini file content
      set_fact:
        expected: |+
          [section1]
          var1 = 
          var2=bbb
          var4 = 0
          var5 = 
          [section2]
          var3=ccc

        content: "{{ output_content.content | b64decode }}"


    - debug: var=expected
    - debug: var=content
  
```


### Expected Results

I expect that adding an option with `value` set to the empty string and `allow_no_value` set to `false` should gain similar results no matter if the given section already exists or not.

### Actual Results



```console (paste below)
ansible-playbook 2.9.23
  config file = /etc/ansible/ansible.cfg
  configured module search path = ['/home/daniel/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /usr/lib/python3.9/site-packages/ansible
  executable location = /usr/bin/ansible-playbook
  python version = 3.9.6 (default, Jul 16 2021, 00:00:00) [GCC 11.1.1 20210531 (Red Hat 11.1.1-3)]
Using /etc/ansible/ansible.cfg as config file
setting up inventory plugins
host_list declined parsing /etc/ansible/hosts as it did not pass its verify_file() method
script declined parsing /etc/ansible/hosts as it did not pass its verify_file() method
auto declined parsing /etc/ansible/hosts as it did not pass its verify_file() method
Parsed /etc/ansible/hosts inventory source with ini plugin
[WARNING]: provided hosts list is empty, only localhost is available. Note that the implicit localhost does not match 'all'
Loading callback plugin default of type stdout, v2.0 from /usr/lib/python3.9/site-packages/ansible/plugins/callback/default.py
Attempting to use 'actionable' callback.
Skipping callback 'actionable', as we already have a stdout callback.
Attempting to use 'aws_resource_actions' callback.
Attempting to use 'cgroup_memory_recap' callback.
Attempting to use 'cgroup_perf_recap' callback.
Attempting to use 'context_demo' callback.
Attempting to use 'counter_enabled' callback.
Skipping callback 'counter_enabled', as we already have a stdout callback.
Attempting to use 'debug' callback.
Skipping callback 'debug', as we already have a stdout callback.
Attempting to use 'dense' callback.
Skipping callback 'dense', as we already have a stdout callback.
Attempting to use 'dense' callback.
Skipping callback 'dense', as we already have a stdout callback.
Attempting to use 'foreman' callback.
Attempting to use 'full_skip' callback.
Skipping callback 'full_skip', as we already have a stdout callback.
Attempting to use 'grafana_annotations' callback.
Attempting to use 'hipchat' callback.
Attempting to use 'jabber' callback.
Attempting to use 'json' callback.
Skipping callback 'json', as we already have a stdout callback.
Attempting to use 'junit' callback.
Attempting to use 'log_plays' callback.
Attempting to use 'logdna' callback.
Attempting to use 'logentries' callback.
Attempting to use 'logstash' callback.
Attempting to use 'mail' callback.
Attempting to use 'minimal' callback.
Skipping callback 'minimal', as we already have a stdout callback.
Attempting to use 'nrdp' callback.
Attempting to use 'null' callback.
Skipping callback 'null', as we already have a stdout callback.
Attempting to use 'oneline' callback.
Skipping callback 'oneline', as we already have a stdout callback.
Attempting to use 'osx_say' callback.
Attempting to use 'profile_roles' callback.
Attempting to use 'profile_tasks' callback.
Attempting to use 'say' callback.
Attempting to use 'selective' callback.
Skipping callback 'selective', as we already have a stdout callback.
Attempting to use 'skippy' callback.
Skipping callback 'skippy', as we already have a stdout callback.
Attempting to use 'slack' callback.
Attempting to use 'splunk' callback.
Attempting to use 'stderr' callback.
Skipping callback 'stderr', as we already have a stdout callback.
Attempting to use 'sumologic' callback.
Attempting to use 'syslog_json' callback.
Attempting to use 'timer' callback.
Attempting to use 'tree' callback.
Attempting to use 'unixy' callback.
Skipping callback 'unixy', as we already have a stdout callback.
Attempting to use 'yaml' callback.
Skipping callback 'yaml', as we already have a stdout callback.

PLAYBOOK: ini_file-issue.yml *********************************************************************************************************************************************************************************************************************************************************************************************************************************************************************
Positional arguments: ini_file-issue.yml
verbosity: 5
connection: smart
timeout: 10
become_method: sudo
tags: ('all',)
inventory: ('/etc/ansible/hosts',)
forks: 5
1 plays in ini_file-issue.yml

PLAY [localhost] *********************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************

TASK [Gathering Facts] ***************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************
task path: /home/daniel/Development/github/ansible_collections/community/general/ini_file-issue.yml:2
<127.0.0.1> ESTABLISH LOCAL CONNECTION FOR USER: daniel
<127.0.0.1> EXEC /bin/sh -c 'echo ~daniel && sleep 0'
<127.0.0.1> EXEC /bin/sh -c '( umask 77 && mkdir -p "` echo /home/daniel/.ansible/tmp `"&& mkdir "` echo /home/daniel/.ansible/tmp/ansible-tmp-1626687779.0045197-1079272-70130803665671 `" && echo ansible-tmp-1626687779.0045197-1079272-70130803665671="` echo /home/daniel/.ansible/tmp/ansible-tmp-1626687779.0045197-1079272-70130803665671 `" ) && sleep 0'
Using module_utils file /usr/lib/python3.9/site-packages/ansible/module_utils/facts/__init__.py
Using module_utils file /usr/lib/python3.9/site-packages/ansible/module_utils/basic.py
Using module_utils file /usr/lib/python3.9/site-packages/ansible/module_utils/facts/default_collectors.py
Using module_utils file /usr/lib/python3.9/site-packages/ansible/module_utils/facts/ansible_collector.py
Using module_utils file /usr/lib/python3.9/site-packages/ansible/module_utils/facts/namespace.py
Using module_utils file /usr/lib/python3.9/site-packages/ansible/module_utils/facts/compat.py
Using module_utils file /usr/lib/python3.9/site-packages/ansible/module_utils/parsing/convert_bool.py
Using module_utils file /usr/lib/python3.9/site-packages/ansible/module_utils/common/_collections_compat.py
Using module_utils file /usr/lib/python3.9/site-packages/ansible/module_utils/common/process.py
Using module_utils file /usr/lib/python3.9/site-packages/ansible/module_utils/six/__init__.py
Using module_utils file /usr/lib/python3.9/site-packages/ansible/module_utils/compat/__init__.py
Using module_utils file /usr/lib/python3.9/site-packages/ansible/module_utils/common/_utils.py
Using module_utils file /usr/lib/python3.9/site-packages/ansible/module_utils/common/text/converters.py
Using module_utils file /usr/lib/python3.9/site-packages/ansible/module_utils/common/_json_compat.py
Using module_utils file /usr/lib/python3.9/site-packages/ansible/module_utils/parsing/__init__.py
Using module_utils file /usr/lib/python3.9/site-packages/ansible/module_utils/compat/selectors.py
Using module_utils file /usr/lib/python3.9/site-packages/ansible/module_utils/common/text/formatters.py
Using module_utils file /usr/lib/python3.9/site-packages/ansible/module_utils/common/validation.py
Using module_utils file /usr/lib/python3.9/site-packages/ansible/module_utils/common/text/__init__.py
Using module_utils file /usr/lib/python3.9/site-packages/ansible/module_utils/common/file.py
Using module_utils file /usr/lib/python3.9/site-packages/ansible/module_utils/pycompat24.py
Using module_utils file /usr/lib/python3.9/site-packages/ansible/module_utils/common/parameters.py
Using module_utils file /usr/lib/python3.9/site-packages/ansible/module_utils/_text.py
Using module_utils file /usr/lib/python3.9/site-packages/ansible/module_utils/common/__init__.py
Using module_utils file /usr/lib/python3.9/site-packages/ansible/module_utils/common/sys_info.py
Using module_utils file /usr/lib/python3.9/site-packages/ansible/module_utils/compat/_selectors2.py
Using module_utils file /usr/lib/python3.9/site-packages/ansible/module_utils/common/collections.py
Using module_utils file /usr/lib/python3.9/site-packages/ansible/module_utils/distro/__init__.py
Using module_utils file /usr/lib/python3.9/site-packages/ansible/module_utils/distro/_distro.py
Using module_utils file /usr/lib/python3.9/site-packages/ansible/module_utils/facts/hardware/linux.py
Using module_utils file /usr/lib/python3.9/site-packages/ansible/module_utils/facts/network/darwin.py
Using module_utils file /usr/lib/python3.9/site-packages/ansible/module_utils/facts/hardware/__init__.py
Using module_utils file /usr/lib/python3.9/site-packages/ansible/module_utils/facts/virtual/base.py
Using module_utils file /usr/lib/python3.9/site-packages/ansible/module_utils/facts/system/service_mgr.py
Using module_utils file /usr/lib/python3.9/site-packages/ansible/module_utils/facts/virtual/sunos.py
Using module_utils file /usr/lib/python3.9/site-packages/ansible/module_utils/facts/network/iscsi.py
Using module_utils file /usr/lib/python3.9/site-packages/ansible/module_utils/facts/system/dns.py
Using module_utils file /usr/lib/python3.9/site-packages/ansible/module_utils/facts/hardware/base.py
Using module_utils file /usr/lib/python3.9/site-packages/ansible/module_utils/facts/network/dragonfly.py
Using module_utils file /usr/lib/python3.9/site-packages/ansible/module_utils/facts/hardware/sunos.py
Using module_utils file /usr/lib/python3.9/site-packages/ansible/module_utils/facts/network/netbsd.py
Using module_utils file /usr/lib/python3.9/site-packages/ansible/module_utils/facts/other/ohai.py
Using module_utils file /usr/lib/python3.9/site-packages/ansible/module_utils/facts/system/date_time.py
Using module_utils file /usr/lib/python3.9/site-packages/ansible/module_utils/facts/hardware/darwin.py
Using module_utils file /usr/lib/python3.9/site-packages/ansible/module_utils/facts/virtual/netbsd.py
Using module_utils file /usr/lib/python3.9/site-packages/ansible/module_utils/facts/virtual/dragonfly.py
Using module_utils file /usr/lib/python3.9/site-packages/ansible/module_utils/facts/system/__init__.py
Using module_utils file /usr/lib/python3.9/site-packages/ansible/module_utils/facts/network/fc_wwn.py
Using module_utils file /usr/lib/python3.9/site-packages/ansible/module_utils/facts/hardware/dragonfly.py
Using module_utils file /usr/lib/python3.9/site-packages/ansible/module_utils/facts/system/user.py
Using module_utils file /usr/lib/python3.9/site-packages/ansible/module_utils/facts/hardware/netbsd.py
Using module_utils file /usr/lib/python3.9/site-packages/ansible/module_utils/facts/network/hurd.py
Using module_utils file /usr/lib/python3.9/site-packages/ansible/module_utils/facts/network/aix.py
Using module_utils file /usr/lib/python3.9/site-packages/ansible/module_utils/facts/system/chroot.py
Using module_utils file /usr/lib/python3.9/site-packages/ansible/module_utils/facts/system/selinux.py
Using module_utils file /usr/lib/python3.9/site-packages/ansible/module_utils/facts/network/freebsd.py
Using module_utils file /usr/lib/python3.9/site-packages/ansible/module_utils/facts/system/caps.py
Using module_utils file /usr/lib/python3.9/site-packages/ansible/module_utils/facts/network/nvme.py
Using module_utils file /usr/lib/python3.9/site-packages/ansible/module_utils/facts/system/local.py
Using module_utils file /usr/lib/python3.9/site-packages/ansible/module_utils/facts/other/facter.py
Using module_utils file /usr/lib/python3.9/site-packages/ansible/module_utils/facts/system/apparmor.py
Using module_utils file /usr/lib/python3.9/site-packages/ansible/module_utils/facts/virtual/freebsd.py
Using module_utils file /usr/lib/python3.9/site-packages/ansible/module_utils/facts/system/lsb.py
Using module_utils file /usr/lib/python3.9/site-packages/ansible/module_utils/facts/network/openbsd.py
Using module_utils file /usr/lib/python3.9/site-packages/ansible/module_utils/facts/system/env.py
Using module_utils file /usr/lib/python3.9/site-packages/ansible/module_utils/facts/system/python.py
Using module_utils file /usr/lib/python3.9/site-packages/ansible/module_utils/facts/hardware/hurd.py
Using module_utils file /usr/lib/python3.9/site-packages/ansible/module_utils/facts/hardware/aix.py
Using module_utils file /usr/lib/python3.9/site-packages/ansible/module_utils/facts/network/hpux.py
Using module_utils file /usr/lib/python3.9/site-packages/ansible/module_utils/facts/system/ssh_pub_keys.py
Using module_utils file /usr/lib/python3.9/site-packages/ansible/module_utils/facts/hardware/freebsd.py
Using module_utils file /usr/lib/python3.9/site-packages/ansible/module_utils/facts/virtual/openbsd.py
Using module_utils file /usr/lib/python3.9/site-packages/ansible/module_utils/facts/system/pkg_mgr.py
Using module_utils file /usr/lib/python3.9/site-packages/ansible/module_utils/facts/system/distribution.py
Using module_utils file /usr/lib/python3.9/site-packages/ansible/module_utils/facts/virtual/hpux.py
Using module_utils file /usr/lib/python3.9/site-packages/ansible/module_utils/facts/network/linux.py
Using module_utils file /usr/lib/python3.9/site-packages/ansible/module_utils/facts/network/__init__.py
Using module_utils file /usr/lib/python3.9/site-packages/ansible/module_utils/facts/system/fips.py
Using module_utils file /usr/lib/python3.9/site-packages/ansible/module_utils/facts/hardware/openbsd.py
Using module_utils file /usr/lib/python3.9/site-packages/ansible/module_utils/facts/system/cmdline.py
Using module_utils file /usr/lib/python3.9/site-packages/ansible/module_utils/facts/network/base.py
Using module_utils file /usr/lib/python3.9/site-packages/ansible/module_utils/facts/virtual/__init__.py
Using module_utils file /usr/lib/python3.9/site-packages/ansible/module_utils/facts/hardware/hpux.py
Using module_utils file /usr/lib/python3.9/site-packages/ansible/module_utils/facts/virtual/linux.py
Using module_utils file /usr/lib/python3.9/site-packages/ansible/module_utils/facts/system/platform.py
Using module_utils file /usr/lib/python3.9/site-packages/ansible/module_utils/facts/other/__init__.py
Using module_utils file /usr/lib/python3.9/site-packages/ansible/module_utils/facts/network/sunos.py
Using module_utils file /usr/lib/python3.9/site-packages/ansible/module_utils/facts/utils.py
Using module_utils file /usr/lib/python3.9/site-packages/ansible/module_utils/facts/timeout.py
Using module_utils file /usr/lib/python3.9/site-packages/ansible/module_utils/facts/network/generic_bsd.py
Using module_utils file /usr/lib/python3.9/site-packages/ansible/module_utils/facts/collector.py
Using module_utils file /usr/lib/python3.9/site-packages/ansible/module_utils/facts/sysctl.py
Using module_utils file /usr/lib/python3.9/site-packages/ansible/module_utils/facts/virtual/sysctl.py
Using module file /usr/lib/python3.9/site-packages/ansible/modules/system/setup.py
<127.0.0.1> PUT /home/daniel/.ansible/tmp/ansible-local-1079268xzxtahwz/tmpbvi9znku TO /home/daniel/.ansible/tmp/ansible-tmp-1626687779.0045197-1079272-70130803665671/AnsiballZ_setup.py
<127.0.0.1> EXEC /bin/sh -c 'chmod u+x /home/daniel/.ansible/tmp/ansible-tmp-1626687779.0045197-1079272-70130803665671/ /home/daniel/.ansible/tmp/ansible-tmp-1626687779.0045197-1079272-70130803665671/AnsiballZ_setup.py && sleep 0'
<127.0.0.1> EXEC /bin/sh -c '/usr/bin/python3 /home/daniel/.ansible/tmp/ansible-tmp-1626687779.0045197-1079272-70130803665671/AnsiballZ_setup.py && sleep 0'
<127.0.0.1> EXEC /bin/sh -c 'rm -f -r /home/daniel/.ansible/tmp/ansible-tmp-1626687779.0045197-1079272-70130803665671/ > /dev/null 2>&1 && sleep 0'
ok: [localhost]
META: ran handlers

TASK [create temporary directory] ****************************************************************************************************************************************************************************************************************************************************************************************************************************************************************
task path: /home/daniel/Development/github/ansible_collections/community/general/ini_file-issue.yml:4
<127.0.0.1> ESTABLISH LOCAL CONNECTION FOR USER: daniel
<127.0.0.1> EXEC /bin/sh -c 'echo ~daniel && sleep 0'
<127.0.0.1> EXEC /bin/sh -c '( umask 77 && mkdir -p "` echo /home/daniel/.ansible/tmp `"&& mkdir "` echo /home/daniel/.ansible/tmp/ansible-tmp-1626687779.5823815-1079418-42515002231040 `" && echo ansible-tmp-1626687779.5823815-1079418-42515002231040="` echo /home/daniel/.ansible/tmp/ansible-tmp-1626687779.5823815-1079418-42515002231040 `" ) && sleep 0'
Using module_utils file /usr/lib/python3.9/site-packages/ansible/module_utils/_text.py
Using module_utils file /usr/lib/python3.9/site-packages/ansible/module_utils/basic.py
Using module_utils file /usr/lib/python3.9/site-packages/ansible/module_utils/six/__init__.py
Using module_utils file /usr/lib/python3.9/site-packages/ansible/module_utils/compat/__init__.py
Using module_utils file /usr/lib/python3.9/site-packages/ansible/module_utils/parsing/__init__.py
Using module_utils file /usr/lib/python3.9/site-packages/ansible/module_utils/common/file.py
Using module_utils file /usr/lib/python3.9/site-packages/ansible/module_utils/pycompat24.py
Using module_utils file /usr/lib/python3.9/site-packages/ansible/module_utils/compat/selectors.py
Using module_utils file /usr/lib/python3.9/site-packages/ansible/module_utils/common/_utils.py
Using module_utils file /usr/lib/python3.9/site-packages/ansible/module_utils/common/parameters.py
Using module_utils file /usr/lib/python3.9/site-packages/ansible/module_utils/common/text/__init__.py
Using module_utils file /usr/lib/python3.9/site-packages/ansible/module_utils/parsing/convert_bool.py
Using module_utils file /usr/lib/python3.9/site-packages/ansible/module_utils/common/__init__.py
Using module_utils file /usr/lib/python3.9/site-packages/ansible/module_utils/common/text/formatters.py
Using module_utils file /usr/lib/python3.9/site-packages/ansible/module_utils/common/sys_info.py
Using module_utils file /usr/lib/python3.9/site-packages/ansible/module_utils/common/validation.py
Using module_utils file /usr/lib/python3.9/site-packages/ansible/module_utils/common/text/converters.py
Using module_utils file /usr/lib/python3.9/site-packages/ansible/module_utils/common/_collections_compat.py
Using module_utils file /usr/lib/python3.9/site-packages/ansible/module_utils/common/process.py
Using module_utils file /usr/lib/python3.9/site-packages/ansible/module_utils/common/_json_compat.py
Using module_utils file /usr/lib/python3.9/site-packages/ansible/module_utils/compat/_selectors2.py
Using module_utils file /usr/lib/python3.9/site-packages/ansible/module_utils/common/collections.py
Using module_utils file /usr/lib/python3.9/site-packages/ansible/module_utils/distro/__init__.py
Using module_utils file /usr/lib/python3.9/site-packages/ansible/module_utils/distro/_distro.py
Using module file /usr/lib/python3.9/site-packages/ansible/modules/files/tempfile.py
<127.0.0.1> PUT /home/daniel/.ansible/tmp/ansible-local-1079268xzxtahwz/tmpjsvz2b1h TO /home/daniel/.ansible/tmp/ansible-tmp-1626687779.5823815-1079418-42515002231040/AnsiballZ_tempfile.py
<127.0.0.1> EXEC /bin/sh -c 'chmod u+x /home/daniel/.ansible/tmp/ansible-tmp-1626687779.5823815-1079418-42515002231040/ /home/daniel/.ansible/tmp/ansible-tmp-1626687779.5823815-1079418-42515002231040/AnsiballZ_tempfile.py && sleep 0'
<127.0.0.1> EXEC /bin/sh -c '/usr/bin/python3 /home/daniel/.ansible/tmp/ansible-tmp-1626687779.5823815-1079418-42515002231040/AnsiballZ_tempfile.py && sleep 0'
<127.0.0.1> EXEC /bin/sh -c 'rm -f -r /home/daniel/.ansible/tmp/ansible-tmp-1626687779.5823815-1079418-42515002231040/ > /dev/null 2>&1 && sleep 0'
changed: [localhost] => {
    "changed": true,
    "gid": 1000,
    "group": "daniel",
    "invocation": {
        "module_args": {
            "path": null,
            "prefix": "ansible.",
            "state": "directory",
            "suffix": ".test"
        }
    },
    "mode": "0700",
    "owner": "daniel",
    "path": "/tmp/ansible.exrjkap5.test",
    "secontext": "unconfined_u:object_r:user_tmp_t:s0",
    "size": 40,
    "state": "directory",
    "uid": 1000
}

TASK [record temporary directory] ****************************************************************************************************************************************************************************************************************************************************************************************************************************************************************
task path: /home/daniel/Development/github/ansible_collections/community/general/ini_file-issue.yml:10
ok: [localhost] => {
    "ansible_facts": {
        "remote_tmp_dir": "/tmp/ansible.exrjkap5.test"
    },
    "changed": false
}

TASK [record the output directory] ***************************************************************************************************************************************************************************************************************************************************************************************************************************************************************
task path: /home/daniel/Development/github/ansible_collections/community/general/ini_file-issue.yml:14
ok: [localhost] => {
    "ansible_facts": {
        "output_file": "/tmp/ansible.exrjkap5.test/foo.ini"
    },
    "changed": false
}

TASK [Test with empty string in non-existing section] ********************************************************************************************************************************************************************************************************************************************************************************************************************************************
task path: /home/daniel/Development/github/ansible_collections/community/general/ini_file-issue.yml:17
<127.0.0.1> ESTABLISH LOCAL CONNECTION FOR USER: daniel
<127.0.0.1> EXEC /bin/sh -c 'echo ~daniel && sleep 0'
<127.0.0.1> EXEC /bin/sh -c '( umask 77 && mkdir -p "` echo /home/daniel/.ansible/tmp `"&& mkdir "` echo /home/daniel/.ansible/tmp/ansible-tmp-1626687779.8068976-1079439-239876695883337 `" && echo ansible-tmp-1626687779.8068976-1079439-239876695883337="` echo /home/daniel/.ansible/tmp/ansible-tmp-1626687779.8068976-1079439-239876695883337 `" ) && sleep 0'
Using module_utils file /usr/lib/python3.9/site-packages/ansible/module_utils/common/text/converters.py
Using module_utils file /usr/lib/python3.9/site-packages/ansible/module_utils/common/__init__.py
Using module_utils file /usr/lib/python3.9/site-packages/ansible/module_utils/common/text/__init__.py
Using module_utils file /usr/lib/python3.9/site-packages/ansible/module_utils/basic.py
Using module_utils file /usr/lib/python3.9/site-packages/ansible/module_utils/common/_collections_compat.py
Using module_utils file /usr/lib/python3.9/site-packages/ansible/module_utils/_text.py
Using module_utils file /usr/lib/python3.9/site-packages/ansible/module_utils/six/__init__.py
Using module_utils file /usr/lib/python3.9/site-packages/ansible/module_utils/compat/__init__.py
Using module_utils file /usr/lib/python3.9/site-packages/ansible/module_utils/parsing/__init__.py
Using module_utils file /usr/lib/python3.9/site-packages/ansible/module_utils/common/file.py
Using module_utils file /usr/lib/python3.9/site-packages/ansible/module_utils/pycompat24.py
Using module_utils file /usr/lib/python3.9/site-packages/ansible/module_utils/compat/selectors.py
Using module_utils file /usr/lib/python3.9/site-packages/ansible/module_utils/common/_utils.py
Using module_utils file /usr/lib/python3.9/site-packages/ansible/module_utils/common/parameters.py
Using module_utils file /usr/lib/python3.9/site-packages/ansible/module_utils/parsing/convert_bool.py
Using module_utils file /usr/lib/python3.9/site-packages/ansible/module_utils/common/text/formatters.py
Using module_utils file /usr/lib/python3.9/site-packages/ansible/module_utils/common/sys_info.py
Using module_utils file /usr/lib/python3.9/site-packages/ansible/module_utils/common/validation.py
Using module_utils file /usr/lib/python3.9/site-packages/ansible/module_utils/common/process.py
Using module_utils file /usr/lib/python3.9/site-packages/ansible/module_utils/common/_json_compat.py
Using module_utils file /usr/lib/python3.9/site-packages/ansible/module_utils/compat/_selectors2.py
Using module_utils file /usr/lib/python3.9/site-packages/ansible/module_utils/common/collections.py
Using module_utils file /usr/lib/python3.9/site-packages/ansible/module_utils/distro/__init__.py
Using module_utils file /usr/lib/python3.9/site-packages/ansible/module_utils/distro/_distro.py
Using module file /home/daniel/.ansible/collections/ansible_collections/community/general/plugins/modules/ini_file.py
<127.0.0.1> PUT /home/daniel/.ansible/tmp/ansible-local-1079268xzxtahwz/tmpwjigppw9 TO /home/daniel/.ansible/tmp/ansible-tmp-1626687779.8068976-1079439-239876695883337/AnsiballZ_ini_file.py
<127.0.0.1> EXEC /bin/sh -c 'chmod u+x /home/daniel/.ansible/tmp/ansible-tmp-1626687779.8068976-1079439-239876695883337/ /home/daniel/.ansible/tmp/ansible-tmp-1626687779.8068976-1079439-239876695883337/AnsiballZ_ini_file.py && sleep 0'
<127.0.0.1> EXEC /bin/sh -c '/usr/bin/python3 /home/daniel/.ansible/tmp/ansible-tmp-1626687779.8068976-1079439-239876695883337/AnsiballZ_ini_file.py && sleep 0'
<127.0.0.1> EXEC /bin/sh -c 'rm -f -r /home/daniel/.ansible/tmp/ansible-tmp-1626687779.8068976-1079439-239876695883337/ > /dev/null 2>&1 && sleep 0'
changed: [localhost] => {
    "changed": true,
    "diff": {
        "after": "",
        "after_header": "/tmp/ansible.exrjkap5.test/foo.ini (content)",
        "before": "",
        "before_header": "/tmp/ansible.exrjkap5.test/foo.ini (content)"
    },
    "gid": 1000,
    "group": "daniel",
    "invocation": {
        "module_args": {
            "allow_no_value": false,
            "attributes": null,
            "backup": false,
            "content": null,
            "create": true,
            "delimiter": null,
            "directory_mode": null,
            "follow": false,
            "force": null,
            "group": null,
            "mode": null,
            "no_extra_spaces": false,
            "option": "var1",
            "owner": null,
            "path": "/tmp/ansible.exrjkap5.test/foo.ini",
            "regexp": null,
            "remote_src": null,
            "section": "section1",
            "selevel": null,
            "serole": null,
            "setype": null,
            "seuser": null,
            "src": null,
            "state": "present",
            "unsafe_writes": null,
            "value": ""
        }
    },
    "mode": "0664",
    "msg": "section and option added",
    "owner": "daniel",
    "path": "/tmp/ansible.exrjkap5.test/foo.ini",
    "secontext": "unconfined_u:object_r:user_home_t:s0",
    "size": 20,
    "state": "file",
    "uid": 1000
}

TASK [read content from output file] *************************************************************************************************************************************************************************************************************************************************************************************************************************************************************
task path: /home/daniel/Development/github/ansible_collections/community/general/ini_file-issue.yml:24
<127.0.0.1> ESTABLISH LOCAL CONNECTION FOR USER: daniel
<127.0.0.1> EXEC /bin/sh -c 'echo ~daniel && sleep 0'
<127.0.0.1> EXEC /bin/sh -c '( umask 77 && mkdir -p "` echo /home/daniel/.ansible/tmp `"&& mkdir "` echo /home/daniel/.ansible/tmp/ansible-tmp-1626687779.9876573-1079455-239740078583458 `" && echo ansible-tmp-1626687779.9876573-1079455-239740078583458="` echo /home/daniel/.ansible/tmp/ansible-tmp-1626687779.9876573-1079455-239740078583458 `" ) && sleep 0'
Using module_utils file /usr/lib/python3.9/site-packages/ansible/module_utils/basic.py
Using module_utils file /usr/lib/python3.9/site-packages/ansible/module_utils/parsing/__init__.py
Using module_utils file /usr/lib/python3.9/site-packages/ansible/module_utils/compat/selectors.py
Using module_utils file /usr/lib/python3.9/site-packages/ansible/module_utils/parsing/convert_bool.py
Using module_utils file /usr/lib/python3.9/site-packages/ansible/module_utils/common/text/formatters.py
Using module_utils file /usr/lib/python3.9/site-packages/ansible/module_utils/common/validation.py
Using module_utils file /usr/lib/python3.9/site-packages/ansible/module_utils/common/_collections_compat.py
Using module_utils file /usr/lib/python3.9/site-packages/ansible/module_utils/common/process.py
Using module_utils file /usr/lib/python3.9/site-packages/ansible/module_utils/six/__init__.py
Using module_utils file /usr/lib/python3.9/site-packages/ansible/module_utils/common/text/__init__.py
Using module_utils file /usr/lib/python3.9/site-packages/ansible/module_utils/compat/__init__.py
Using module_utils file /usr/lib/python3.9/site-packages/ansible/module_utils/common/_utils.py
Using module_utils file /usr/lib/python3.9/site-packages/ansible/module_utils/common/file.py
Using module_utils file /usr/lib/python3.9/site-packages/ansible/module_utils/pycompat24.py
Using module_utils file /usr/lib/python3.9/site-packages/ansible/module_utils/common/parameters.py
Using module_utils file /usr/lib/python3.9/site-packages/ansible/module_utils/_text.py
Using module_utils file /usr/lib/python3.9/site-packages/ansible/module_utils/common/__init__.py
Using module_utils file /usr/lib/python3.9/site-packages/ansible/module_utils/common/sys_info.py
Using module_utils file /usr/lib/python3.9/site-packages/ansible/module_utils/common/text/converters.py
Using module_utils file /usr/lib/python3.9/site-packages/ansible/module_utils/common/_json_compat.py
Using module_utils file /usr/lib/python3.9/site-packages/ansible/module_utils/compat/_selectors2.py
Using module_utils file /usr/lib/python3.9/site-packages/ansible/module_utils/common/collections.py
Using module_utils file /usr/lib/python3.9/site-packages/ansible/module_utils/distro/__init__.py
Using module_utils file /usr/lib/python3.9/site-packages/ansible/module_utils/distro/_distro.py
Using module file /usr/lib/python3.9/site-packages/ansible/modules/net_tools/basics/slurp.py
<127.0.0.1> PUT /home/daniel/.ansible/tmp/ansible-local-1079268xzxtahwz/tmpuh4h52yk TO /home/daniel/.ansible/tmp/ansible-tmp-1626687779.9876573-1079455-239740078583458/AnsiballZ_slurp.py
<127.0.0.1> EXEC /bin/sh -c 'chmod u+x /home/daniel/.ansible/tmp/ansible-tmp-1626687779.9876573-1079455-239740078583458/ /home/daniel/.ansible/tmp/ansible-tmp-1626687779.9876573-1079455-239740078583458/AnsiballZ_slurp.py && sleep 0'
<127.0.0.1> EXEC /bin/sh -c '/usr/bin/python3 /home/daniel/.ansible/tmp/ansible-tmp-1626687779.9876573-1079455-239740078583458/AnsiballZ_slurp.py && sleep 0'
<127.0.0.1> EXEC /bin/sh -c 'rm -f -r /home/daniel/.ansible/tmp/ansible-tmp-1626687779.9876573-1079455-239740078583458/ > /dev/null 2>&1 && sleep 0'
ok: [localhost] => {
    "changed": false,
    "content": "CltzZWN0aW9uMV0KdmFyMSA9IAo=",
    "encoding": "base64",
    "invocation": {
        "module_args": {
            "src": "/tmp/ansible.exrjkap5.test/foo.ini"
        }
    },
    "source": "/tmp/ansible.exrjkap5.test/foo.ini"
}

TASK [set expected content and get current ini file content] *************************************************************************************************************************************************************************************************************************************************************************************************************************************
task path: /home/daniel/Development/github/ansible_collections/community/general/ini_file-issue.yml:29
ok: [localhost] => {
    "ansible_facts": {
        "content": "\n[section1]\nvar1 = \n",
        "expected": "\n[section1]\nvar1 = \n"
    },
    "changed": false
}

TASK [debug] *************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************
task path: /home/daniel/Development/github/ansible_collections/community/general/ini_file-issue.yml:37
ok: [localhost] => {
    "expected": "\n[section1]\nvar1 = \n"
}

TASK [debug] *************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************
task path: /home/daniel/Development/github/ansible_collections/community/general/ini_file-issue.yml:38
ok: [localhost] => {
    "content": "\n[section1]\nvar1 = \n"
}

TASK [copy ini file] *****************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************
task path: /home/daniel/Development/github/ansible_collections/community/general/ini_file-issue.yml:40
<127.0.0.1> ESTABLISH LOCAL CONNECTION FOR USER: daniel
<127.0.0.1> EXEC /bin/sh -c 'echo ~daniel && sleep 0'
<127.0.0.1> EXEC /bin/sh -c '( umask 77 && mkdir -p "` echo /home/daniel/.ansible/tmp `"&& mkdir "` echo /home/daniel/.ansible/tmp/ansible-tmp-1626687780.2385635-1079479-162530678137431 `" && echo ansible-tmp-1626687780.2385635-1079479-162530678137431="` echo /home/daniel/.ansible/tmp/ansible-tmp-1626687780.2385635-1079479-162530678137431 `" ) && sleep 0'
Using module_utils file /usr/lib/python3.9/site-packages/ansible/module_utils/_text.py
Using module_utils file /usr/lib/python3.9/site-packages/ansible/module_utils/basic.py
Using module_utils file /usr/lib/python3.9/site-packages/ansible/module_utils/six/__init__.py
Using module_utils file /usr/lib/python3.9/site-packages/ansible/module_utils/compat/__init__.py
Using module_utils file /usr/lib/python3.9/site-packages/ansible/module_utils/parsing/__init__.py
Using module_utils file /usr/lib/python3.9/site-packages/ansible/module_utils/common/file.py
Using module_utils file /usr/lib/python3.9/site-packages/ansible/module_utils/pycompat24.py
Using module_utils file /usr/lib/python3.9/site-packages/ansible/module_utils/compat/selectors.py
Using module_utils file /usr/lib/python3.9/site-packages/ansible/module_utils/common/_utils.py
Using module_utils file /usr/lib/python3.9/site-packages/ansible/module_utils/common/parameters.py
Using module_utils file /usr/lib/python3.9/site-packages/ansible/module_utils/common/text/__init__.py
Using module_utils file /usr/lib/python3.9/site-packages/ansible/module_utils/parsing/convert_bool.py
Using module_utils file /usr/lib/python3.9/site-packages/ansible/module_utils/common/__init__.py
Using module_utils file /usr/lib/python3.9/site-packages/ansible/module_utils/common/text/formatters.py
Using module_utils file /usr/lib/python3.9/site-packages/ansible/module_utils/common/sys_info.py
Using module_utils file /usr/lib/python3.9/site-packages/ansible/module_utils/common/validation.py
Using module_utils file /usr/lib/python3.9/site-packages/ansible/module_utils/common/text/converters.py
Using module_utils file /usr/lib/python3.9/site-packages/ansible/module_utils/common/_collections_compat.py
Using module_utils file /usr/lib/python3.9/site-packages/ansible/module_utils/common/process.py
Using module_utils file /usr/lib/python3.9/site-packages/ansible/module_utils/common/_json_compat.py
Using module_utils file /usr/lib/python3.9/site-packages/ansible/module_utils/compat/_selectors2.py
Using module_utils file /usr/lib/python3.9/site-packages/ansible/module_utils/common/collections.py
Using module_utils file /usr/lib/python3.9/site-packages/ansible/module_utils/distro/__init__.py
Using module_utils file /usr/lib/python3.9/site-packages/ansible/module_utils/distro/_distro.py
Using module file /usr/lib/python3.9/site-packages/ansible/modules/files/stat.py
<127.0.0.1> PUT /home/daniel/.ansible/tmp/ansible-local-1079268xzxtahwz/tmpk7e4k88h TO /home/daniel/.ansible/tmp/ansible-tmp-1626687780.2385635-1079479-162530678137431/AnsiballZ_stat.py
<127.0.0.1> EXEC /bin/sh -c 'chmod u+x /home/daniel/.ansible/tmp/ansible-tmp-1626687780.2385635-1079479-162530678137431/ /home/daniel/.ansible/tmp/ansible-tmp-1626687780.2385635-1079479-162530678137431/AnsiballZ_stat.py && sleep 0'
<127.0.0.1> EXEC /bin/sh -c '/usr/bin/python3 /home/daniel/.ansible/tmp/ansible-tmp-1626687780.2385635-1079479-162530678137431/AnsiballZ_stat.py && sleep 0'
<127.0.0.1> PUT /home/daniel/.ansible/tmp/ansible-local-1079268xzxtahwz/tmpz8_7y_ah TO /home/daniel/.ansible/tmp/ansible-tmp-1626687780.2385635-1079479-162530678137431/source
<127.0.0.1> EXEC /bin/sh -c 'chmod u+x /home/daniel/.ansible/tmp/ansible-tmp-1626687780.2385635-1079479-162530678137431/ /home/daniel/.ansible/tmp/ansible-tmp-1626687780.2385635-1079479-162530678137431/source && sleep 0'
Using module_utils file /usr/lib/python3.9/site-packages/ansible/module_utils/basic.py
Using module_utils file /usr/lib/python3.9/site-packages/ansible/module_utils/_text.py
Using module_utils file /usr/lib/python3.9/site-packages/ansible/module_utils/common/__init__.py
Using module_utils file /usr/lib/python3.9/site-packages/ansible/module_utils/common/process.py
Using module_utils file /usr/lib/python3.9/site-packages/ansible/module_utils/six/__init__.py
Using module_utils file /usr/lib/python3.9/site-packages/ansible/module_utils/compat/__init__.py
Using module_utils file /usr/lib/python3.9/site-packages/ansible/module_utils/parsing/__init__.py
Using module_utils file /usr/lib/python3.9/site-packages/ansible/module_utils/common/file.py
Using module_utils file /usr/lib/python3.9/site-packages/ansible/module_utils/pycompat24.py
Using module_utils file /usr/lib/python3.9/site-packages/ansible/module_utils/compat/selectors.py
Using module_utils file /usr/lib/python3.9/site-packages/ansible/module_utils/common/_utils.py
Using module_utils file /usr/lib/python3.9/site-packages/ansible/module_utils/common/parameters.py
Using module_utils file /usr/lib/python3.9/site-packages/ansible/module_utils/parsing/convert_bool.py
Using module_utils file /usr/lib/python3.9/site-packages/ansible/module_utils/common/text/formatters.py
Using module_utils file /usr/lib/python3.9/site-packages/ansible/module_utils/common/sys_info.py
Using module_utils file /usr/lib/python3.9/site-packages/ansible/module_utils/common/validation.py
Using module_utils file /usr/lib/python3.9/site-packages/ansible/module_utils/common/text/converters.py
Using module_utils file /usr/lib/python3.9/site-packages/ansible/module_utils/common/_collections_compat.py
Using module_utils file /usr/lib/python3.9/site-packages/ansible/module_utils/common/text/__init__.py
Using module_utils file /usr/lib/python3.9/site-packages/ansible/module_utils/common/_json_compat.py
Using module_utils file /usr/lib/python3.9/site-packages/ansible/module_utils/compat/_selectors2.py
Using module_utils file /usr/lib/python3.9/site-packages/ansible/module_utils/common/collections.py
Using module_utils file /usr/lib/python3.9/site-packages/ansible/module_utils/distro/__init__.py
Using module_utils file /usr/lib/python3.9/site-packages/ansible/module_utils/distro/_distro.py
Using module file /usr/lib/python3.9/site-packages/ansible/modules/files/copy.py
<127.0.0.1> PUT /home/daniel/.ansible/tmp/ansible-local-1079268xzxtahwz/tmp7w7mi_rq TO /home/daniel/.ansible/tmp/ansible-tmp-1626687780.2385635-1079479-162530678137431/AnsiballZ_copy.py
<127.0.0.1> EXEC /bin/sh -c 'chmod u+x /home/daniel/.ansible/tmp/ansible-tmp-1626687780.2385635-1079479-162530678137431/ /home/daniel/.ansible/tmp/ansible-tmp-1626687780.2385635-1079479-162530678137431/AnsiballZ_copy.py && sleep 0'
<127.0.0.1> EXEC /bin/sh -c '/usr/bin/python3 /home/daniel/.ansible/tmp/ansible-tmp-1626687780.2385635-1079479-162530678137431/AnsiballZ_copy.py && sleep 0'
<127.0.0.1> EXEC /bin/sh -c 'rm -f -r /home/daniel/.ansible/tmp/ansible-tmp-1626687780.2385635-1079479-162530678137431/ > /dev/null 2>&1 && sleep 0'
changed: [localhost] => {
    "changed": true,
    "checksum": "04cb4c94e3b44d59d7fa17c62c98bd099958a646",
    "dest": "/tmp/ansible.exrjkap5.test/foo.ini",
    "diff": [],
    "gid": 1000,
    "group": "daniel",
    "invocation": {
        "module_args": {
            "_original_basename": "tmpz8_7y_ah",
            "attributes": null,
            "backup": false,
            "checksum": "04cb4c94e3b44d59d7fa17c62c98bd099958a646",
            "content": null,
            "delimiter": null,
            "dest": "/tmp/ansible.exrjkap5.test/foo.ini",
            "directory_mode": null,
            "follow": false,
            "force": true,
            "group": null,
            "local_follow": null,
            "mode": null,
            "owner": null,
            "regexp": null,
            "remote_src": null,
            "selevel": null,
            "serole": null,
            "setype": null,
            "seuser": null,
            "src": "/home/daniel/.ansible/tmp/ansible-tmp-1626687780.2385635-1079479-162530678137431/source",
            "unsafe_writes": null,
            "validate": null
        }
    },
    "md5sum": "eeaa32ff486de5b5981bab27da5cb580",
    "mode": "0664",
    "owner": "daniel",
    "secontext": "unconfined_u:object_r:user_home_t:s0",
    "size": 58,
    "src": "/home/daniel/.ansible/tmp/ansible-tmp-1626687780.2385635-1079479-162530678137431/source",
    "state": "file",
    "uid": 1000
}

TASK [Test with empty string in existing section] ************************************************************************************************************************************************************************************************************************************************************************************************************************************************
task path: /home/daniel/Development/github/ansible_collections/community/general/ini_file-issue.yml:53
<127.0.0.1> ESTABLISH LOCAL CONNECTION FOR USER: daniel
<127.0.0.1> EXEC /bin/sh -c 'echo ~daniel && sleep 0'
<127.0.0.1> EXEC /bin/sh -c '( umask 77 && mkdir -p "` echo /home/daniel/.ansible/tmp `"&& mkdir "` echo /home/daniel/.ansible/tmp/ansible-tmp-1626687780.5913038-1079503-212919886700693 `" && echo ansible-tmp-1626687780.5913038-1079503-212919886700693="` echo /home/daniel/.ansible/tmp/ansible-tmp-1626687780.5913038-1079503-212919886700693 `" ) && sleep 0'
Using module file /home/daniel/.ansible/collections/ansible_collections/community/general/plugins/modules/ini_file.py
<127.0.0.1> PUT /home/daniel/.ansible/tmp/ansible-local-1079268xzxtahwz/tmpbtoo1p5h TO /home/daniel/.ansible/tmp/ansible-tmp-1626687780.5913038-1079503-212919886700693/AnsiballZ_ini_file.py
<127.0.0.1> EXEC /bin/sh -c 'chmod u+x /home/daniel/.ansible/tmp/ansible-tmp-1626687780.5913038-1079503-212919886700693/ /home/daniel/.ansible/tmp/ansible-tmp-1626687780.5913038-1079503-212919886700693/AnsiballZ_ini_file.py && sleep 0'
<127.0.0.1> EXEC /bin/sh -c '/usr/bin/python3 /home/daniel/.ansible/tmp/ansible-tmp-1626687780.5913038-1079503-212919886700693/AnsiballZ_ini_file.py && sleep 0'
<127.0.0.1> EXEC /bin/sh -c 'rm -f -r /home/daniel/.ansible/tmp/ansible-tmp-1626687780.5913038-1079503-212919886700693/ > /dev/null 2>&1 && sleep 0'
ok: [localhost] => {
    "changed": false,
    "diff": {
        "after": "",
        "after_header": "/tmp/ansible.exrjkap5.test/foo.ini (content)",
        "before": "",
        "before_header": "/tmp/ansible.exrjkap5.test/foo.ini (content)"
    },
    "gid": 1000,
    "group": "daniel",
    "invocation": {
        "module_args": {
            "allow_no_value": false,
            "attributes": null,
            "backup": false,
            "content": null,
            "create": true,
            "delimiter": null,
            "directory_mode": null,
            "follow": false,
            "force": null,
            "group": null,
            "mode": null,
            "no_extra_spaces": false,
            "option": "var5",
            "owner": null,
            "path": "/tmp/ansible.exrjkap5.test/foo.ini",
            "regexp": null,
            "remote_src": null,
            "section": "section1",
            "selevel": null,
            "serole": null,
            "setype": null,
            "seuser": null,
            "src": null,
            "state": "present",
            "unsafe_writes": null,
            "value": ""
        }
    },
    "mode": "0664",
    "msg": "OK",
    "owner": "daniel",
    "path": "/tmp/ansible.exrjkap5.test/foo.ini",
    "secontext": "unconfined_u:object_r:user_home_t:s0",
    "size": 58,
    "state": "file",
    "uid": 1000
}

TASK [read content from output file] *************************************************************************************************************************************************************************************************************************************************************************************************************************************************************
task path: /home/daniel/Development/github/ansible_collections/community/general/ini_file-issue.yml:60
<127.0.0.1> ESTABLISH LOCAL CONNECTION FOR USER: daniel
<127.0.0.1> EXEC /bin/sh -c 'echo ~daniel && sleep 0'
<127.0.0.1> EXEC /bin/sh -c '( umask 77 && mkdir -p "` echo /home/daniel/.ansible/tmp `"&& mkdir "` echo /home/daniel/.ansible/tmp/ansible-tmp-1626687780.7217317-1079522-55254770128980 `" && echo ansible-tmp-1626687780.7217317-1079522-55254770128980="` echo /home/daniel/.ansible/tmp/ansible-tmp-1626687780.7217317-1079522-55254770128980 `" ) && sleep 0'
Using module file /usr/lib/python3.9/site-packages/ansible/modules/net_tools/basics/slurp.py
<127.0.0.1> PUT /home/daniel/.ansible/tmp/ansible-local-1079268xzxtahwz/tmpev7feq_z TO /home/daniel/.ansible/tmp/ansible-tmp-1626687780.7217317-1079522-55254770128980/AnsiballZ_slurp.py
<127.0.0.1> EXEC /bin/sh -c 'chmod u+x /home/daniel/.ansible/tmp/ansible-tmp-1626687780.7217317-1079522-55254770128980/ /home/daniel/.ansible/tmp/ansible-tmp-1626687780.7217317-1079522-55254770128980/AnsiballZ_slurp.py && sleep 0'
<127.0.0.1> EXEC /bin/sh -c '/usr/bin/python3 /home/daniel/.ansible/tmp/ansible-tmp-1626687780.7217317-1079522-55254770128980/AnsiballZ_slurp.py && sleep 0'
<127.0.0.1> EXEC /bin/sh -c 'rm -f -r /home/daniel/.ansible/tmp/ansible-tmp-1626687780.7217317-1079522-55254770128980/ > /dev/null 2>&1 && sleep 0'
ok: [localhost] => {
    "changed": false,
    "content": "W3NlY3Rpb24xXQp2YXIxID0gCnZhcjI9YmJiCnZhcjQgPSAwCltzZWN0aW9uMl0KdmFyMz1jY2MKCg==",
    "encoding": "base64",
    "invocation": {
        "module_args": {
            "src": "/tmp/ansible.exrjkap5.test/foo.ini"
        }
    },
    "source": "/tmp/ansible.exrjkap5.test/foo.ini"
}

TASK [set expected content and get current ini file content] *************************************************************************************************************************************************************************************************************************************************************************************************************************************
task path: /home/daniel/Development/github/ansible_collections/community/general/ini_file-issue.yml:65
ok: [localhost] => {
    "ansible_facts": {
        "content": "[section1]\nvar1 = \nvar2=bbb\nvar4 = 0\n[section2]\nvar3=ccc\n\n",
        "expected": "[section1]\nvar1 = \nvar2=bbb\nvar4 = 0\nvar5 = \n[section2]\nvar3=ccc\n\n"
    },
    "changed": false
}

TASK [debug] *************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************
task path: /home/daniel/Development/github/ansible_collections/community/general/ini_file-issue.yml:79
ok: [localhost] => {
    "expected": "[section1]\nvar1 = \nvar2=bbb\nvar4 = 0\nvar5 = \n[section2]\nvar3=ccc\n\n"
}

TASK [debug] *************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************
task path: /home/daniel/Development/github/ansible_collections/community/general/ini_file-issue.yml:80
ok: [localhost] => {
    "content": "[section1]\nvar1 = \nvar2=bbb\nvar4 = 0\n[section2]\nvar3=ccc\n\n"
}
META: ran handlers
META: ran handlers

PLAY RECAP ***************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************
localhost                  : ok=15   changed=3    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

```


### Code of Conduct

- [X] I agree to follow the Ansible Code of Conduct


Discussion:
Files identified in the description:
* [`plugins/modules/files/ini_file.py`](https://github.com/ansible-collections/community.general/blob/master/plugins/modules/files/ini_file.py)

If these files are inaccurate, please update the `component name` section of the description or use the `!component` bot command.

[click here for bot help](https://github.com/ansible/ansibullbot/blob/master/ISSUE_HELP.md)
<!--- boilerplate: components_banner --->
cc @jpmens @noseka1
[click here for bot help](https://github.com/ansible/ansibullbot/blob/master/ISSUE_HELP.md)
<!--- boilerplate: notify --->
hi @ziegenberg , thank you for this detailed report !

Maybe there is some confusion somewhere in the code between an empty value and no value at all. I will take a deeper look in a few days.
Hi @quidame, If you tell me which way to solve the inconsistency, I can compile a PR and fix the issue. I've been working on PR #3033 and got some insight into ini_file lately. Based on the decision here, PR #3033 might need a small update as well.
I can reproduce the bug. In fact, it has nothing to do with `allow_no_value=False`. Or, more precisely, we get the same inconsistency when `allow_no_value=True`, but with a different result than when it is False.

```yaml
---
- hosts: localhost
  tasks:
    - name: remove test file
      file: /tmp/file.ini
        state: absent

    - name: add option with empty value in non-existing section
      ini_file:
        path: /tmp/file.ini
        section: foobar
        option: foo
        value: ""
        allow_no_value: "{{ allow_no_value | d(False) }}"

    - name: add option with empty value in existing section
      ini_file:
        path: /tmp/file.ini
        section: foobar
        option: bar
        value: ""
        allow_no_value: "{{ allow_no_value | d(False) }}"
```

 When we should get:
```dosini
[foobar]
foo = 
bar = 
```
with `allow_no_value=False`, we get:
```dosini
[foobar]
foo = 
```
with `allow_no_value=True`, we get:
```dosini
[foobar]
foo = 
bar 
```
The lines to focus on seem to be:
https://github.com/ansible-collections/community.general/blob/20db4fc5604472f9014d670974e33e7e9d704276/plugins/modules/files/ini_file.py#L208-L215
and
https://github.com/ansible-collections/community.general/blob/20db4fc5604472f9014d670974e33e7e9d704276/plugins/modules/files/ini_file.py#L228-L229
that are not consistent with:
https://github.com/ansible-collections/community.general/blob/20db4fc5604472f9014d670974e33e7e9d704276/plugins/modules/files/ini_file.py#L326-L327

I think these changes (non exhaustive, there's maybe more) should fix the issue:
```diff
-    if option and value:
+    if option and value is not None:
```
```diff
-    elif option and not value and allow_no_value:
+    elif option and value is None and allow_no_value:
```
and also, for clarity (empty value vs. no value at all):
```diff
-        module.fail_json("Parameter 'value' must not be empty if state=present and allow_no_value=False")
+        module.fail_json("Parameter 'value' is mandatory if state=present and allow_no_value=False")
```

Resolving patch:
diff --git a/plugins/modules/files/ini_file.py b/plugins/modules/files/ini_file.py
--- a/plugins/modules/files/ini_file.py
+++ b/plugins/modules/files/ini_file.py
@@ -193,11 +193,11 @@ def do_ini(module, filename, section=None, option=None, value=None,
                     for i in range(index, 0, -1):
                         # search backwards for previous non-blank or non-comment line
                         if not re.match(r'^[ \t]*([#;].*)?$', ini_lines[i - 1]):
-                            if option and value:
+                            if option and value is not None:
                                 ini_lines.insert(i, assignment_format % (option, value))
                                 msg = 'option added'
                                 changed = True
-                            elif option and not value and allow_no_value:
+                            elif option and value is None and allow_no_value:
                                 ini_lines.insert(i, '%s\n' % option)
                                 msg = 'option added'
                                 changed = True
@@ -213,7 +213,7 @@ def do_ini(module, filename, section=None, option=None, value=None,
                 if state == 'present':
                     # change the existing option line
                     if match_opt(option, line):
-                        if not value and allow_no_value:
+                        if value is None and allow_no_value:
                             newline = '%s\n' % option
                         else:
                             newline = assignment_format % (option, value)
@@ -311,7 +311,7 @@ def main():
     create = module.params['create']
 
     if state == 'present' and not allow_no_value and value is None:
-        module.fail_json("Parameter 'value' must not be empty if state=present and allow_no_value=False")
+        module.fail_json("Parameter 'value' must be defined if state=present and allow_no_value=False")
 
     (changed, backup_file, diff, msg) = do_ini(module, path, section, option, value, state, backup, no_extra_spaces, create, allow_no_value)
 


Test patch:
diff --git a/tests/integration/targets/ini_file/tasks/main.yml b/tests/integration/targets/ini_file/tasks/main.yml
--- a/tests/integration/targets/ini_file/tasks/main.yml
+++ b/tests/integration/targets/ini_file/tasks/main.yml
@@ -215,10 +215,10 @@
     path: "{{ output_file }}"
     section: mysqld
     option: "{{ item.o }}"
-    value: "{{ item.v }}"
+    value: "{{ item.v | d(omit) }}"
     allow_no_value: yes
   with_items:
-    - { o: "skip-name-resolve", v: null }
+    - { o: "skip-name-resolve" }
     - { o: "max_connections", v: "500" }
 
 - name: read content from output file
@@ -459,12 +459,23 @@
         option: like
         value: tea
         state: absent
-    - name: Test with empty string
+
+    # See https://github.com/ansible-collections/community.general/issues/3031
+    - name: Tests with empty strings
       ini_file:
         path: "{{ output_file }}"
-        section: extensions
-        option: evolve
+        section: "{{ item.section | d('extensions') }}"
+        option: "{{ item.option }}"
         value: ""
+        allow_no_value: "{{ item.no_value | d(omit) }}"
+      loop:
+        - option: evolve
+        - option: regress
+        - section: foobar
+          option: foo
+          no_value: true
+        - option: improve
+          no_value: true
 
 - name: read content from output file
   slurp:
@@ -473,7 +484,7 @@
 
 - name: set expected content and get current ini file content
   set_fact:
-    expected15: "\n[extensions]\nevolve = \n"
+    expected15: "\n[extensions]\nevolve = \nregress = \nimprove = \n[foobar]\nfoo = \n"
     content15: "{{ output_content.content | b64decode }}"
 - debug: var=content15
 - name: Verify content of ini file is as expected