1

I'm writing an Ansible script to automatically add users to servers. The first step is uses the URI module to make a rest call to an intranet server to pull the public key for each user, which is stored in user_keys dict

Now I want to loop over user_keys.results and for each element apply a regex to to the key (ie item.content) to find the uid of the user. The uid is in the key and can be found with the regex 'unixid=\d+'

However, I'm struggling to get this to work.

I know I can use combine to append to the item array, and that I can use regex_search to do a search on item.content. However, I can't seem to combine the two in one command. In fact even this simpler test fails:

- name: set key for user
  set_fact:
    item: "{{ item | combine({'key: {{item.content}} }) }}
  with_items: "{{ user_keys.results }}"

Though the similar command:

- name: set key for user
  set_fact:
    item: "{{ item | combine({'key: 'dummy_key' }) }}
  with_items: "{{ user_keys.results }}"

works fine. That suggests that Ansible doesn't like my nesting variable references (ie no recursive uses of the {{ }} sections). But given that how can I pull out the uid from the key and save it so I can use it in future commands?

I'm using ansible 2.10.9

β.εηοιτ.βε
  • 33,893
  • 13
  • 69
  • 83
dsollen
  • 6,046
  • 6
  • 43
  • 84
  • Does this answer your question? [How can I make Ansible interpret a variable inside a variable?](https://stackoverflow.com/questions/67408680/how-can-i-make-ansible-interpret-a-variable-inside-a-variable) – β.εηοιτ.βε May 26 '21 at 19:40
  • 1
    Also mind that you are also have a typo with a quote in those two snippet, to close the key of name `key`: `item: "{{ item | combine({'key: item.content }) }}` should be `item: "{{ item | combine({'key': item.content }) }}` – β.εηοιτ.βε May 26 '21 at 19:42
  • @β.εηοιτ.βε that confirms what I suspected was the issue. It still doesn't tell me how I can do what I want. None of the suggestsions listed would help me to utilize combine and regex_search together in the same task. – dsollen May 26 '21 at 20:41
  • Another problem is that you cannot alter the current item in a loop. If I read that correctly between the lines. The best you can do here would be to create another list. – β.εηοιτ.βε May 26 '21 at 20:43

1 Answers1

1

You cannot act on item in the course of a loop.
Or at least it wouldnt do what you expect, meaning: it won't change the current item you are looping on, it will just set a global scope variable named item that you will override over and over as you loop your user_keys.results list.

The best here would be to recreate a new list.

For example with the playbook:

- hosts: localhost
  gather_facts: no

  tasks:
    - set_fact: 
        new_user_keys: >-
          {{ 
            new_user_keys | default([]) + 
            [item | combine({'key': item.content | regex_findall('unixid=(\d+)', '\\1') | first})] 
          }}
      loop: "{{ user_keys.results }}"
      vars:
        user_keys:
          results:
           - content: 000 foo unixid=123 bar 987
             changed: true
             rc: 0
             etc: etc, etc, ...
           - content: 000 foo unixid=456 bar 987
             changed: true
             rc: 0
             etc: etc, etc, ...
           - content: 000 foo unixid=789 bar 987
             changed: true
             rc: 0
             etc: etc, etc, ...

    - debug:
        var: new_user_keys

We end with the recap:

PLAY [localhost] **************************************************************************************************

TASK [set_fact] ***************************************************************************************************
ok: [localhost] => (item={'content': '000 foo unixid=123 bar 987', 'changed': True, 'rc': 0, 'etc': 'etc, etc, ...'})
ok: [localhost] => (item={'content': '000 foo unixid=456 bar 987', 'changed': True, 'rc': 0, 'etc': 'etc, etc, ...'})
ok: [localhost] => (item={'content': '000 foo unixid=789 bar 987', 'changed': True, 'rc': 0, 'etc': 'etc, etc, ...'})

TASK [debug] ******************************************************************************************************
ok: [localhost] => 
  new_user_keys:
  - changed: true
    content: 000 foo unixid=123 bar 987
    etc: etc, etc, ...
    key: '123'
    rc: 0
  - changed: true
    content: 000 foo unixid=456 bar 987
    etc: etc, etc, ...
    key: '456'
    rc: 0
  - changed: true
    content: 000 foo unixid=789 bar 987
    etc: etc, etc, ...
    key: '789'
    rc: 0

PLAY RECAP ********************************************************************************************************
localhost                  : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
β.εηοιτ.βε
  • 33,893
  • 13
  • 69
  • 83