Skip to content

sudoers module does not handle state: absent properly #4852

@s-hamann

Description

@s-hamann

Summary

The community.general.sudoers module does not handle state: absent properly.
If the file specified by name does not exist, it gets created, with possibly invalid content. As a side effect, commands and user/group is required, although these options do not make a lot of sense with state: absent.
If the file specified by name exists, it is (correctly) deleted. Of course, the next invocation of the play creates it again.

Issue Type

Bug Report

Component Name

sudoers

Ansible Version

$ ansible --version
ansible [core 2.12.5]
  config file = ...
  configured module search path = [...]
  ansible python module location = /usr/lib/python3.9/site-packages/ansible
  ansible collection location = /usr/share/ansible/collections
  executable location = /usr/lib/python-exec/python3.9/ansible
  python version = 3.9.12 (main, Jun 17 2022, 16:04:33) [GCC 11.3.0]
  jinja version = 3.1.2
  libyaml = True

Community.general Version

$ ansible-galaxy collection list community.general
# /usr/lib/python3.9/site-packages/ansible_collections
Collection        Version
----------------- -------
community.general 4.8.0  

Configuration

$ ansible-config dump --only-changed

OS / Environment

Target OS is Debian 11.

Steps to Reproduce

---
- hosts: all
  gather_facts: false
  tasks:
    - community.general.sudoers:
        name: test
        commands: []
        user: root
        state: absent

    - ansible.builtin.stat:
        path: /etc/sudoers.d/test
      register: _stat_sudoers

    - ansible.builtin.assert:
        that:
          - "not _stat_sudoers.stat.exists"

Note: /etc/sudoers.d/test is assumed not to exist prior to running this play.

Expected Results

The play never fails, i.e. /etc/sudoers.d/test gets deleted/not created.

Actual Results

The assertion fails on every second invocation of the play (starting with the first). The file /etc/sudoers.d/test gets created by the sudoers module.
The assertion passes on every other invocation of the play (starting with the second).

PLAY [all] **********************************************************************************************

TASK [community.general.sudoers] ************************************************************************
changed: [test]

TASK [ansible.builtin.stat] *****************************************************************************
ok: [test]

TASK [ansible.builtin.assert] ***************************************************************************
fatal: [test]: FAILED! => {
    "assertion": "not _stat_sudoers.stat.exists",
    "changed": false,
    "evaluated_to": false,
    "msg": "Assertion failed"
}

PLAY RECAP **********************************************************************************************
test                       : ok=2    changed=1    unreachable=0    failed=1    skipped=0    rescued=0    ignored=0

Code of Conduct

  • I agree to follow the Ansible Code of Conduct

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugThis issue/PR relates to a bugmodulemodulepluginsplugin (any type)system

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions