Ansible: Lookup group name by gid

Posted by ads' corner on Sunday, 2022-06-12
Posted in [Ansible]

For one of my Ansible Playbooks I need the group name associated with a specific group id. Turns out there is not much documentation online how to do this, and I had to test it out.

To create a simple example (not the one in my Playbook, which is more complex), I start with a getent passwd entry for a user:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
- name: Get current user
  command: "whoami"
  register: whoami
  become: no

- name: Get passwd entry for login user
  getent:
    database: passwd
    key: "{{ whoami.stdout }}"
  become: no

After running this, the variable $ansible_facts.getent_passwd holds the entry for whatever username is logged in. Since I add become:no, this will use the login username and not root in case this Playbook runs under become: yes.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
- debug: msg="{{ ansible_facts.getent_passwd }}"

TASK [debug] *************
ok: [xxx.xxx.xxx.xxx] => {
    "msg": {
        "ubuntu": [
            "x",
            "1000",
            "1000",
            "Ubuntu",
            "/home/ubuntu",
            "/bin/bash"
        ]
    }
}

Using $ansible_facts.getent_passwd[whoami.stdout][2] gives me the gid: 1000. This can be used for another getent call, this time for the group database:

1
2
3
4
5
- name: Get group
  getent:
    database: group
    split: ':'
    key: "{{ ansible_facts.getent_passwd[whoami.stdout][2] }}"

More debugging:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
- debug: msg="{{ ansible_facts.getent_passwd }}"

TASK [debug] *************
ok: [xxx.xxx.xxx.xxx] => {
    "ansible_facts.getent_group": {
        "ubuntu": [
            "x",
            "1000",
            ""
        ]
    }
}

More tests

The default user on Ubuntu (ubuntu) has both uid=1000 and gid=1000, there is a slight chance my above Playbook is doing something wrong.

Therefore I looked up some more gid’s:

1
2
3
4
adm:x:4:syslog,ubuntu
tty:x:5:
disk:x:6:
tape:x:26:

And tried finding the groups by gid:

1
2
3
4
5
- name: Get group
  getent:
    database: group
    split: ':'
    key: "4"
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
TASK [debug] *************
ok: [xxx.xxx.xxx.xxx] => {
    "msg": {
        "adm": [
            "x",
            "4",
            "syslog,ubuntu"
        ]
    }
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
TASK [debug] *************
ok: [xxx.xxx.xxx.xxx] => {
    "msg": {
        "tty": [
            "x",
            "5",
            ""
        ]
    }
}

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
TASK [debug] *************
ok: [xxx.xxx.xxx.xxx] => {
    "msg": {
        "disk": [
            "x",
            "6",
            ""
        ]
    }
}

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
TASK [debug] *************
ok: [xxx.xxx.xxx.xxx] => {
    "msg": {
        "tape": [
            "x",
            "26",
            ""
        ]
    }
}

And I tried looking up groups by name:

1
2
3
4
5
- name: Get group
  getent:
    database: group
    split: ':'
    key: "tape"
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
TASK [debug] *************
ok: [xxx.xxx.xxx.xxx] => {
    "msg": {
        "tape": [
            "x",
            "26",
            ""
        ]
    }
}

Retrieving the name

As you might have seen, the $ansible_facts.getent_group variable returns a dict, not a list. If I don’t know the name, how do I access the entry in the dictionary?

first will help:

1
2
3
4
5
6
7
- debug: msg="{{ ansible_facts.getent_group | first }}"

TASK [debug] *************
ok: [xxx.xxx.xxx.xxx] => {
    "msg": "ubuntu"
}

Summary

getent/group can lookup entries by both name and id. That’s not mentioned in the documentation:

Key from which to return values from the specified database, otherwise the full contents are returned.

Nice to know that key refers to both the group name and the group id here.


Categories: [Ansible]
Tags: [Ansible] [Json]