Turgon37.sudoers
Ansible Role Sudo/Sudoers
 
 
Description
⚠️ Warning: Before using this role, please note that all my Ansible roles are tailored to my IT environment. They might not fit your needs perfectly, so I recommend reviewing their functions and assessing their secure installation on your servers.
This role sets up sudo.
Requirements
- Ansible version must be 2.4 or higher.
Dependencies
Operating Systems Supported
This role works on Debian and CentOS.
Features
Currently, this role can:
- Install sudo.
- Set default configurations and command rules.
- Provide a way to add additional sudo rules from other roles.
- Use local facts.
Configuration
Role
All variables that can be changed are stored in the defaults/main.yml file as well as in the table below. For default values, refer to the file.
| Name | Types/Values | Description | 
|---|---|---|
| sudoers__sss | Boolean | Install necessary packages for sudo with SSS backend | 
| sudoers__defaults_(global/group/host) | List of dict/string | Set default settings for sudoers at the role level | 
| sudoers__purge | Boolean | If true, removes all sudo rules not managed by this role | 
| sudoers__ansible_managed_key | String | Identifies which sudo rules are managed by Ansible | 
| sudoers__rules_(global/group/host) | Dict of rules | Sudoers rules to apply at the role level | 
Sudo Rule
This role allows you to create a set of sudo rules from another role, outside of this sudoers role.
To use it, declare a task like so:
- name: Configure sudoers rule for ROLE
  include_role:
    name: sudoers
    tasks_from: types/sudo_rule
  vars:
    sudoers__sudo_rule: {}
All rule items must be under the variable sudoers__sudo_rule.
| Name | Types/Values | Description | 
|---|---|---|
| name | String | Name of the rule file (no spaces allowed) | 
| state | Enum absent/present | Indicates whether to remove the rule if needed | 
| defaults | List of defaults | List of sudoers 'defaults' settings to apply | 
| users | List of string | Users to whom this rule applies | 
| hosts | List of string | Optional hosts for this rule; defaults to ALL | 
| commands | List of commands | Command definitions | 
| comment | String | Optional comment to add to the file | 
"defaults" Directive
The sudo "defaults" directive can accept optional values. Ansible supports two forms for each defaults directive under the defaults key:
Defaults   always_set_home
Defaults   listpw = always
- A simple string.
- A mapping.
The string version is simpler, as it follows the sudo keyword directly. The mapping supports more detailed setups, allowing filtering based on host, user, command, or runas. You can only choose one filter condition per default directive.
If the directive needs a value, set the directive name as a key in the mapping, with its value as the corresponding value. If a directive only requires its name (like requiretty), use "defaults" as the key and the directive name as the value.
For instance, to set requiretty for user1, set the following vars:
sudoers__sudo_rule:
  name: rule1
  defaults:
    - defaults: requiretty
      user: user1
And for listpw, use:
sudoers__sudo_rule:
  name: rule1
  defaults:
    - listpw: always
      user: user1
Here are the available keys for a defaults specification:
| Name | Usage | 
|---|---|
| defaults: NAME | For directives with no value | 
| NAME: VALUE | For directives that require a value | 
| host: HOST | Restricts Defaults to specific host | 
| user: USER | Restricts Defaults to specific user | 
| command: COMMAND | Restricts Defaults to specific command | 
| runas: RUNAS_USER | Restricts Defaults to specific runas user | 
"commands" Directive
Each command under the commands key allows users to run commands, with or without restrictions.
A command block can contain the following keys:
| Name | Types/Values | Usage | 
|---|---|---|
| commands: | String or list of string | Command pattern(s), see man 5 sudoers for syntax | 
| run_as_user: | String or list of string | This/these commands must be run as this/these user(s) | 
| run_as_group: | String or list of string | This/these commands must be run as this/these group(s) | 
| tags | String or list of string | Tag or list of tags to apply to this command | 
For example, to allow user "user1" to run ls anywhere as root without needing a password:
sudoers__sudo_rule:
  name: rule1
  commands:
   - commands: /bin/ls
     run_as_user: user1
     run_as_group: root
     tags: NOPASSWD
Facts
By default, local facts are created and expose the following variables:
- ansible_local.sudoers.version_full
- ansible_local.sudoers.version_major
Example
Playbook
Use this in a playbook like this:
- hosts: all
  roles:
    - turgon37.sudoers
Inventory
- Set your default settings:
sudoers__defaults_global:
  - always_set_home
  - insults
  - listpw: always
  - mailsub: "[PRODUCTION][%h][SUDO SECURITY]"
  - mailto: [email protected]
  - mail_no_user
  - mail_no_perms
  - mail_no_host
  - mail_badpass
  - passprompt_override
  - pwfeedback
  - secure_path: /sbin:/bin:/usr/sbin:/usr/bin:/usr/local/sbin:/usr/local/bin
  - '!visiblepw'
- Use with sssd:
# Required for sudo to retrieve rules from LDAP
sudoers__sss: true
- Define sudo rules from another role:
- name: Configure sudoers rule for ROLE
  include_role:
    name: sudoers
    tasks_from: types/sudo_rule
  vars:
    sudoers__sudo_rule:
      name: role__autogenerated_rule_10
      remove_using_regexp:
        - role__autogenerated_rule_0[0-9]+
      force_remove_using_regexp: true
      users: '{{ role__user }}'
      hosts: ALL
      comment: Autogenerated rule for role
      commands:
        - commands: /bin/ls
          run_as_user: '{{ role__another_user }}'
          run_as_group: root
          tags: NOPASSWD
        - commands: /bin/cat /home/[a-zA-Z]*/.ssh/config
          run_as_user: ALL
          run_as_group: root
      defaults:
        - defaults: '!requiretty'
          user: '{{ role__user }}'
      state: present
ansible-galaxy install Turgon37.sudoers