<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>howto Archives - Tailored Cloud</title>
	<atom:link href="https://tailored.cloud/tag/howto/feed/" rel="self" type="application/rss+xml" />
	<link>https://tailored.cloud/tag/howto/</link>
	<description>Kubernetes, devops and everything cloud</description>
	<lastBuildDate>Thu, 24 May 2018 17:40:23 +0000</lastBuildDate>
	<language>en-GB</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.6</generator>
	<item>
		<title>How to filter, join and map lists in Ansible</title>
		<link>https://tailored.cloud/devops/how-to-filter-and-map-lists-in-ansible/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=how-to-filter-and-map-lists-in-ansible</link>
					<comments>https://tailored.cloud/devops/how-to-filter-and-map-lists-in-ansible/#respond</comments>
		
		<dc:creator><![CDATA[tc-admin]]></dc:creator>
		<pubDate>Sun, 31 Dec 2017 14:46:25 +0000</pubDate>
				<category><![CDATA[devops]]></category>
		<category><![CDATA[ansible]]></category>
		<category><![CDATA[howto]]></category>
		<guid isPermaLink="false">http://localhost:8080/?p=230</guid>

					<description><![CDATA[<p>TL;DR use &#8220;select&#8221; filter to filter a list and &#8220;match&#8221; to combine it with reg exps, like: use &#8220;map&#8221; to <a class="more-link" href="https://tailored.cloud/devops/how-to-filter-and-map-lists-in-ansible/">Continue Reading</a></p>
<p>The post <a href="https://tailored.cloud/devops/how-to-filter-and-map-lists-in-ansible/">How to filter, join and map lists in Ansible</a> appeared first on <a href="https://tailored.cloud">Tailored Cloud</a>.</p>
]]></description>
										<content:encoded><![CDATA[<h1>TL;DR</h1>
<ul>
<li style="list-style-type: none;">
<ul>
<li>use <a href="http://jinja.pocoo.org/docs/2.10/templates/#select">&#8220;select&#8221;</a> filter to filter a list and &#8220;match&#8221; to combine it with reg exps, like:
<pre class="brush: plain; title: ; notranslate">&quot;{{ ansible_interfaces | select('match', '^(eth|wlan)&#x5B;0-9]+') | list }}&quot;</pre>
</li>
<li>use <a href="http://jinja.pocoo.org/docs/2.10/templates/#map">&#8220;map&#8221;</a> to map list elements, like:
<pre class="brush: plain; title: ; notranslate">&quot;{{ ansible_interfaces | map('upper') | list }}&quot;</pre>
</li>
<li>use just &#8220;+&#8221; operator to combine two lists into one, like:
<pre class="brush: plain; title: ; notranslate">&quot;{{ ansible_interfaces + &#x5B;\&quot;VETH-1\&quot;, \&quot;VETH-2\&quot;] }}&quot;</pre>
</li>
</ul>
</li>
</ul>
<ul>
<li style="list-style-type: none;">
<ul>
<li>check here for more advanced example: <a href="http://localhost:8080/devops/advanced-list-operations-ansible/">Advanced list operations in Ansible</a></li>
</ul>
</li>
</ul>
<h1>Ansible filters and lists operators</h1>
<p><img fetchpriority="high" decoding="async" class="alignleft size-full wp-image-277" src="https://localhost:8080/wp-content/uploads/2017/12/ansible.png" alt="" width="225" height="225" srcset="https://tailored.cloud/wp-content/uploads/2017/12/ansible.png 225w, https://tailored.cloud/wp-content/uploads/2017/12/ansible-150x150.png 150w" sizes="(max-width: 225px) 100vw, 225px" /><a href="http://docs.ansible.com/">Ansible</a> provides a rich set of filters, which you can apply to your variables. Recently, I needed to filter and map a list of host interfaces. I couldn&#8217;t remind myself how to do this, so I jumped to <a href="http://docs.ansible.com/ansible/latest/playbooks_filters.html">ansible filters docs</a>. But I couldn&#8217;t find it there. Well, you have to remember, that expression evaluation in Ansible is based on Jinja2, so you need to check <a href="http://jinja.pocoo.org/docs/2.10/templates/#builtin-filters">Jinja2 filters documentation</a> as well. You will find basic operators there.</p>
<p>When operating on lists, functional languages are a great example: by combining just a few list operators, you can get almost any desired transformation of the list. These basic operators include:</p>
<ul>
<li>filter &#8211; to select just matching elements from the list and create a new list from them</li>
<li>map &#8211; to convert all elements on the list according to transformation function that operates on a single element</li>
<li>reduce &#8211; to convert (aggregate) all elements of a list into a single value</li>
<li>flat map &#8211; to merge multiple lists into a single list</li>
</ul>
<p>Let&#8217;s now see how to perform them in Ansible 2.4.</p>
<h2>Our example &#8211; list all network interfaces</h2>
<p>As our example list we want to transform in ansible, let&#8217;s use a list of local network interfaces that Ansible discovers during setup and stores in &#8220;ansible_interfaces&#8221; list. A simple play that just fetches and prints the list can look like this:</p>
<pre class="brush: yaml; title: ; notranslate">
- hosts: all
  tasks:
    - name: print interfaces
      debug:
        msg: &quot;{{ ansible_interfaces }}&quot;
</pre>
<p>Let&#8217;s save the above code in file &#8216;list_operators.yml&#8217; and run it with:</p>
<pre class="brush: bash; title: ; notranslate">
ansible-playbook -c local -i 'localhost,' list_operators.yml
</pre>
<p>On my PC this produces the following output:</p>
<pre class="brush: plain; title: ; notranslate">
PLAY &#x5B;all] ****************************************************************

TASK &#x5B;Gathering Facts] ****************************************************
ok: &#x5B;localhost]

TASK &#x5B;print interfaces] ***************************************************
ok: &#x5B;localhost] {
    &quot;msg&quot;: &#x5B;
        &quot;docker0&quot;, 
        &quot;lo&quot;, 
        &quot;veth3e8c318&quot;, 
        &quot;wlan0&quot;,
        &quot;eth0&quot;, 
        &quot;vethe2459c9&quot;
    ]
}

PLAY RECAP ****************************************************************
localhost                  : ok=2    changed=0    unreachable=0    failed=0
</pre>
<h2>Filter a list in Ansible</h2>
<p>Let&#8217;s assume we want to filter the interfaces list to include only &#8220;eth&#8221; or &#8220;wlan&#8221; types of interfaces. As you can find <a href="http://jinja.pocoo.org/docs/2.10/templates/#select">here in Jinja2</a> docs, we can use the &#8220;select&#8221; filter to filter the list. But the great thing &#8211; and not that easy to find &#8211; is that we can combine &#8220;select&#8221; with &#8220;match&#8221; operator to test for matching against a regular expression! This brings us to the following solution:</p>
<pre class="brush: yaml; title: ; notranslate">
- hosts: all
  tasks:
    - name: print interfaces
      debug:
        msg: &quot;{{ ansible_interfaces | select('match', '^(eth|wlan)&#x5B;0-9]+') | list }}&quot;
</pre>
<p>So, what it does is that it passes each element on the list &#8220;ansible_interfaces&#8221; to a &#8220;match&#8221; test. This test checks with the regexp if the element starts with &#8220;eth&#8221; or &#8220;wlan&#8221; followed by at least 1 digit. Elements that match are combined back again into a list with the &#8220;list&#8221; filter. The code above produces the following output:</p>
<pre class="brush: plain; title: ; notranslate">
TASK &#x5B;print interfaces] ***************************************************
ok: &#x5B;localhost] {
    &quot;msg&quot;: &#x5B;
        &quot;wlan0&quot;, 
        &quot;eth0&quot;
    ]
}
</pre>
<h2>Map list elements in Ansible</h2>
<p>OK, let&#8217;s now see how we can use the <a href="http://jinja.pocoo.org/docs/2.10/templates/#map">map filter</a> in Ansible. Let&#8217;s assume that we want to convert each interface name on our list to upper case only. Jinja2 <a href="http://jinja.pocoo.org/docs/2.10/templates/#upper">has a filter</a> for that, so our Ansible task becomes:</p>
<pre class="brush: yaml; title: ; notranslate">
- hosts: all
  tasks:
    - name: print interfaces
      debug:
        msg: &quot;{{ ansible_interfaces | map('upper') | list }}&quot;
