roles an funky playbooks

Hi,

I have a usecase for split-playbook but I still want to maintain it all under the same structure. In my case I’d like to split two phases “install” and “configure” but retain most of the vars etc. between two.

What I was thinking is having something like:

install.yml
config.yml
roles
_A
_tasks
_install.yml
_conig.yml
_B
_tasks
_install.yml
_config.yml

with install/config.yml looking something like:

  • hosts: Ahosts
    roles:

  • role: A

  • hosts: Bhosts
    roles:

  • role: B

so when I call ansible-playbook install.yml it will invoke install.yml for each role (instead of main.yml) and the same for “config.yml”.

I realize that something similar could be done with tags but resulting constructs become bit cumbersome IMO and one has to remember to use tags- otherwise entire execution will go in one sweep.

So in other words can I redefine what to call instead of main.yml for all roles at runtime?

I'd say use tags. That's what they are for. You could also
divide your roles up, so instead of 2 roles, you have four.

A/
  config/
     tasks/main.yml
   install/
      tasks/main.yml

B/
  config/
     tasks/main.yml
   install/
      tasks/main.yml

install.yml:

- hosts: Ahosts
  roles:
  - role: A/install

- hosts: Bhosts
  roles:
  - role: B/install

config.yml:

- hosts: Ahosts
  roles:
  - role: A/config

- hosts: Bhosts
  roles:
  - role: B/config

- James

that’s an interesting idea - didn’t realize roles can be nested like that.

tags have one disadvantage: out of multiple you can’t exclude one - instead you have to enumerate the rest. so if project already has some tags things become less… clear.

I like the nested stuff, thanks for the pointer!

However I believe I stepped on a bug there:

if I define variable “foo” in /group_vars/all and /roles/B/vars/main.yml interesting thing happens:

if prior to call to B/install tasks I call B tasks - “foo” gets populated with /roles/B/vars/main.yml, otherwise it picks up /group_vars/all

Dmitry,

Can you explain what you mean in more detail "if prior to call to
B/install tasks I call B tasks - "foo" gets populated with
/roles/B/vars/main.yml, otherwise it picks up /group_vars/all".

Examples of playbooks on github would be helpful.

Thanks,

James

there you go:

https://github.com/droopy4096/ansible-nested-roles

in https://github.com/droopy4096/ansible-nested-roles/blob/master/install.yml line “9” is the “trigger” line.

launch

ansible-playbook -v -u root -i inventory install.yml

and you’ll see that echo prints “Hello Darleks”, now comment above line 9 in install.yml and run the same… it’ll say “Hello people”

variable world is defined in several places group_vars/all (“people”) and roles/B/vars/main.yml (“Darleks”)

you see what I mean?

So a couple of things --

I don't think you want a

B/
   tasks/
   main/

For A and B, we established that there are 2 roles for each-- install
and configure. Even though they are sub directories to A & B, don't
inherit anything (as in, they don't get vars from the parent role
because there's no such thing). They are fully separate roles.

If you simply want to maintain different variables for different host
groups, you should be using group_vars/group_name which will supersede
group_vars/all.

In other words:

set
inventory/group_vars/all:
world: people

inventory/group_vars/B:
world: daleks

Tell me what you expect the output to be, and we can work to figure
out how to make it so.

- James

Even though they are sub directories to A & B, don’t
inherit anything (as in, they don’t get vars from the parent role
because there’s no such thing). They are fully separate roles.

not nitpicking, but out of curiosity - why then when I first call B role var gets substituted for B/install ? If what you’re saying is correct my experience suggests it’s an inconsistent behavior at the moment. Which is to say - I did not find information so far that would’ve helped me to predict such an outcome.

Tell me what you expect the output to be, and we can work to figure
out how to make it so.

in that particular case I was testing the waters to see whether “nested” roles would work and I can set common vars for “B/{install,configure}” instead of populating them either in both places or making a tighter fit between groups and roles (which we know are not always 1:1 match). From that little sample I see that the only way for me to set things up for both B/install and B/configure is to either make a design decision to keep group->role a 1:1 map (well more like 1:n but what’s important we can’t have same role applied to two different groups under those conditions).

In other words I was looking at nested roles more like OOP concept - to get common attributes I introduce common parent, but it’s not the case here.

Let me go back and review my design ideas and see whether I can find a different way of expressing what I need.

Thanks for bearing with me here as I’m trying to sort things out.