Ansible YAML Inventory


At this point we have a fairly useful setup. We can take fresh servers and get them into some sort of shape that meets our basic needs. We aren't quite production ready just yet, but we're on our way.

Along the way we've accumulated some areas of our configuration that could be improved.

You don't need to do any of this. But you might want to. I do, and I think it's useful to know about.

production >> production.yml

As it stands at the moment we have a file called production which details all our production inventory. This file tells Ansible all about our servers, what names they have, what IP address should be used to connect, what groups we want to associate these servers with, and so on.

rk8s-lb-1 ansible_host=5.9.117.211 ansible_python_interpreter=/usr/bin/python3
rk8s-node-1 ansible_host=6.10.118.222 ansible_python_interpreter=/usr/bin/python3
rk8s-node-2 ansible_host=7.11.119.233 ansible_python_interpreter=/usr/bin/python3

[rancher-2-kubernetes-nodes]
rk8s-node-1
rk8s-node-2

[rancher-2-load-balancers]
rk8s-lb-1

For me, this is starting to get a little long winded.

As it stands we repeat ansible_python_interpreter every time we define a new host entry, and then we're going to have various bits of custom data added, and over time the lines will become long and hard to read.

We can remove the ansible_python_interpreter entry. Given that at the moment, all of our hosts use Python 3, I'm going to move this entry into group_vars/all.

But before I do, I'm going to switch to YAML syntax for all my configuration and inventories.

I prefer the syntax highlighting my editor gives me when working with yml files, over the plain text / ini files.

This comes at the expense of verbosity, as we shall soon see.

touch group_vars/all.yml

And into this file, add the line:

---
ansible_python_interpreter: "/usr/bin/python3"

So far, so good.

Then the same for production:

mv production production.yml

And this file needs totally changing:

---
all:
  hosts:
    rk8s-lb-1: 
      ansible_host: 5.9.117.211
    rk8s-node-1: 
      ansible_host: 6.10.118.222
    rk8s-node-2: 
      ansible_host: 7.11.119.233

  children:
    rancher-2-kubernetes-nodes:
      hosts:
        rk8s-node-1:
        rk8s-node-2:
    rancher-2-load-balancers:
      hosts:
        rk8s-lb-1:

Ok, the weird parts are hosts, and children. And there's another top level entry that I haven't used: vars.

Working with this stuff is fairly intuitive after a while. You just have to get tactile - type it out.

The Ansible documentation for inventories is decent on this subject, and this handy 'cheatsheet' should get you the rest of the way.

Groups of Groups

We have the concept of rancher-2-kubernetes-nodes, which we know will be any node provisioned for use inside our Rancher 2 Kubernetes cluster.

Think of this as a generic, catch all approach to node management.

We also need three sub groups. We've touch on these already:

  • etcd
  • controlplane
  • worker

These are more specific types of nodes. We should model this concept in our inventory. And to do that, we can use groups of groups:

---
all:
  hosts:
    loadbalancer: 
      ansible_host: 5.9.117.211

    etcd-0: 
      ansible_host: 6.10.118.221
    etcd-1: 
      ansible_host: 6.10.118.222

    controlplane-0: 
      ansible_host: 7.11.119.231
    controlplane-1: 
      ansible_host: 7.11.119.232

    worker-0: 
      ansible_host: 8.12.120.241
    worker-1: 
      ansible_host: 8.12.120.241

  children:
    rancher-2-kubernetes-nodes:
      children:
        etcd:
          hosts:
            etcd-0:
            etcd-1:
        controlplane:
          hosts:
            controlplane-0:
            controlplane-1:
        worker:
          hosts:
            worker-0:
            worker-1:
    rancher-2-load-balancers:
      hosts:
        loadbalancer:

It doesn't matter if you use additional lines between the blocks. I've shown two variations here. I think the all.hosts block is easier to read with additional line breaks between the groups. Indentation is what matters.

Lastly we need to update our Makefile to use the new .yml extension:

run_playbook:
    @docker run --rm \
        -v $(CURDIR):/crv-ansible \
        -v ~/.ssh/id_rsa:/root/.ssh/id_rsa \
        -v ~/.ssh/id_rsa.pub:/root/.ssh/id_rsa.pub \
        -w /crv-ansible \
        williamyeh/ansible:alpine3 \
-       ansible-playbook -i production site.yml $(cmd)
+       ansible-playbook -i production.yml site.yml $(cmd)

At this stage we have cleaned up our configuration, and learned a few extra useful techniques along the way.

In the next Rancher 2 / Kubernetes tutorial video we will move on to installing Kubernetes with Rancher Kubernetes Engine (RKE).

Episodes