- In this video we will talk a little bit more
about Running your First Playbook
and everything that's involved.
So to run a playbook,
you use the Ansible-playbook command.
And syntax check is possible,
but it's not really needed.
And that is because the Ansible-playbook command
will alert you anyway if anything is wrong
with your playbook.
If you want to get more insight
in the workings of the playbook
you can use a minus v option,
up to four times for increased verbosity messages.
Minus v two times will tell you which files I used
which is pretty convenient.
And minus v four times is giving you
complete debugging information about everything
that is happening while you are running your playbook.
Notice that by default playbooks
do not write any output log.
You can read the standard output,
which is your computer screen
to analyze the messages about success or failure
of the playbooks.
The idea is that in a command line version of Ansible,
also known as Ansible engine,
output messages are printed on screen.
You can read them from screen.
So why would you want to write them to log?
Because logs can be very verbose.
Now let's go have a look at an example playbook.
There is install and start httpd.yaml.
You can find it in a basics directory,
in the git repository.
Let's go check it out.
So in the Ansible cvc git repository,
there's the basics sub directory.
But hey, before we continue,
let me show you history by grep git
just to make sure that you see where I get this from.
So command number 87 is telling you,
git clone https//github.com/sandervanvugt/Ansiblecvc.
That's the clone git repository.
In there you will find install and start httpd.yaml.
Let's the example playbook.
So install and start httpd.yaml.
About the name of the playbook,
playbooks are written in YAML
and it's common to have the YAML extension
and you can find two different extensions.
You can find YML, you can find YAML.
For some reason, I like YAML better.
And that's why my playbooks in general have YAML,
but it's totally fine if you want to do YML,
it really does not matter.
So here we can see this install start and enable httpd.
So it's a different playbook doing the same thing
as what we've just seen.
It starts with three dashes.
That's a YAML identifier
that is telling your YAML interpreter
that the code is starting here.
Then we see the play header.
So this is a one play playbook.
And in this single play playbook
we are running it using name hosts, all tasks.
Are we going to do this on hosts all?
No, we shouldn't be doing that.
Let me use hosts rocky
for the simple reason that ubuntu does not have a package
with the name httpd oh, you know what?
Let's talk about errors at the same time
and let's try to run it on ubuntu SL.
So next we have the task and in the task
I'm using the package module.
Package is a generic module
that allows you to install software packages.
It doesn't allow you to use some of the specifics
that may be available in specific modules like ept and dnf.
But the nice thing about it
is that it will work against different Linux targets.
So this is going to try to install the httpd packages,
and then it is using the service module
and the service module it'll try to make sure
that the httpd package is started and enabled.
So package talk to the package manager on the back end
of the managed target and service is talking
to system D to make sure that the package is installed.
Now let's run it Ansible playbook.
So you run it on install and start httpd.yaml
and there we go and we can see it
starting with fact gathering.
Fact gathering always takes a little bit of time.
We just talked about it.
And fact gathering is something that actually
you may want to turn off
because facts can be used as variables inside your playbook.
But if you're not going to use the facts
why would you waste the time on gathering them?
You can see that here reaching out
to the rocky machines is taking some time and oh
what do we see install package, fatal ubuntu failed.
So what is it showing us?
Well, if you glimpse over it, we can see
that the package httpd has no insulation candidate.
That makes sense, because on ubuntu
the name of the package is Apache2 not httpd.
You can see on Ansible one, as well as on Ansible two,
we get the status have changed,
which means that the package
has successfully been installed.
Changed means that the desired state
is described in the playbook
did not meet the current state of the managed machine
and if change was required.
If the desired state already met with the current state
then you will see, okay, instead.
Also you will see something else in start and enable server,
it's not working on ubuntu anymore.
And that's because of the default behavior in errors.
If task execution on a specific host is failing
then further task execution
on the same host will be skipped.
So that is why ubuntu failed install package.
So it doesn't play ball anymore
and start and enable service.
And we only continue on Ansible one and Ansible two
to start and enable the service.
So in the summary, we can see that all Ansible one
and Ansible two, three tasks have run successfully.
If you are wondering why is that three?
That is because fact gathering counts as a task as well.
Of these three tasks, two have triggered a change,
and one of them is only an okay.
And an ubuntu, well on ubuntu fact gathering
was working as expected but we got a failure.
And that's why we see failed is one.
Now it would be interesting to run the playbook again
if you run the playbook again
it should give you the exact same result
with the exaction that now Ansible one
and Ansible two already have httpd installed.
So now we should see the idempotent nature of the playbook.
It shouldn't do anything.
It shouldn't complain.
It should just tell us, okay and okay.
Because no further changes were needed on Ansible one
as well as on Ansible two.
And that is exactly what we see here.
Still failing on ubuntu that's expected behavior.
And then we can see that on Ansible two
as well as on Ansible one, it is giving us an okay.
Okay, meaning that the managed machine state
already met with the desired state
and no changes were necessary.
Right, now that we have run and analyzed our first playbook,
let's get back to the slides and see what else is in there.
So we have seen how to run the playbook
with Ansible playbook, install, and start httpd.yaml
and how you can observe the output.
We've also seen the different things are happening
while executing a playbook
which includes fact gathering, task execution
and a play recap, and notice
that good playbooks are written to be idempotent.
Idempotency is really really very important
because you want every single time
that the playbook is running no matter
which is the state of the managed machine
you want it to be successful.
Now in a playbook, you can also find multiple plays.
That's the nature of a playbook.
It can define one or more plays
and defining multiple playbooks makes sense
in a couple of cases,
first, to write a playbook in a modular way
just imagine that you want to set up a host
and there's like 50 different tasks that you want to run
on one host then, including all of the 50 tasks
in just one play is not really easy to manage dependencies
to oversee what exactly is happening.
And you might be better off
just for the sake of organization
to make it to multiple play playbook
that would limit the number of tasks that run in one play.
Also, another good reason to run multi-play playbook
is to run some task on one host
while others are running on another host, or if you want to
in a play header, you can set variables as well.
Multiple plays allows you to work with different variables
in different stages of playbook execution.
Now let's have a quick look at a run and test httpd.yaml,
which is a multi-play playbook.
So here we have the run and test httpd so what do we see?
We see that it is installing
and enabling httpd in the first play.
Then we see gather facts set to false
because fact gathering is useful
if you are going to use the variables that are gathered
by fact gathering.
If you are not planning to use them at all,
you might as well turn it off.
The host is rocky.
So we are going to run this on rocky only.
And what do we see in so and start and enable service?
This should give us okay.
And okay, because the service is already installed.
And next we go to local host,
local host is your Ansible control host.
We do not need to become anybody else.
And that is why become is set to false.
We can do that with ordinary user privileges
without any privilege, escalation.
And we are going to test httpd accessibility.
We do that by using the uri module
and the uri module is going to reach out
to the url httpd column slash slash rocky.
And if name resolving is set up correctly
and httpd is listening, and the firewall is open as well.
Well, then we should see positive reaction.
Let's run it Ansible playbook on run and test httpd.yaml.
As you can see, we are skipping the fact gathering
that makes it really much faster.
And then it's trying to install the package again.
That's something that's not needed anymore
because we have already done that
in the play that we were just running.
But the thing is that behind package management
there is yam slash dnf
on recent RedHat that needs to update package cash
and stuff like that.
And that always takes a minute or so.
So there we go start and enable service
that also shoot not take too much time.
And now we can see that we are executing the second play.
So at this point, we are on local host on which, by the way
I forgot to turn off fact gathering.
Of course we don't need any fact gathering at all
on local host because we are not using it.
Next, it is working on test httpd access,
and oh no what do we see?
Well, we see change false content,
elapsed status code was minus one and not 200.
The uri module is expecting a status codes 200
if access is successful, it was not successful.
And why is it not successful?
Well, most likely because we are not doing any httpd
in the firewall here.
By default the firewall is preventing httpd
from being accessed, you know what?
Let's fix that right now.
I'm going to open a new tab.
And in my new tab, I am going to use
Ansible doc on firewalld.
Firewalld is the module that we need
on RedHat and relate it.
I am going to scroll downwards.
And if you scroll downwards
we can see an example of what we need.
So let's get back to the other tab.
And on the other tab, let's use this run and test httpd
in which I am going to use
name open port in firewall,
Firewalld is what we need.
Notice that firewalld is specific for RedHat
won't work on ubuntu, but that's no problem here
because we are on the rocky hosts anyway,
and then what do we need?
Well, we need to follow the example
which is service permanent state, and also immediate.
So service, permanent state and immediate.
So service is going to be http,
permanent is going to be set to yes,
state is going to be set to enabled, et cetera.
So we will double check in a while
and immediate is going to be set to, yes, let's double check
and service, permanent and state enabled all looking good.
Now how about the immediates?
Do we see that in the examples?
As well as you can see, I really like the examples
and the last example has the immediate
and that is exactly what we need.
Immediate in firewalld ensures that it is immediately opened
and we don't need to wait for the next restart of firewalld.
All right, now I can get back to my playbook
and I can include this gather facts
and set it to no, notice that this is bullying.
And in bullying, you can use false.
You can use, no, you can use false
with an uppercase F or a lowercase f
Ansible is quite tolerant relating to all of that.
And now we are going to run it again
and see what it is doing.
So there we go.
It's opening the port in the firewall, as you can see
change and change, which means that the firewall port
is opened successfully and out accessing httpd access.
And once it's done it should tell us that it got a 200.
200 is the http return code that is identifying
that all whilst good.
And, oh, no, we can see that still httpd access is failing.
What is going on?
Well, let's use some Palo Alto commands to troubleshoot.
So I'm using Ansible on Ansible on what?
Well, I know what is going on.
Let's have a look.
Can you see what I'm doing here?
I'm using http on rocky.
I shouldn't be using http on rocky because rocky
is the name of a host group,
and we need to do this on a host itself.
And that is Ansible one instead of rocky,
let's run it again.
And once it is there, and now we should see
that it is successful in giving us the result that we want.
So what is this?
This looks like an error.
It's not, this is the default webpage
that Apache is showing.
If it does not really have anything else to show
it's not an exit code 200.
And that is why we see this message filled.
But if you know Apache
then you know that you shouldn't consider this a failure.
This is doing okay.
The thing here is that we get status 403
which means index html not found.
And that is why we see this.
Troubleshooting, we don't need to troubleshoot this.
We can consider this a working situation.