Skip to content

Instantly share code, notes, and snippets.

@halberom
Created May 17, 2017 09:35
Show Gist options
  • Save halberom/9bfe009c9a3df5d64c7bb505a7700430 to your computer and use it in GitHub Desktop.
Save halberom/9bfe009c9a3df5d64c7bb505a7700430 to your computer and use it in GitHub Desktop.
ansible - example of using map + regex_replace to modify all items in a list
---
- hosts: localhost
connection: local
gather_facts: False
vars:
mylist:
- group_1
- group_2
tasks:
- debug:
msg: "{{ mylist | map('regex_replace', '(.*)', '\\1_foo') | list }}"
PLAY [localhost] **********************************************************************************************************************
TASK [debug] **************************************************************************************************************************
ok: [localhost] => {
"changed": false,
"msg": [
"group_1_foo",
"group_2_foo"
]
}
PLAY RECAP ****************************************************************************************************************************
localhost : ok=1 changed=0 unreachable=0 failed=0
@Infiniverse
Copy link

The \ doesn't appear to make a difference. I tried '\', but that didn't happen.

Another approach should be:

    - debug: msg="YYY {{ groups['all'] | map('regex_replace', '(.*)', "hostvars[\1].ansible_ssh_host") | list }}"

which correctly outputs:

ok: [neptune] => {
    "changed": false, 
    "msg": "YYY [u'hostvars[unifi-controller-office].ansible_ssh_host', u'hostvars[neptune].ansible_ssh_host']"
}

So the question is, how do we evaluate those strings to get them replaced by the variable values.

@halberom
Copy link
Author

this is a method for modifying all items in a list, it's not suitable for pulling out elements from a nested structure.

As pointed out in chan,

{{ groups['all'] | map('extract', hostvars, 'ansible_ssh_host' }}

is the way to do that

@ReSearchITEng
Copy link

if you need to both add a prefix and a suffix, as well as making everything a list, take a look at the below:

  set_fact:
    extended_etcd_endpoints_list: "{{ groups['etcd'] | map('extract', hostvars, ['ansible_default_ipv4','address']) | map('regex_replace', '^(.*)$','https://\\1:2379') | list  }}"

it takes the list of all machines in the group etcd, extracts the ipv4, adds an 'https://' in front and an ':2379' at the end.
Finally, everything is transformed in a list.

@gobenji
Copy link

gobenji commented Mar 13, 2020

Indeed, I got strange results if the regex was not achored at the beginning: "^..."
Other than that, thanks for this useful pattern.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment