2018-04-25

Ansible Week - Part 3

We have a target machine and we've put its access credentials into our inventory. We can ping it with Ansible, but it's time for us to do something. You can define these steps into a "playbook", which is just a specially-formatted file that outlines your chosen actions and which machines upon which you want to act. This file is in YAML, which Isn't Terrible so you Shouldn't Be Afraid of It:

$ cat ./playbook.yml
---
- hosts: mymachines
  tasks:
  - name: Create a new file
    shell: echo "Hello world" >> {{ansible_ssh_user}}/hw.txt
    args:
      creates: "{{ansible_ssh_user}}/hw.txt"

I'm fairly certain no one actually understands the technical syntax of YAML. Everyone simply takes an existing valid YAML file and edits it as they desire into a new YAML file. When they need another change, they edit the previous one and make a new YAML file, and so on. The YAML specification, then, is just a matter for people writing YAML parsers. YAML writers can just steal old .YML files and go on with their lives, which is nice.

This is a simple playbook that just creates a new file on the target host. It defines your target hosts ("mymachines") and defines a task to run on it. Tasks have a name and a type, in this case the type is "shell" and the shell type takes one argument called "creates", which tells ansible that this task has a defined end result: it creates a specific file. Therefore, if this file already exists, Ansible will skip performing this task.

Now we run it:

ansible-playbook --inventory=./hosts.my ./playbook.yml

Note that the actual action of this task is echo "Hello world" and it is appended to a file. Without the "creates" line in this task, running this playbook multiple times will continue to add "Hello world" to that file over and over again. These are the kinds of tricks and gotchas that will occupy your mind as you create bigger and more complicated playbooks and which I began learning and correcting in my own sysadminning back in the days of mailcom scripting.

Note, too, that we are using a variable in the playbook called "ansible_ssh_user", which we defined in our inventory file. This means that we can reuse this playbook against a number of different inventories, across any number of environments, anywhere we want to have this new "hw.txt", without having to customize a playbook for every environment. Ansible strives to be modular, reusable, and composable, which are fancy words that really just mean "easy to mix and match pieces so I don't end up reinventing the wheel all the time".

This modularity really starts to take effect when you stop putting your actions into playbooks and evolve into putting them into roles. What's a role? It's tasks on steroids.

Next time: Role playing.

No comments: