Dimon
(Dimon)
June 4, 2014, 9:47pm
1
Hi,
I’ve got a usecase where I’d like to iterate over several servers based on groups, so task looks like:
name: group A & B
shell: echo {{ item }} >> /tmp/log
with_items:
groups[“A”]
groups[“B”]
so what I get in /tmp/log is:
groups[‘A’]
groups[‘B’]
Now, eliminating either group I can get:
name: group A
shell: echo {{ item }} >> /tmp/log
with_items: groups[“A”]
I get proper result.
I’m pretty certain I’ve seen this topic come up recently but can’t find it anymore. Any pointers (including links to other topics) are welcome.
P.S.
for bonus points - can I do set-like concatenation - i.e. eliminate duplicates?
adam2
June 4, 2014, 9:50pm
2
ansible uses jinga2. Look up that syntax. Then, off the top of my head, may not be exactly right, but:
groups["A"].concat(groups["B"]) | set | list
Some of that is python syntax(the contact, check jinga2 and python docs), and the |set|list is jinga2.
Dimon
(Dimon)
June 4, 2014, 9:57pm
3
nice try - but no dice:
fatal: [192.168.0.138] => with_items expects a list or a set
FATAL: all hosts have already failed – aborting
I even played a bit and checked python syntax making it:
groups[‘A’].extend(groups[‘B’])|set
with or without last “list” filter with original syntax or with my “correction” it fails as per above. -vvvv doesn’t help much to pinpoint where the problem is.
Dimon
(Dimon)
June 4, 2014, 10:01pm
4
thanks to your hint I’m one step closer:
name: group A & B
shell: echo {{ item }} >> /tmp/log
with_items: groups[“A”] + groups[“B”]
however I still can’t figure out how to make a “set” out of the result.
sivel
(sivel)
June 4, 2014, 10:02pm
5
You might want to take a look at the ‘set’ filters provided by ansible at http://docs.ansible.com/playbooks_variables.html#set-theory-filters
I imagine something like:
with_items: groups[‘A’]|union(groups[‘B’])|unique
would work.
I doubt it is needed, but you might have to add |list onto the end of that.
I think jinja2 addition may also work:
with_items: (groups[‘A’] + groups[‘B’])|unique
Dimon
(Dimon)
June 4, 2014, 10:17pm
6
Thanks Matt and Adam!
Winning combination turned out to be:
( groups[‘A’]+groups[‘B’] ) | unique
I do like how simple it looks vs
( groups[‘A’]|union (groups[‘B’]))| unique
since in my case I have more groups to add and it is very simple with “+” and less error-prone.
Excerpts from Dmitry Makovey's message of 2014-06-04 18:17:04 -0400:
Winning combination turned out to be:
( groups['A']+groups['B'] ) | unique
I do like how simple it looks vs
( groups['A']|union (groups['B']))| unique
Just FYI, the 'unique filter in the latter form is redundant; this
should work fine:
groups['A']|union(groups['B')
Sets, by definition, have no duplicate items.
The first problem here is not about sets or unions or anything.
The issue is with_items wants a single list to walk over, not a list of two lists.
So
with_items: variable_ame
works
as does
with_items:
With hard coded strings
But if you want to walk two lists, that’s “with_nested”.
Here, though you do want to add them together.
I just wanted to mention why you were seeing “groups[“A”]” literally in the first logfile above.