Passwordless Sudo with Ansible

Sudo without password, automatically. Short example role for ansible.

The role

  • creates a new user in "sudoless" group
  • adds a sudoers.d/ NOPASSWD rule for the group

Prerequisites

Applying this example file requires you to have Ansible working.

Tero's rule #1 for IaC: Manual before auto.

So it's a good idea to try creating passwordless sudo manually first.

Draft: This article has commands written from memory. It has not gone trough quality assuarance and testing yet.

Tree

$ tree -F
./
├── ansible.cfg
├── hosts.ini
├── roles/
│   ├── antero/
│   │   └── tasks/
│   │       └── main.yml
│   └── world/
│       └── tasks/
│           └── main.yml
└── site.yml

Role - antero

cat roles/antero/tasks/main.yml

- group:
    name: "sudoless"
    state: present
- user:
    name: "antero"
    state: present
    groups: ["sudoless", "sudo", "adm"]
- authorized_key:
    user: "antero"
    key: "ssh-ed25519 U2VlIHlvdSBhdCBUZXJvS2FydmluZW4uY29tIQ== tero@example.com"
- copy:
    dest: "/etc/sudoers.d/sudoless"
    content: "%sudoless ALL = (ALL) NOPASSWD: ALL\n"
    owner: "root"
    group: "root"
    mode: "0644"

First run - chicken or egg?

For the first run, you don't yet have sudo without password.

Let's make ansible try for sudo rights. Add "become: true" in the correct block in site.yml:

- hosts: all
  become: true
  roles:
    - world
    - antero
$ ansible-playbook site.yml

Now it should complain that sudo needs password. Ansible asks this with -K aka --ask-become-password.

$ ansible-playbook site.yml --ask-become-password

Tips

When you got it to work manually, you have your example. Copy it to automation!

  • Copy paste paths.
  • Copy files or file contents.
  • Use 'stat' to check for modes (permissions). Do not guess octal permissions, you have to understand them to avoid privesc worries.

Some IaC programs only reliably understand octal modes (numbers), and only as strings. I would also recommend explicit leading zero meaning no special permissions (no setgid...). So "0644", in quotes. Maybe it has improved over the years? Who knows.