Skip to content

Add role for configuring sudoers groups #709

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions ansible/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -90,3 +90,5 @@ roles/*
!roles/gateway/**
!roles/alertmanager/
!roles/alertmanager/**
!roles/sudoers/
!roles/sudoers/**
9 changes: 9 additions & 0 deletions ansible/extras.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,15 @@
- import_role:
name: basic_users

- hosts: sudoers:!builder
become: true
tags: sudoers
gather_facts: yes
tasks:
- name: Configure sudoers
import_role:
name: sudoers

- name: Setup EESSI
hosts: eessi
tags: eessi
Expand Down
65 changes: 65 additions & 0 deletions ansible/roles/sudoers/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
# sudoers

Manage sudoers configuration by creating files in `/etc/sudoers.d/`.

## Role Variables

- `sudoers_groups`: Required list. A list of dictionaries defining sudo group configurations. Each dictionary should contain:
- `group`: Required string. The group name to grant sudo privileges to.
- `commands`: Required string. The sudo commands specification (e.g., "ALL=(ALL) ALL").
- `state`: Optional string. Either "present" (default) or "absent" to remove the configuration.
Comment on lines +8 to +10
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add more indentation to these lines.


## Features

- Creates individual sudoers files for each group in `/etc/sudoers.d/`
- Validates sudoers syntax using `visudo -cf` before applying
- Sanitizes group names by replacing spaces and slashes with underscores for filename safety
- Supports removing sudoers configurations by setting `state: absent`
- Sets proper permissions (0440) and ownership (root:root) on sudoers files

## Dependencies

None.

## Example Playbook

```yaml
- hosts: servers
become: yes
roles:
- role: sudoers
vars:
sudoers_groups:
- group: SITE_Admins
commands: "ALL=(ALL) ALL"
- group: SITE_Users
commands: "ALL=(ALL) ALL"
- group: developers
commands: "ALL=(ALL) NOPASSWD: /usr/bin/systemctl restart myapp"
- group: old_group
state: absent
```

## Example Variables

```yaml
# Merge your existing groups like this:
sudoers_groups: "{{ sudo_groups + management_sudo_groups }}"

# Where you have:
sudo_groups:
- group: SITE_Users
commands: "ALL=(ALL) ALL"

management_sudo_groups:
- group: SITE_Admins
commands: "ALL=(ALL) ALL"
```

## License

Apache v2

## Author Information

StackHPC Ltd.
20 changes: 20 additions & 0 deletions ansible/roles/sudoers/defaults/main.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
---
# Default variables for sudoers role

# List of sudo groups to configure
# Each item should have:
# - group: the group name (required)
# - commands: the sudo commands specification (required)
# - state: present (default) or absent (optional)
sudoers_groups: []

# Example:
# sudoers_groups:
# - group: SITE_Admins
# commands: "ALL=(ALL) ALL"
# - group: SITE_Users
# commands: "ALL=(ALL) ALL"
# - group: developers
# commands: "ALL=(ALL) NOPASSWD: /usr/bin/systemctl restart myapp"
# - group: old_group
# state: absent
24 changes: 24 additions & 0 deletions ansible/roles/sudoers/tasks/main.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
---
- name: Configure sudoers files
template:
src: sudoers.j2
dest: /etc/sudoers.d/{{ item.group | replace(' ', '_') | replace('/', '_') }}
owner: root
group: root
mode: '0440'
validate: 'visudo -cf %s'
become: true
with_items: "{{ sudoers_groups }}"
when:
- sudoers_groups is defined
- sudoers_groups | length > 0

- name: Remove sudoers files for absent groups
file:
path: /etc/sudoers.d/{{ item.group | replace(' ', '_') | replace('/', '_') }}
state: absent
become: true
with_items: "{{ sudoers_groups }}"
when:
- sudoers_groups is defined
- item.state | default('present') == 'absent'
1 change: 1 addition & 0 deletions ansible/roles/sudoers/templates/sudoers.j2
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
%{{ item.group }} {{ item.commands }}
3 changes: 3 additions & 0 deletions environments/common/inventory/groups
Original file line number Diff line number Diff line change
Expand Up @@ -182,3 +182,6 @@ extra_packages

[gateway]
# Add builder to this group to install gateway ansible-init playbook into image

[sudoers]
# Hosts to configure sudoers groups
3 changes: 3 additions & 0 deletions environments/common/layouts/everything
Original file line number Diff line number Diff line change
Expand Up @@ -125,3 +125,6 @@ builder
[gateway:children]
# Add builder to this group to install gateway ansible-init playbook into image
builder

[sudoers]
# Hosts to configure sudoers groups
Loading