Modules
We need to talk about 2 important words in Ansible: modules and hosts.
Ansible comes built with a ton of things called modules: small programs that do some work on the server. Most of the time, instead of saying:
Ansible! Execute this command!
you'll say:
Ansible! Execute this module and allow it to run whatever commands it needs to get its job done.
For example, if you want to install something on an Ubuntu server, instead of running
sudo apt-get install php7.1
, you'll use the apt
module. Need to edit a file?
There's a module for that too.
And when you execute a module, you'll of course always execute that module on one or more servers. These are called hosts. So, in Ansible language, we'll say:
I want to run this module on these hosts.
Running your First Module
Ok, terminology garbage done. Let's do something! The simplest way to execute a module
is from the command line. ansible localhost
means that - for now - we're going to
run this module against our local machine. Then, -m command
to run the "command"
module - the simplest module in Ansible that allows you to... well... just run a
command directly on the server. Then, add -a "/bin/echo 'Hello Ansible'"
to pass
that as an argument to the command
module:
ansible localhost -m command -a "/bin/echo 'Hello Ansible'"
Try it! We see some output and... Hello Ansible! Congrats! You just ran your first
module: command
. In this case, we can even remove the -m
option:
ansible localhost -a "/bin/echo 'Hello Ansible'"
The command
module is so fundamental, it's the default module... if we don't pass one.
Hey! Let's try another module!
ansible localhost -m ping
You can probably guess what this does: ping
is a small program that makes sure
that we can contact the server.
What other modules can we use? Flip back to your browser and Google for "Ansible modules". They have a few pages, like "modules by category". But let's go to the full All Modules page.
Woh! If we're commanding a robot army, we just found out that a lot of our robots already know how to do a ton of stuff. Yes! This is all free functionality!
The composer Module
One of these modules should look pretty interesting to PHP developers: the composer module. Instead of executing Composer commands manually on the server, you can use this.
For example, back on the command line, if you setup your project like I did, then
your vendor/
directory is populated with files. Let's kill them! Be reckless by
running:
rm -rf vendor/
Now, take the composer
module for a test drive:
ansible localhost -m composer
Woh! It fails!
Missing required arguments:
working_dir
.
The Ansible module documentation is pretty awesome: each page lists all of that
module's options, their default value and whether or not they're required, like
working_dir
. And below, they usually have a bunch of really nice examples.
In this case, to pass the option, add -a "working_dir=./"
to point to this
directory, since the module will run on this machine. We also need to pass
no_dev=false
. That's just another option for this module - and we'll talk about
what it does in a little while.
Ok, try that!
ansible localhost -m composer -a "working_dir=./ no_dev=false"
Woohoo! It looks like it's working! My terminal tab even shows the crazy things it's doing behind the scenes.
Tip
If it doesn't work on your machine, no big deal. This module requires you to have PHP and Composer installed. Soon, we'll guarantee that these are installed on a fresh Ubuntu machine.
Once it's done... boom! We see the full output of everything that happened.
The "changed" Status
AND, we see one really important thing: it says "changed true" and the output is yellow. The module detected that this command made a change to the server. Run the module again:
ansible localhost -m composer -a "working_dir=./ no_dev=false"
Woh! Now the output is green and it says "changed: false".
That is one of the most important superpowers of modules: not only do they make something happen on your server, they're able to detect whether or not the server changed by running the module. This will be important: later, we can trigger different actions based on whether or not a module did or did not actually make any changes.
But how the heck did Ansible know that the server didn't change the second time?
That cleverness is actually built into each module. The composer
module is smart
enough to know that nothing changed based on the output of the command - the fact
that it said:
Nothing to install or update
By the way, now that we're rocking Ansible, we could have cleared the vendor directory
via the command
module:
ansible localhost -a "rm -rf vendor/"
To prove that worked, run the composer
module again:
ansible localhost -m composer -a "working_dir=./ no_dev=false"
Ha! Back to "changed: true" with yellow output.
Next, let's talk about how we organize which servers we're running Ansible against. Because obviously, we don't want to run against localhost forever!
Dear Ryan,
I believe there is a typo. The text states "bin/echo" and the video shows "/bin/echo".
Drove me a bit nuts because I thought you probably ment the symfony "bin/" folder but why "echo"?!?
Cheers
Karsten