So friends, let me tell you a little bit of a secret.
One of the best modules that you can use in order to troubleshoot and to debug
your problems
is indeed the debug module.
Now we have just really been using this module to effectively print out
particular messages.
It really has been acting much more like a print module as opposed to a debug
module,
but by virtue of it being able to print out these messages, we can use it in
such a way
that it can help us debugish us.
So how about we take some time to actually explore this module in the context WEBVTT X-TIMESTAMP-MAP=LOCAL:00:00:00.000,MPEGTS:900000
So how about we take some time to actually explore this module in the context
of fixing problems,
and I think you'll get to see just how useful this particular module can be.
So with that said, let's just get to it.
Now just before we actually begin looking at a playbook,
one of the big problems we can have with Ansible is actually ensuring that our
variables have been
correctly defined.
Now, how do we actually know that Ansible is consuming the correct variables?
Well, one of the ways we can do that is just simply to print out those variable
values and
see if they match what you expect them to actually be. WEBVTT X-TIMESTAMP-MAP=LOCAL:00:00:00.000,MPEGTS:900000
see if they match what you expect them to actually be.
How are we going to print them out?
Well, you guess that we're going to use that debug module.
So let's just dive in and I'm going to my playbook right here.
Let's just say Vim, Play 1 dot YML and to enter, going to insert mode,
have our three hyphens at the top and we'll just say using the debug module to
find issues.
And let me just set my host to the value all and for now let's just set gather
facts to the
billion value false and now I'll define my tasks.
So let's just maybe say I wanted to see what particular variables were being WEBVTT X-TIMESTAMP-MAP=LOCAL:00:00:00.000,MPEGTS:900000
So let's just maybe say I wanted to see what particular variables were being
consumed by
what particular hosts.
Now before we begin, as we know with Ansible, we have this concept of an
inventory
and with respect to our inventory, we can categorize different groups as well
as different
hosts within this inventory.
Now the interesting thing is that depending on where you happen to define your
variables,
different hosts and different groups within that particular inventory can
effectively inherit WEBVTT X-TIMESTAMP-MAP=LOCAL:00:00:00.000,MPEGTS:900000
effectively inherit
different values.
Now if you happen to have a very simple inventory, like I have right here, if I
go into my inventory
for a moment, all I have are two devices in my group and each device belongs to
its own
geographical location.
So this is very, very simple.
But if you happen to have a massive inventory with many devices belonging to
multiple different
groups, it can be difficult to determine which particular values are going to
be associated
with which particular hosts.
So let me give you a simple example here.
If I go into my host first directory, I can see I have a host variable file for WEBVTT X-TIMESTAMP-MAP=LOCAL:00:00:00.000,MPEGTS:900000
If I go into my host first directory, I can see I have a host variable file for
each of
my devices, my blue box as well as my yellow box.
Let's go into the blue box right here.
Let's give this particular device a DNS setting value of 8.8.8.8.
That will be the IP address of the server here.
Now in the case of the yellow box, this here is actually just empty.
We have not defined any DNS configurations.
So let's go back out and if I go back and I see the end to my group first and
inside of
my all.yaml file, I happen to specify the key DNS server at this particular WEBVTT X-TIMESTAMP-MAP=LOCAL:00:00:00.000,MPEGTS:900000
my all.yaml file, I happen to specify the key DNS server at this particular
level and
I give it the value 192.168.1.1.
So we have a potential clash here.
Well, it's not really going to be a clash.
It's going to be resolved as per the rows of Ansible.
But as we can see, apparently in the all.yaml file, which should apply to all
hosts and the
inventory, the DNS server setting should be 192.168.1.1.
Whereas if we look at the host first of the blue box, the DNS server is set to
8.8.8.
Now if you recall about inheritance, the more specific variables should win. WEBVTT X-TIMESTAMP-MAP=LOCAL:00:00:00.000,MPEGTS:900000
Now if you recall about inheritance, the more specific variables should win.
So that means that the host variable value should override the group membership
.
But nevertheless, imagine like I say, it wasn't quite so simple.
There were multiple groups at many different levels.
Really, really nested that type of thing.
We want a quick way to determine which devices in our inventory is going to get
which particular
value. So what we can just simply do is to use a debug module to print out that
value straight away.
If I go into my playbook here, we could just say printing the DNS value for the WEBVTT X-TIMESTAMP-MAP=LOCAL:00:00:00.000,MPEGTS:900000
If I go into my playbook here, we could just say printing the DNS value for the
host.
And all I will do is use the Ansible built in a debug module and I'll specify
the message.
And I can just say the message, the DNS setting for host and the way I can
determine the host
is going to be the inventory host name, magic variable.
And then I could just effectively call the actual variable that I want to read,
which in this case here would be DNS underscore server.
So check this out right here.
If I just say Ansible play with play with one dot yml and to enter.
As we can see here, when Ansible runs through its process of a variable
resolution, WEBVTT X-TIMESTAMP-MAP=LOCAL:00:00:00.000,MPEGTS:900000
resolution,
for the blue box, it's going to resolve to the value 8.8.8.8.
Which is the host specific value, whereas the yellow box given the fact that it
doesn't have
a host value specified for that particular variable, it is just getting the
inheritance
via its group membership easily identified just by a simple use of the debug
module.
Similarly, what could also happen is if I go into my group verse again,
going to all dot yml, let's just remove the DNS server for this particular
group.
Therefore, what is going to happen? Well, when we happen to run the playbook WEBVTT X-TIMESTAMP-MAP=LOCAL:00:00:00.000,MPEGTS:900000
Therefore, what is going to happen? Well, when we happen to run the playbook
right here,
the DNS server is going to be set in the host variables for the blue box,
but it's not going to exist for anywhere in the case of the yellow box.
So when we go to print out this particular variable, we're going to see here,
we have a failure.
It says here in the message, this task includes an option with an undefined
variable.
So it tells us straight away here that for the actual yellow box,
we can see here we have the DNS server being undefined.
And just by simply reading this error message, we know straight away, WEBVTT X-TIMESTAMP-MAP=LOCAL:00:00:00.000,MPEGTS:900000
And just by simply reading this error message, we know straight away,
hey, if you want to use this particular value for a configuration on the yellow
box,
then we have to go and define that value somewhere within the inventory
relating to
the yellow box's configuration. Now, just to be aware here,
if we happen to suspect that we may have many, many devices and you want to
have a default
value, let's say in the event that the DNS server variable is not defined,
we can actually resolve this directly in the playbook itself.
So obviously I could go and define the host variable files or the group var WEBVTT X-TIMESTAMP-MAP=LOCAL:00:00:00.000,MPEGTS:900000
So obviously I could go and define the host variable files or the group var
files.
But in this case here, check this out if I just happened to say,
inside my double color braces, if I use the pipe symbol,
what I can do is use the default keywords.
And then within parentheses, I'll have my single quotation marks and I can give
a default value.
So let's just go with the value 1.1 and again, apologies for the ugly or lane
wrapping right here.
But check this out if I happen to just save this right now, if I read on the
playbook,
now we can see here in the event of any devices that do not have a particular
value specified as WEBVTT X-TIMESTAMP-MAP=LOCAL:00:00:00.000,MPEGTS:900000
value specified as
we saw via the debug module right above here, we can configure a default
variable value to be
populated when the playbook is executed. Now another very important concept
that we can utilize
with respect to Ansible is we can also specify the verbosity of the output of
the playbook itself.
So realistically, when we go to run our playbook as we see right here,
we just get to see the basic information about the playbook's execution.
We get to see the play recap, we see if there's any changes, any failures,
anything unreachable,
that type of thing, along with any potential values we may have printed. WEBVTT X-TIMESTAMP-MAP=LOCAL:00:00:00.000,MPEGTS:900000
that type of thing, along with any potential values we may have printed.
If I happen to run the playbook with a dash V, check this out right here.
We're actually getting more information about the execution.
We can see here in my case, this is the Ansible config file that's going to be
used,
which is this one right here inside my working directory.
Now if I just happened to maybe rename this particular file,
or just call this Ansible.Backup, if I just ran the playbook right here,
it just says here we don't have any host been matched.
However, just by specifying the dash V value here, we can see here, aha, WEBVTT X-TIMESTAMP-MAP=LOCAL:00:00:00.000,MPEGTS:900000
However, just by specifying the dash V value here, we can see here, aha,
a different Ansible configuration file has now been used.
It's been using the Etsy Ansible Ansible.CF to use the config files so we can
go in here.
And as we can see here, this file has not actually been populated with any
values.
So we can go back, watch the scape here.
If I do an LS, we can see the actual file, which should be my Ansible
configuration file,
isn't actually using the correct convention.
It should be called Ansible.CFG.
So in the case of the playbook, we can see we're not using the correct file.
So all I will do is simply change the name of this particular file to be Ans WEBVTT X-TIMESTAMP-MAP=LOCAL:00:00:00.000,MPEGTS:900000
So all I will do is simply change the name of this particular file to be Ans
ible.CFG.
Now Ansible should identify this as the valid configuration file.
And when I run the playbook with dash V, we can now see we're using the correct
configuration
file and we're getting the response as expected.
Now what we can actually do here is effectively toggle the verbosity by
specifying more v's.
If I do dash vv, hit enter, if I scroll on it, notice we're getting even more
information about
the execution itself.
We get to see where the Python module collection is. WEBVTT X-TIMESTAMP-MAP=LOCAL:00:00:00.000,MPEGTS:900000
We get to see where the Python module collection is.
We see things relating to the ginger templating line that we happen to be using
.
We see the execution location for where the Ansible playbook binary is actually
being called.
And again, if we just crank up the verbosity once more, as we can see here, we
're getting
even more information again.
Now what we can actually do here is within our playbooks, we can correlate the
printing of
particular variables if we so wish with a specified verbosity level.
Let me show you what I mean.
So let's go back.
So let's tell you all this and let's maybe say I define some variable values. WEBVTT X-TIMESTAMP-MAP=LOCAL:00:00:00.000,MPEGTS:900000
So let's tell you all this and let's maybe say I define some variable values.
Let's just call this test var.
Okay.
And let's just make the variable value pizza.
So if I create a task and let's just call the name test task, it doesn't
actually matter so much,
I will use the Ansible built-in debug module once again.
And the variable I want to print out is going to be my test for.
Now, like I say, if I happen to just run this right here and I hit enter,
notice the value of the variable happened to be printed out.
But what we can do here is we can go back in and let's say we just wanted to
only print
out this particular value when we wanted to use more verbosity on our playbooks WEBVTT X-TIMESTAMP-MAP=LOCAL:00:00:00.000,MPEGTS:900000
out this particular value when we wanted to use more verbosity on our playbooks
.
What I could do is I could assign the printing of this variable only when the
verbosity hits a
certain level.
So let's say the verbosity is at one.
Okay.
So if I use dash v, which is one v or greater, this variable will be printed
otherwise it won't be
to check this out.
So let's run a playbook without any verbosity, hit enter.
Nothing actually happens.
The task happens to be skipped.
However, if I say dash v and I enter, now the task is going to execute and we
do print it. WEBVTT X-TIMESTAMP-MAP=LOCAL:00:00:00.000,MPEGTS:900000
do print it.
And again, if we go even more verbose, then it also still will be printed.
Once again, we actually print out the test var.
Now, we don't actually have to just assign this with a particular variable.
Let's go back in.
It could be really similar to what we saw before.
I could just have a task pretty much saying print the DNS vars for the host.
Let's use the Ansible Belt and Debug module with the message.
Just say the DNS setting for this host is DNS_server.
And let me just change this to the blue box since the blue box is the only one
with a
DNS setting right now.
And again, of course, you could be defining a whole bunch of other tasks. WEBVTT X-TIMESTAMP-MAP=LOCAL:00:00:00.000,MPEGTS:900000
And again, of course, you could be defining a whole bunch of other tasks.
Let's imagine you wanted to use the Ansible Belt and Copy module.
I could just say copy some info and I'll specify that the content is going to
be
the DNS setting is and I'll pass in the DNS server value.
And I specify that the destination is going to be any file and attempt
directory,
just called test.txt.
Now, like I say, this part here is really just a test.
It doesn't do anything but give us information.
And it only really would be valuable if the actual task here wasn't performed WEBVTT X-TIMESTAMP-MAP=LOCAL:00:00:00.000,MPEGTS:900000
And it only really would be valuable if the actual task here wasn't performed
as expected.
Now, if it is performed as expected, we don't necessarily want to see this
information.
So what we can do is, like I say, we can specify that this particular message
is only going to
be printed when we require a verbosity level of what's maybe say to in this
case.
In fact, let's just call this task debug_print.
Okay.
So check this out.
If I just run the playbook as it is right now and hit enter, we're going to
actually skip
the printing of this variable because I didn't actually specify the verbosity.
Now, for whatever reason, if I was making configurations across many different WEBVTT X-TIMESTAMP-MAP=LOCAL:00:00:00.000,MPEGTS:900000
Now, for whatever reason, if I was making configurations across many different
devices
and some of the configurations in those files were not the value that you
expected,
then you could invoke the require verbosity.
Like I say, if we just do -v one time, it's still not going to show.
You see that the task has still been skipped.
The verbosity threshold was not met.
But if we run it again with double verbosity and hit enter,
now we're going to be actually printing out the debug message.
So quite honestly, the debug module is a very, very important utility
when ensuring that your playbooks are executing correctly and particularly WEBVTT X-TIMESTAMP-MAP=LOCAL:00:00:00.000,MPEGTS:900000
when ensuring that your playbooks are executing correctly and particularly
when dealing with variable values in any complex environments.