</pre>
<p>and produces the following output:</p>
<pre class="brush: plain; title: ; notranslate">
TASK &#x5B;print interfaces] ***************************************************
ok: &#x5B;localhost] {
    &quot;msg&quot;: &#x5B;
        &quot;DOCKER0&quot;, 
        &quot;LO&quot;, 
        &quot;VETH3E8C318&quot;, 
        &quot;WLAN0&quot;, 
        &quot;DOCKERCON&quot;, 
        &quot;ETH0&quot;, 
        &quot;VETHE2459C9&quot;
    ]
}
</pre>
<h2>Merge two lists into one in Ansible</h2>
<p>Now, what if we want to merge two lists into a single one that contains elements of both of them? That&#8217;s really easy, as the normal &#8220;+&#8221; operator works for lists and does exactly that. So, running this code:</p>
<pre class="brush: yaml; title: ; notranslate">
- hosts: all
  tasks:
    - name: print interfaces
      debug:
        msg: &quot;{{ ansible_interfaces + &#x5B;\&quot;VETH-1\&quot;, \&quot;VETH-2\&quot;] }}&quot;
</pre>
<p>produces the following output, where the list of local interfaces is extended with elements &#8220;VETH-1&#8221; and &#8220;VETH-2&#8221; from the second list:</p>
<pre class="brush: plain; title: ; notranslate">
TASK &#x5B;print interfaces] ***************************************************
ok: &#x5B;localhost] {
    &quot;msg&quot;: &#x5B;
        &quot;docker0&quot;, 
        &quot;lo&quot;, 
        &quot;veth3e8c318&quot;, 
        &quot;wlan0&quot;, 
        &quot;dockercon&quot;, 
        &quot;eth0&quot;, 
        &quot;vethe2459c9&quot;, 
        &quot;VETH-1&quot;, 
        &quot;VETH-2&quot;
    ]
}
</pre>
<h2>Aggregate / reduce</h2>
<p>Here the problem is trickier &#8211; it depends on what you really want to do with list&#8217;s elements. Probably the most popular aggregation filter is <a href="http://jinja.pocoo.org/docs/2.10/templates/#join">&#8220;join&#8221;</a>, which just joins list elements into a single stream with elements separated by a given separator. There are a few more, but in general, when you need something more complicated, you either have to escape to a full Jinja2 template and do something custom in a &#8220;{% for %}&#8221; loop or <a href="http://docs.ansible.com/ansible/latest/dev_guide/developing_plugins.html#filter-plugins">implement your own filter.</a></p>
<h2>Related</h2>
<p>This article also has a continuation: <a style="background-color: #ffffff;" href="http://localhost:8080/devops/advanced-list-operations-ansible/">Advanced list operations in Ansible</a></p>
<p>The post <a href="https://tailored.cloud/devops/how-to-filter-and-map-lists-in-ansible/">How to filter, join and map lists in Ansible</a> appeared first on <a href="https://tailored.cloud">Tailored Cloud</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://tailored.cloud/devops/how-to-filter-and-map-lists-in-ansible/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
	</channel>
</rss>
