If you liked what you've learned so far, dive in!
Subscribe to get access to this tutorial plus
video, code and script downloads.
At this point, we can execute any module on our hosts... but we're still doing it manually from the command line. If that's all Ansible could do, it would... kinda suck.
Nope, what I really want is to be able to create a big config file that describes all of the modules that we need to execute to get an entire server set up: like installing PHP, installing MySQL, installing Nginx and then configuring everything.
This is done in something called a playbook: a YAML-formatted file that contains
these instructions. In the ansible
directory, create our playbook: playbook.yml
.
For now, just leave it empty.
To run the playbook, instead of using the ansible
command, use ansible-playbook
.
Point that at your playbook and keep passing -i ansible/hosts.ini
. Try it!
ansible-playbook ansible/playbook.yml -i ansible/hosts.ini
Error!
Playbook must be a list of plays
Ah, ok, this is a preview of some Ansible terminology. Let's start filling in the
playbook. At the top, every YAML file in Ansible starts with three dashes (---
):
... lines 2 - 6 |
It's not really important and doesn't meaning anything... it's just a YAML standard.
Below, add host: all
:
- hosts: all | |
... lines 3 - 6 |
Then, indent two spaces, add tasks
, indent again, and add ping: ~
:
- hosts: all | |
tasks: | |
- ping: ~ |
If you're new to YAML, you do need to be careful: the spacing and indentation are important. Try it:
ansible-playbook ansible/playbook.yml -i ansible/hosts.ini
Sweet! It runs the ping
module against all hosts: our local machine and the VM.
Ok, back to the terminology we saw in the error message. A playbook contains plays.
In this case we have just one play that will run on all
hosts. Later, if we added
another host
line with its own tasks
below it, that would be a second play.
So, a playbook contains plays, a play contains tasks and each task executes a module.
In this case we're executing the ping
module.
To run the play against only one group, there are two options. First, at the
command line, you can pass -l vb
:
ansible-playbook ansible/playbook.yml -i ansible/hosts.ini -l vb
But a better way is to configure this inside of your playbook. This play will
be responsible for setting up an entire server... so we don't want to run it against
our local machine... ever. Change the all
to vb
:
- hosts: vb | |
tasks: | |
- ping: ~ |
Now try the command, but without the -l
option:
ansible-playbook ansible/playbook.yml -i ansible/hosts.ini
Yes! Just one ping.
Ok, let's install stuff!
"Houston: no signs of life"
Start the conversation!
// composer.json
{
"require": {
"php": ">=5.5.9",
"symfony/symfony": "3.1.*", // v3.1.4
"doctrine/orm": "^2.5", // v2.7.2
"doctrine/doctrine-bundle": "^1.6", // 1.6.4
"doctrine/doctrine-cache-bundle": "^1.2", // 1.3.0
"symfony/swiftmailer-bundle": "^2.3", // v2.3.11
"symfony/monolog-bundle": "^2.8", // 2.11.1
"symfony/polyfill-apcu": "^1.0", // v1.2.0
"sensio/distribution-bundle": "^5.0", // v5.0.12
"sensio/framework-extra-bundle": "^3.0.2", // v3.0.16
"incenteev/composer-parameter-handler": "^2.0", // v2.1.2
"doctrine/doctrine-migrations-bundle": "^1.2", // v1.2.0
"snc/redis-bundle": "^2.0", // 2.0.0
"predis/predis": "^1.1", // v1.1.1
"composer/package-versions-deprecated": "^1.11" // 1.11.99
},
"require-dev": {
"sensio/generator-bundle": "^3.0", // v3.0.8
"symfony/phpunit-bridge": "^3.0", // v3.1.4
"doctrine/data-fixtures": "^1.1", // 1.3.3
"hautelook/alice-bundle": "^1.3" // v1.4.1
}
}