Using ansible in a host-centric fashion

Dear list,

Ansible configuration management seems to be based on the idea that
I invoke a playbook, which then specifies which tasks to run on
whatever the nodes may be.

By this logic, one might create a playbook configuring lighttpd or
apache2 on all "webservers", and another playbook configuring
PostgreSQL on all "sqlservers", and then maybe another playbook that
includes both of those to be run at once. Now, using a push or pull
approach, this all-inclusive playbook is played across the entire
infrastructure.

This is a powerful approach when configuration management is
targeted at an "infrastructure", by which I mean a number of
computers that form an entity, i.e. an e-commerce site.

But there also seem to be downsides. For instance, I have to always
make sure that the all-inclusive playbook is actually all-inclusive,
and when I add a new playbook, I need not forget to add it. Also,
I need to maintain my nodegroups in the inventory, and the more
diverse my infrastructure gets, the harder and complex this will
get.

And while I can look at any playbook and immediately figure out
which hosts will be targeted (possibly after consulting the
inventory), I cannot glean from a single look exactly which plays
will be performed on a given host (blue.example.org); instead,
I need to look at all the playbooks and determine which ones apply
to said host, and I need to apply the variable precedence rules
and inspect all variable files to figure out what parameters will be
used in these plays.

Surely, a tool to pull all these data together is trivial to write
or already exists, but is it possible to maintain the data in
a host-centric fashion in the first place?

For instance, consider:

  blue.example.org:
    roles:
      - webserver
      - debiannode@wheezy
      - hosted@zurich
    playbooks:
      - foobar
    vars:
      motd:
        blue.example.org is sponsored by XYZ Ltd.

and a role might be similarly defined like this:

  webserver:
    playbooks:
      - apache2
    vars:
      …

The roles create a simple hierarchical database (they are basically
includes), and each role adds onr or more playbooks to the list to
be applied to this host, along with variable defaults that I can
override at any point.

With Puppet and Saltstack, I had to use so-called external_nodes
interfaces (cf. https://github.com/madduck/salt-reclass).

Is something like this possible with Ansible? Can I use ansible in
such a host-centric way? Where do I start?

Or do you think that my view on configuration management is twisted
and I should wake up, unwind my head and embrace the ansible
paradigm? I would love to hear your arguments if you think that the
approach I described is inferior.

Thanks,

also sprach martin f krafft <madduck@madduck.net> [2013.02.13.1400 +1300]:

Is something like this possible with Ansible? Can I use ansible in
such a host-centric way? Where do I start?

https://github.com/mavimo/ansible-docs/blob/master/rst/api.rst#external-inventory-scripts

looks like the ticket. It should be trivial to amend my "reclass"
script to those conventions.

https://github.com/madduck/salt-reclass

Or do you think that my view on configuration management is
twisted and I should wake up, unwind my head and embrace the
ansible paradigm? I would love to hear your arguments if you think
that the approach I described is inferior.

I would still love to hear thoughts about this.

But there also seem to be downsides. For instance, I have to always
make sure that the all-inclusive playbook is actually all-inclusive,
and when I add a new playbook, I need not forget to add it. Also,
I need to maintain my nodegroups in the inventory, and the more
diverse my infrastructure gets, the harder and complex this will
get.

This happens with basically every CM tool.

It's also why tools like the external-inventory script exist.

And while I can look at any playbook and immediately figure out
which hosts will be targeted (possibly after consulting the
inventory), I cannot glean from a single look exactly which plays
will be performed on a given host (blue.example.org); instead,
I need to look at all the playbooks and determine which ones apply
to said host, and I need to apply the variable precedence rules
and inspect all variable files to figure out what parameters will be
used in these plays.

ansible-playbook foo.yml --list-tasks

ansible-playbook foo.yml --list-hosts

Surely, a tool to pull all these data together is trivial to write
or already exists, but is it possible to maintain the data in
a host-centric fashion in the first place?

For instance, consider:

  blue.example.org:
    roles:
      - webserver
      - debiannode@wheezy
      - hosted@zurich

playbooks are mappings between host groups and roles, exactly.

Though it sounds like what you may want is to write an external
inventory script that allows you to define host groups and variables
differently than Ansible does with it's default text configuration.

This is totally fine, and why we added the external inventory script
-- to allow people to customize how they want to set things up to
their own preferences.

Is something like this possible with Ansible? Can I use ansible in
such a host-centric way? Where do I start?

This is what I've been talking about :slight_smile:

Puppet invented them, as far as I'm aware, and ours are very similar.

http://ansible.cc/docs/api.html#external-inventory-scripts

Or do you think that my view on configuration management is twisted
and I should wake up, unwind my head and embrace the ansible
paradigm? I would love to hear your arguments if you think that the
approach I described is inferior.

I think you're already in our paradigm, you just don't know it yet :slight_smile: