Thanks for your reply (also thanks to James, btw). This might be getting slightly off-topic, but I'd really like to hear your opinion and see whether there is a more ansible-like way of doing this:
I am trying to avoid copy'n'paste as much as possible and created a few include files with tasks that I use in almost every role. For example, making sure a service is started and enabled, or defining reload/restart handlers -- and they all use the same logic of mapping "apache" to whatever the actual service name is on the OS ("apache2", "httpd", etc.), mapping package names etc. (discovering {{ansible_pkg_mgr}} made me switch to roles finally, btw, because apt/yum/portage was the (almost) only reason I needed group_by and multiple plays for different distros).
One of those common tasks is loading variables using include_vars with {{ansible_distribution}} or {{ansible_os_family}} (whichever vars-file exist), so it has to know the role's vars/ directory. With this, most of my {{role}}/tasks/main.yml become nicely clean and concise:
- include: ../../common/tasks/include_vars.yml
- include: ../../common/tasks/pkg_mgr.yml pkgs=foobar,libfoo
- include: ../../common/tasks/service.yml name=foobar
If the role is called foobar and only needs one package, I can even omit the name and pkgs parameters, and only define svc['foobar'] and pkg['foobar'] in vars/{{distro}}.yml if service or package name are different from "foobar".
Another common task is installing a new Apache vhost config. I am doomed to work with three different distros -- the <VirtualHost> snippet can be reused on every server, but the way it's installed is different. I am trying to avoid teaching all of my {{webapp}} roles how to install a vhost, and instead do something like
- include: ../../common/tasks/include_vars.yml role=apache
- include: ../../apache/tasks/vhost.yml
which then finds "apache_vhost.conf" in the current role's templates/ directory.