fix(tasks)!: stop flushing /etc/sudoers.d

Recreating /etc/sudoers.d on every run deleted every drop-in file on the host, not only the ones managed by this role.
That removes files shipped by packages or other tooling, such as 90-cloud-init-users on cloud instances, which can lock
out the remaining login paths. The task also reported changed on every run and therefore made check mode and CI runs
useless for detecting real drift.

The directory is now only ensured with its owner, group and permissions. To keep entries removable, each item of
sudo_users_sudoers accepts an optional state, which is passed to community.general.sudoers and defaults to present.

BREAKING CHANGE: Entries dropped from sudo_users_sudoers are no longer deleted implicitly. Set state: absent on the
entry to remove its drop-in file.

Co-authored-by: Copilot <copilot@github.com>
This commit is contained in:
2026-09-10 21:41:34 +02:00
co-authored by Copilot
parent 7c76a5cc86
commit c3f714a7c6
2 changed files with 7 additions and 9 deletions
+1
View File
@@ -7,4 +7,5 @@ sudo_users_sudoers: []
# group: "" # Group or User, not booth! # group: "" # Group or User, not booth!
# nopassword: true # nopassword: true
# runas: "" # Optional # runas: "" # Optional
# state: present # Optional: present or absent. Default to present
# user: "markus": # Group or User, not booth! # user: "markus": # Group or User, not booth!
+6 -9
View File
@@ -41,21 +41,18 @@
owner: "root" owner: "root"
group: "root" group: "root"
- name: Flush drop-in files of sudoers.d - name: Create drop-in directory of sudoers
ansible.builtin.file: ansible.builtin.file:
state: "{{ item }}" state: directory
path: "/etc/sudoers.d" path: "/etc/sudoers.d"
owner: "root" owner: "root"
group: "root" group: "root"
mode: "0750" mode: "0750"
with_items:
- absent
- directory
- name: "Create sudoers drop-in file to execute commands for specific unix users" - name: "Create sudoers drop-in file to execute commands for specific unix users"
community.general.sudoers: community.general.sudoers:
name: "{{ item.filename | default(item.user) }}" name: "{{ item.filename | default(item.user) }}"
state: present state: "{{ item.state | default('present') }}"
user: "{{ item.user }}" user: "{{ item.user }}"
nopassword: "{{ item.nopassword | default(false) }}" nopassword: "{{ item.nopassword | default(false) }}"
commands: "{{ item.commands | default('ALL') }}" commands: "{{ item.commands | default('ALL') }}"
@@ -68,7 +65,7 @@
- name: "Create sudoers drop-in file to execute commands for specific unix users as specific unix user" - name: "Create sudoers drop-in file to execute commands for specific unix users as specific unix user"
community.general.sudoers: community.general.sudoers:
name: "{{ item.filename | default(item.user) }}" name: "{{ item.filename | default(item.user) }}"
state: present state: "{{ item.state | default('present') }}"
user: "{{ item.user }}" user: "{{ item.user }}"
runas: "{{ item.runas }}" runas: "{{ item.runas }}"
nopassword: "{{ item.nopassword | default(false) }}" nopassword: "{{ item.nopassword | default(false) }}"
@@ -82,7 +79,7 @@
- name: "Create sudoers drop-in file to execute commands for specific unix groups" - name: "Create sudoers drop-in file to execute commands for specific unix groups"
community.general.sudoers: community.general.sudoers:
name: "{{ item.filename | default(item.group) }}" name: "{{ item.filename | default(item.group) }}"
state: present state: "{{ item.state | default('present') }}"
group: "{{ item.group }}" group: "{{ item.group }}"
nopassword: "{{ item.nopassword | default(false) }}" nopassword: "{{ item.nopassword | default(false) }}"
commands: "{{ item.commands | default('ALL') }}" commands: "{{ item.commands | default('ALL') }}"
@@ -95,7 +92,7 @@
- name: "Create sudoers drop-in file to execute commands for specific unix groups as specifix unix user" - name: "Create sudoers drop-in file to execute commands for specific unix groups as specifix unix user"
community.general.sudoers: community.general.sudoers:
name: "{{ item.filename | default(item.group) }}" name: "{{ item.filename | default(item.group) }}"
state: present state: "{{ item.state | default('present') }}"
group: "{{ item.group }}" group: "{{ item.group }}"
runas: "{{ item.runas }}" runas: "{{ item.runas }}"
nopassword: "{{ item.nopassword | default(false) }}" nopassword: "{{ item.nopassword | default(false) }}"