Get user or group name from GID

I’m doing some user management tasks and use the ansible.builtin.getent module to gather information about the local groups on the systems. The module output is (if I’m not mistaken) a dictionary where they group name is the key and a list of group attributes is the value. I’d like to be able to get the group name by using the GID to “search” for it. However, this isn’t straightforward, since you need to know the key name to be able to access the value. Below is a snippet of the module output. I know that [*] can be used to access each item in a list. Is there something similar for dictionaries? I tried using the map('extract') filter, but wasn’t figure out how it works well enough. Maybe a different filter or module would be better. Open to suggestions.

ok: [localhost] => {
    "msg": {
        "_ssh": [
            "x",
            "114",
            ""
        ],
        "adm": [
            "x",
            "4",
            "syslog,user-1"
        ],
        "admin": [
            "x",
            "115",
            ""
        ],
        "audio": [
            "x",
            "29",
            "user-1
       ]

If you could post an example of the format of the results you want I’m sure someone will be able to suggest a method to achieve it.

Perhaps the results you can get from slurping the /etc/group files and parsing it with the jc group filter via the jc filter might be more like what you want?

- name: Slurp /etc/group
  ansible.builtin.slurp:
    src: /etc/group
  register: etc_group_b64encoded

- name: Set fact for groups
  ansible.builtin.set_fact:
    groups: "{{ etc_group_b64encoded['content'] | ansible.builtin.b64decode | community.general.jc('group') }}"

Note that you would need jc installed on the Ansible controller to do this.

Thanks, @chris. I hadn’t thought of using the slurp module. The jc filter does provide the data in a more straightforward structure (at least in my head). I’ll have to see if we can use it in our environment.

Another (more general) way to ask my question might be; Is there a way to access data inside a dictionary if the name of the dictionary key is unknown or there are multiple keys to look at?

1 Like

Yes, you can do it with native ansible filters.

Say you’ve one to get the user of ID 140

grep usb /etc/passwd
usbmux:x:140:140:usbmux user:/:/usr/bin/nologin

You can do something like that

---
- hosts: localhost
  tasks:
    - name: getent
      ansible.builtin.getent:
        database: passwd
      register: out
    - debug:
        var: out.ansible_facts.getent_passwd | dict2items | selectattr('value', 'search', '140') | map(attribute='key')

It will result in

TASK [debug] ***********************************************************************************************************
ok: [localhost] => {
    "out.ansible_facts.getent_passwd | dict2items | selectattr('value', 'search', '140') | map(attribute='key')": [
        "usbmux"
    ]
}

2 Likes

Excellent! This is what I was looking for. Thank you.

Do you have some good sources for working with map and selectattr that isn’t the Jinja documentation? I see these two used often in the Ansible documentation, but haven’t come across a list of available options, or really how to work with them outside of the examples.

map/select/reject are part of Jinja2 itself, not Ansible additions, we only document the latter.

Template Designer Documentation — Jinja Documentation (2.10.x)

I was asking if there was some documentation, guides, etc. that were outside the Jinja documentation, but not Ansible documentation. I understand that the these are not included in the Ansible documentation since they’re built into Jinja and are documented there. However, I have a difficult time wrapping my head around the Jinja documentation.