1

In ansible if there is list of host names with fully qualified domain name:

 "groups[group_names[0]]": [
        "node1.in.labs.corp.netin",
        "node2.in.labs.corp.netin"
    ]

How to obtain only node names from these strings? Say , answer list should have only these entries:

[node1 , node2]

Tried using map and split operation, But it does not seem to work.It fails saying split operation is not defined for map.

msg={{ groups[group_names[0]] | map('split','@') | flatten }}

Is there any other way ? Thank you in advance.


I tried using regex_replace option this way:

Here groups[group_names[0]] is list of node names

 "groups[group_names[0]]": [
        "node1.in.labs.corp.netin",
        "node2.in.labs.corp.netin"
    ]
- set_fact:
      groups[group_names[0]]={{ groups[group_names[0]] |
                   map('regex_replace', _regex, _replace)|list }}
  vars:
    _regex: '^(.*?)\.(.*)$'
    _replace: '-n \1'

Hitting the following error line:

{"changed": false, "msg": "The variable name 'groups[group_names[0]]' is not valid. Variables must start with a letter or underscore character, and contain only letters, numbers and underscores."}

Can i assign back to same list ? after replacing the regex ? Also -n option is using so that my expected output should be

-n node1 -n node2

Pooja G
  • 41
  • 1
  • 14
  • You added a different problem ``"The variable name 'groups[group_names[0]]' is not valid"``. Delete it and open a new question instead. – Vladimir Botka Feb 17 '22 at 13:32
  • https://stackoverflow.com/questions/71159207/ansible-use-regex-replace-for-items-in-list-and-assign-it-back – Pooja G Feb 17 '22 at 13:39

2 Answers2

3

If you're not running Ansible 2.11 or above, the split jinja filter won't work

but you can still do {{ var.split('-').0 }} and avoid ugly regexes

Pedro
  • 416
  • 1
  • 8
  • 24
1

Given the data

  my_groups:
    group_names:
      - ["node1.in.labs.corp.netin", "node2.in.labs.corp.netin"]

the expression below does the job

  nodes: "{{ my_groups.group_names.0|map('split', '.')|map('first')|list }}"

gives

  nodes:
  - node1
  - node2

The next option is to use regex_replace, for example, the task below gives the same result

    - set_fact:
        nodes: "{{ my_groups.group_names.0|
                   map('regex_replace', _regex, _replace)|list }}"
      vars:
        _regex: '^(.*?)\.(.*)$'
        _replace: '\1'
Vladimir Botka
  • 58,131
  • 4
  • 32
  • 63
  • Thank you for reply. It did not work. I am using ansible 2.9.27 version . An exception occurred during task execution. To see the full traceback, use -vvv. The error was: jinja2.exceptions.TemplateRuntimeError: no filter named 'split' – Pooja G Feb 17 '22 at 11:34
  • I see. [split as a function](https://docs.ansible.com/ansible/latest/user_guide/playbooks_filters.html#manipulating-strings) is available since 2.11. Are you able to upgrade? The last 3 versions (atm 2.12, 2.11, and 2.10) are supported. – Vladimir Botka Feb 17 '22 at 11:39
  • Upgrading to 2.10 is also fine ? Is there any other way that i could handle in 2.9 ? – Pooja G Feb 17 '22 at 11:56
  • Unfortunately, 2.10 is not enough. When you take a look at the link above you'll see that ``split`` as a filter was ``New in version 2.11.`` – Vladimir Botka Feb 17 '22 at 12:00
  • if i use 2.11 , i get following errors for this piece of code `- name: Copy the ISO to nodes synchronize: src: "{{ iso_location }}" dest: "{{ dest_iso_path }}" rsync_timeout: 60 ` "couldn't resolve module/action 'synchronize'. This often indicates a misspelling, missing collection, or incorrect module path – Pooja G Feb 17 '22 at 12:09
  • See [How do comments work?](https://meta.stackexchange.com/questions/19756/how-do-comments-work) and the part "What are comments for, and when shouldn't I comment?". I added the *regex_replace* option. – Vladimir Botka Feb 17 '22 at 12:24
  • Added my next try in the question itself. Thank you @vladimir – Pooja G Feb 17 '22 at 13:24