Advice on structuring playbooks and tasks

I am attempting to structure playbooks for reusability. Options seem to be:

  • playbooks can include other playbooks
  • playbooks can include tasks and handlers
  • playbooks can include tasks and handlers via ‘roles’

Since every playbook has to be bound to specific hosts, I’m looking at the other two options.

To start with I’ve factored out tasks and handlers. There can be a lot of actions in one related set of tasks. Here’s an example of a tasks file:

cat tasks/snmp/centos.yaml

You should definitely consider using roles in 1.2 and take a look at some organization examples in things like:

https://github.com/ansible/ansible-examples/blob/master/lamp_haproxy/site.yml

If you want to only runs parts of a playbook, yes, you have tags to do that. Though you seem to be more interested in the --interactive flag with --start-at-task for playbook control, so I recommend looking at those, but I like tags a lot.

We are not going to create something halfway between a playbook and a task file as that would be confusing, but hopefully between those two options you can get something you want.

Yes, tasks can reference other tasks, for instance in main.yml:

Tagging pretty much everything is tedious, but it also gives you really
fine-grained control over what you want to execute (if you need it, which
unfortunately i do). And it's just a one-time effort... I tag almost
everything and find myself using "--limit=<hosts> --tags=<tags>" for quick
iteration and testing of new stuff all the time.

That said, you _can_ do exactly what you want above... I have includes like
this in my playbooks and they work just fine:

- include: tasks/snmp/centos.yaml tags=snmp

Basically that implicitly adds the tag "snmp" to each item in centos.yaml.

matt

Yep, this works on roles too!

roles:

  • { role: foo, tags: [ ‘abc’, ‘def’ ], some_variable: 12, some_other_variable: 3000 }

i’m having trouble getting this syntax for restricting tasks inside of roles to a specified tag.

i have in a playbook:

roles:

  • { role: base, tags: [‘users’]}

and then base’s main.yml

[david@ops-1 provision{master}]$ cat roles/base/tasks/main.yml

Hi,

Afaik the tags parameter for include statements and roles is only for tagging (you tag each and every task inside it with this tag), not for filtering (what seems you want to do). Filtering is done by specifying --tags in the command line.

Although it is weird that with --tags “users” base_packages.yml gets skipped over. Shouldn’t it be also tagged with “users” because of the role statement?

Anyway, my approach is to use roles without tags and than the main.yml of each role contains only include statements tagged with all variations, eg: “tags=basic.ntp,base,ntp” (.,,) (the first tag contains a dot and simulates the missing “and” operation when you want to filter only the tasks that contain both tags). This way you can filter with --tags=basic for everything in this role, filter exact include statements inside roles with --tags=basic.ntp or just filter by all NTP related things through all roles --tags=ntp.

Greetings,
gw

Although it is weird that with --tags "users" base_packages.yml gets
skipped over. Shouldn't it be also tagged with "users" because of the role
statement?

Tags were specified later so they were overwritten.

GW is correct below, you must specify the tasks you want to run on the CLI.

Tags in the playbook are for applying tags, not restricting them, as that wouldn’t make sense.

GW is correct below, you must specify the tasks you want to run on the CLI.

Tags in the playbook are for applying tags, not restricting them, as that wouldn’t make sense.

Thanks all, that makes sense.

Thank you everyone for the replies. I’ll try refactoring into roles and applying tags at the role level or at the include: tasks level.

ansible-playbook --step and --start-at-task are both new to me and also look useful. I don’t have them in ansible 1.0 so maybe this is an excuse to upgrade to 1.2 :slight_smile:

Regards,

Brian.