18

I'm trying to retrieve the group ID of two groups (syslog and utmp) by name using an Ansible task. For testing purposes I have created a playbook to retrieve the information from the Ansible host itself.

---
- name: My playbook
  hosts: enabled
  sudo: True
  connection: local
  gather_facts: False
  tasks:
    - name: Determine GIDs
      shell: "getent group {{ item }} | cut -d : -f 3"
      register: gid_{{item}}
      failed_when: gid_{{item}}.rc != 0
      changed_when: false
      with_items:
        - syslog
        - utmp

Unfortunately I get the following error when running the playbook:

fatal: [hostname] => error while evaluating conditional: gid_syslog.rc != 0

How can I consolidate a task like this one into a parametrized form while registering separate variables, one per item, for later use? So the goal is to have variables based on the group name which can then be used in later tasks.

I'm using the int filter on gid_syslog.stdout and gid_utmp.stdout to do some calculation based on the GID in later tasks.


I also tried using gid.{{item}} and gid[item] instead of gid_{{item}} to no avail.


The following works fine in contrast to the above:

---
- name: My playbook
  hosts: enabled
  sudo: True
  connection: local
  gather_facts: False
  tasks:
    - name: Determine syslog GID
      shell: "getent group syslog | cut -d : -f 3"
      register: gid_syslog
      failed_when: gid_syslog.rc != 0
      changed_when: false
    - name: Determine utmp GID
      shell: "getent group utmp | cut -d : -f 3"
      register: gid_utmp
      failed_when: gid_utmp.rc != 0
      changed_when: false

2 Answers 2

14

Set fact supports variables, as opposed to the previous solution's statement

- set_fact:
    "{{ item.name }}": "{{ item.val }}"
  when: item.name not in vars           # this is optional. prevents overwriting vars
  with_items:
    - { name: test, val: myalue }
    - { name: notest, val: novalue }
2
  • 1
    I would give it +10 if I could! :)
    – Vano
    Commented Apr 6, 2020 at 20:09
  • 1
    This right here just made my life so much easier! Commented Jan 26, 2022 at 17:23
8

I suppose there's no easy way for that. And register with with_items loop just puts all results of them into an array variable.results. Try the following tasks:

  tasks:
    - name: Determine GIDs
      shell: "getent group {{ item }} | cut -d : -f 3"
      register: gids
      changed_when: false
      with_items:
        - syslog
        - utmp
    - debug:
        var: gids
    - assert:
        that:
          - item.rc == 0
      with_items: gids.results
    - set_fact:
        gid_syslog: "{{gids.results[0]}}"
        gid_utmp: "{{gids.results[1]}}"
    - debug:
        msg: "{{gid_syslog.stdout}} {{gid_utmp.stdout}}"

You can, however, use variable expansion in set_fact keys like this:

    - set_fact:
        "gid_{{item.item}}": "{{item}}"
      with_items: gids.results
2
  • Thanks, I'll try it out, but it's unlikely I'd put that solution as it is longer and more convoluted than even the one were I duplicate everything (at the bottom of my question). Readability is one of the strengths of Ansible otherwise, so working around that will come back to bite me :) Commented Jun 11, 2015 at 7:10
  • 2
    Set fact supports variables, as opposed to the previous solution's statement, see answer below
    – Vano
    Commented Apr 6, 2020 at 20:08

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .