Introducing role dependencies

2,298 views
Skip to first unread message

James Cammarata

unread,
Aug 16, 2013, 11:17:10 PM8/16/13
to ansible...@googlegroups.com
A new feature we will be introducing in 1.3 (and available now on the devel branch on github) are role dependencies. This allows roles to include other roles, and should allow for greater re-use of stock roles.

To create dependencies, just add a meta/ directory to your role with a main.yml file. As an example, if we had a "drupal" role, then the meta/main.yml file might contain something like this:

   ---
   dependencies:
   - { role: php, memory_limit: "128M" }
   - { role: web_server, http_port: 8080 }
   - { role: memcache, listen_address: "0.0.0.0" }

It is possible for dependent roles to have their own dependencies. Continuing the example above, the web_server role could have dependencies on nginx, fastcgi, and varnish roles. 

Note the variable passed in with the web_server role: http_port. That variable will be seen by any dependent roles too, so the nginx and varnish roles could use that variable in their configuration templates without having to set it themselves (or it will override the defaults stored in vars/main.yml for each role).

Dependent roles are executed before the role that requires them, so again continuing the example above, the order of execution would be:

 php -> nginx -> fastcgi -> varnish -> web_server -> memcache -> drupal

Last but not least, you can use fully qualified paths for the role names just like with regular role includes, so dependent roles do not have to be in the same directory as the playbook that uses them. For example:

   ---
   dependencies:
   - { role: "/path/to/common/roles/nginx" }

The docs on the website have been updated to include this information as well:


If you have any questions, let us know here or on IRC.

Enjoy!

--

James Cammarata <jcamm...@ansibleworks.com>
Sr. Software Engineer, AnsibleWorks, Inc.
http://www.ansibleworks.com/

Byron Schlemmer

unread,
Aug 17, 2013, 5:06:26 AM8/17/13
to ansible...@googlegroups.com
Hi,

Great timing, I was just looking for a way to do this!

Michael DeHaan

unread,
Aug 17, 2013, 11:23:03 AM8/17/13
to ansible...@googlegroups.com
Excellent James!

While not role dependency specific -- One very nice feature hiding under the hood in this patchset, that many people will like here is also a improvement in role variable scoping.   Previously if you had something in roles/x/vars/main.yml and something in roles/y/vars/main.yml, the last one loaded wins and could get applied to all roles, so you had to be careful with reusing variable names.   This could get confusing if both defined a variable named "port".

Now, that's still true for loose tasks as these vars are available later on down in the play, even if coming from other roles -- but within a role, the variables in roles/y/vars/main.yml are guaranteed to be applied to that specific role, just as if they were parameters explicitly passed to the role.  No surprises.   Moral of the story: use roles, roles are your friends!

As for role deps, a small caveat, which you may notice, is that this isn't really forming a dependency tree (this is on purpose!), it's instantiating those roles and applying them to form a nice flat list.   For instance, you can name a role something like "flush_memcache" and include it multiple times, and it will run multiple times.   There are use cases where that is useful of course.

For things like "apply a common config", don't do that with role dependencies, right now:

Just do:

roles:
   - common
   - myapp

And then let myapp pull in what it requires.

We probably need to add something in the role metadata that flags a role should only be included once (or once for this set of explicit role parameters) for these situations.  Like maybe "include_only_once: True".  However, definitely wanted to get everybody a chance to use that before we started making it too involved and that can be done later.

Very nice to see this, I know a lot of people have been asking for it.

   
 



--
You received this message because you are subscribed to the Google Groups "Ansible Project" group.
To unsubscribe from this group and stop receiving emails from it, send an email to ansible-proje...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.



--
Michael DeHaan <mic...@ansibleworks.com>
CTO, AnsibleWorks, Inc.
http://www.ansibleworks.com/

Brice Burgess

unread,
Oct 15, 2013, 2:40:29 PM10/15/13
to ansible...@googlegroups.com
On Saturday, August 17, 2013 10:23:03 AM UTC-5, Michael DeHaan wrote:

While not role dependency specific -- One very nice feature hiding under the hood in this patchset, that many people will like here is also a improvement in role variable scoping.   Previously if you had something in roles/x/vars/main.yml and something in roles/y/vars/main.yml, the last one loaded wins and could get applied to all roles, so you had to be careful with reusing variable names.   This could get confusing if both defined a variable named "port".



In the latest -master, variable definitions in a dependent role do not take precedence when the role is executed/activated as a dependency. I've posted a full example to a github repository here:
  https://github.com/briceburg/ansible-variable-scoping


Overview: The test_app role depends on the test_service role. A variable named shared_var exists between the two roles. When executing the playbook, the value of shared_var defined in test_app takes precedence regardless of the active role.

The two role var files are:
  https://github.com/briceburg/ansible-variable-scoping/blob/master/services/test_service/vars/main.yml
  https://github.com/briceburg/ansible-variable-scoping/blob/master/applications/test_app/vars/main.yml


You can run the test by checking out and executing ./test.sh


Github issue posted here:

  https://github.com/ansible/ansible/issues/4528
 










Michael DeHaan

unread,
Oct 15, 2013, 7:34:56 PM10/15/13
to ansible...@googlegroups.com
You didn't define "shared_var"  in a role though.

Roles get evaluated first and while they are guaranteed to be used, values loose in a playbook are not the same.





--
You received this message because you are subscribed to the Google Groups "Ansible Project" group.
To unsubscribe from this group and stop receiving emails from it, send an email to ansible-proje...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.

Brice Burgess

unread,
Oct 15, 2013, 10:39:01 PM10/15/13
to ansible...@googlegroups.com
Michael,

I believe I defined "shared_var" in *both* roles (using <role>/vars/main.yml). In fact, everything in my example is triggered via ansible's role include behavior  ; and I don't believe there's a "loose" playbook. The base playbook ( https://github.com/briceburg/ansible-variable-scoping/blob/master/application.yml ) simply includes the application role and all tasks & variable definitions are subsequently executed as expected (via <role>/tasks/main.yml).

To clarify I've updated the github repository's README as well as the issue. We expected that the active role variable definitions take precedence... which is not happening in our case [where the active role is executed as a _dependency_ ].

Thanks,

~ Brice

Michael DeHaan

unread,
Oct 16, 2013, 12:37:18 AM10/16/13
to ansible...@googlegroups.com
Sorry, this example is overly dense for a minimal reproduction example so it's hard to tell what's what.   And it's clear we don't quite communicate on the same wavelengths :)

Basically, distill something until it only shows the thing, and then it's much easier to understand.

I should expect you can replicate this in about 15 lines of playbook?



Michael DeHaan

unread,
Oct 16, 2013, 12:45:37 AM10/16/13
to ansible...@googlegroups.com
I've also replied to the ticket.

You're doing some confusing things with loading "vars_files" here, I don't think roles are to blame for variable clobbering here.

  vars_files:
    - ["applications/{{ namespace }}/vars/{{ branch }}.yml", "hosts/host_vars/_.yml"]

Also explicitly loading host_vars looks like a weird thing too.


Reply all
Reply to author
Forward
0 new messages