- In this video we are going to discuss
different filter use cases.
So to start with,
I'd like to have a look at the map filter.
The map filter is useful to look up an attribute
and it is useful when dealing with lists of objects
where you are only interested in a specific value.
It allows you to search for it.
So if for instance,
the find module is used to find files,
multiple attributes are shown
and map can be used to filter just one of them.
Map can work with optional arguments,
such as the relpath function,
which is useful in displaying file names
relative to a directory.
And notice that map returns a list by default.
And to show the output of a single line,
use the joint filter as well.
Let's have a look at some examples.
So the example is in the filters directory
in the Git repository.
It has a name filemap.
And here we can see what it is all about.
So let's go over it line by line.
So if we have the host and the become
and the other parameters.
So basedir is setting a variable with the name basedir
via www/html, is what it's about.
Then it is installing httpd,
that is making sure that we have a basedir directory
and it is showing basedir right here.
Just to make sure that we are okay.
Next it is showing files in basedir.
And you know what, in order to make sure,
I need to make sure that we have this basedir installed.
So ansible on ansible2
- m file -a.
Path is var/www/html,
state is directory.
Oops, and I do require sudo password -k.
And there we go.
And we can see that the directory already existed.
That is good.
Now let's do a quick check
and I know I should be doing this with Ansible
but the thing is that the best way to do it with Ansible
is by using some filters that we have not yet talked about.
So I'm using ls /var/www/html.
And we need to make sure that there's a couple of files.
So here's a couple of files.
If you want this example playbook to work,
make sure that at least you have a couple of files
in the directory that you are investigating.
Of course, feel free to do that using Ansible
or otherwise go for quick and dirty as I've just done here.
So here is where we get the interesting thing.
So we have the find module,
and the find module
is showing files
in the basedir directory.
The result is registered in basedir files.
That's for the simple reason.
That as you know,
in Ansible you don't typically see results
while running the playbook.
So if you want to see the results,
you should put it in some variable.
Here we are using debug to check on basedir files.
And then the important part
where we are going to show the files
based on the map attribute path without a list.
I am showing you how not to do it.
So we are not doing it the right way
by using set fact web files.
On web files, we are looking for basedir files,
which is a tier two variable that is created in basedir.
And then we use map attribute is path.
Now map attribute is path,
that is something that you can only understand
after looking at the basedir files variable
because path is an attribute in that variable.
And we are using map to look up that specific attribute.
Remember that is what map is all about.
Then you will see
that this is not giving the desired results
and if we want to put it in the desired results,
we need to pipe it through a list as well.
And there, we can see that this exactly
is going to give us the list that we want to work with.
We put that in a variable web files list
and there you could continue your playbook
and make it more complicated and work on the specific list.
Let's run it.
So ansible-playbook on filemap.yaml.
There we go.
And what do we see?
Let's have a look at it.
This is where we can see all the different files
and in all these different files
that are found by the find module,
so this is the result of the find module
and picking out is one of them.
One of the attributes is path.
And as you can see, this is a lot to read
and that is probably not what you want.
So here you can see without the list.
And without the list,
you are getting this generator object do map at, whatever.
That's not really meaningful.
The meaningful part is here
where we are combining the map filter
with a list filter as well.
And that is showing a list of files
and this list of files.
Well, that is what you can use in a loop for instance.
And that brings you close to what previously was done
with Ansible with files.
Let's go have a look at the next filter.
So the next filter that we are going to explore is flatten.
Flatten recursively searches list items
and flattens them into one list.
And that is useful when getting multiple items
out of a hierarchical list.
And you can have a look at plot.yaml for a simple example.
So here we have the example.
And what do we see?
We see a complex list.
And in this complex list, we have a variable, whatever,
and in a variable, whatever,
we have a tier one list province
which are provinces in my beautiful country.
And in there, we have a tier two list,
which is showing the cities.
And actually we want to produce a flat list
from the nested structure.
Now, how are we going to do that?
Well, we loop over whatever,
and we look at map attribute is cities,
and then we send it to flatten.
And the results is as follows,
where you can see that every single city
in this case is printed one by one.
Now, how is this useful?
This is useful if you are analyzing a complex variable
that has a list of lists
and you want to put out a specific tier list.
And that is how you can see
that we have combined map to look up the specific attribute
and flatten to make it flat.
And maybe it helps if we have a look at it
without the pipe flatten behind it.
So what is going to happen in that case?
Well, in that case,
this is where you are going to see an,
oh, invalid data passed through the loop,
and it just doesn't understand it.
So we do really need the flatten
to be inserted at the end
to generate the appropriate list.
So there we go again and now it's working again.
Next example.
Let's have a look at subelements.
So, subelements is a filter
that allows you to create a new list
that is based on subelements in complex data structures.
So, a subelement is a list within a list.
And while using subelements,
the top level item in the list is referred to as item.0.
And the second level item is referred to as item.1.
That's really something in the syntax
that you need to pay attention to.
And I have dbvars.yaml and dbuser.yaml, for an example.
Let's go explore.
First, I'd like you to have a look at dbvars.
So this is dbvars, where we can see a variable dbuserperms
with a list username and a list dbaccess.
So these variables need to be used as inputs
to provide a user access to certain databases.
Now, if we have a look at dbuser,
and I'm putting it on one screen
to make it easier to see the relations,
then we can see that we go over the contents of dbvars.
And I'm just using debug to keep it simple
because the purpose here is to give you insight
in how it is working.
So in the debug I'm printing a message,
adding user item.0 username
and granting permissions item.1*.ALL.
And the point here is that it is going to grant
the user permissions to the appropriate databases.
So we should see that Linda is getting access
to books and video,
and Anna is getting access to staff and addresses.
Then we loop over the contents of the variable dbuserperms
and subelements is what is getting the access.
So subelements, as you can see, subelements is dbaccess.
And the subelement dbaccess is really looking
and iterating over the different databases here
and not over the different users.
And that is a secret of subelements.
So let's run it, ansible-playbook on dbuser.yaml.
And there we go.
And you can see
that Linda is indeed getting to books and videos,
and Anna is getting access to staff and addresses.
So this is something that you can easily use
to populate a MySQL database
with your appropriate permissions, for instance.
So the last filter I'd like to have a look at here
is dict2items,
which is converting a dictionary to items.
Why would you wanna do that?
For the simple reason
that you cannot use loop over a dictionary.
So you need dict2items to transform a dictionary
into a list and allow looping over it.
Let's check it out.
So here we have dict2items,
and what do we see?
We see variable, variable users
that is organized dictionary style.
And we have Lisa in shell and groups
and Anna in shell and groups, and then create users.
What is happening if we do that
without the dict2items?
Let's remove it.
Then you can see, well, item,
but probably you can already guess an item needs a loop.
So what is the loop in this case?
Well, that can only give us an error
because there is no loop.
Apart from the fact
that we are missing sudo password on ansible1
but that's not really what matters.
What matters here is invalid data pass to loop.
And it is quite gentle.
It requires a list.
Got this instead.
And hint, if you pass a list dict of just one,
well this is not really helpful, the hint.
So we really need that filter dict2items.
So here we go, dict2items,
and that should convert our dictionary into a list.
And as you can see, that is working so much better.
So this is what I wanted to show you.