ansible-pull dynamic roles

I was wondering if there was a best practice for managing ansible-pull repos, specifically if there is a way to dynamically pass roles to an ansible-pull run. We have an external inventory system that can return roles assigned to a host. As in most environments, a host can belong to multiple roles, but it seems too messy to create single branches for each role to be checked out. I should be able to pull down a master branch with all roles intact, and allow the local.yml dictate which roles should be applied to the localhost.

Directory example

local.yml
roles
-common
- tasks,handlers, etc

-python
- tasks,handlers, etc
-database
- tasks,handlers, etc

local.yml

“way to dynamically pass roles”.

A good solution here might NOT be to not use ansible-pull. In most cases most people don’t need it if you are doing regular push based configuration.

If you do need it for something like autoscaling - let me recommend an alternative - ansible-tower provisioning callbacks can run a whole playbook using “–limit” to run against just the hosts that check in. As such, a playbook could target multiple groups and just the correct role<->group mappings would apply.

Ansible-pull is definitely going to continue to be a supported thing since it exists - but it’s not really NEEDED in most cases - and it’s not always the easiest way to get things done, and you lose all that centralized reporting you get from push mode, or even Tower in callback mode where the node can phone home and request configuration.

Now, one thing you could do is pass --extra-vars “role=foo”

and do

  • hosts: all
    roles:

  • group_by: key=role_{{rolename}}

  • hosts: role_foo
    roles:

  • foo

  • hosts: role_bar
    roles:

  • bar

And that would do it, with putting the right “–extra-vars” flag on the crontab entry.

Thanks for the input Michael! Ansible-pull isnt a requirement, but using a push based method seems to be difficult with our environment which has over 400 roles, and 2000+ servers. I have found that using local facts can help achieve what I am trying to accomplish, but wondering if there is a way to pull a list of roles from a host_var and feed to the roles stanza like:

roles:

  • {role: common, when: “‘base_install’ in ansible_local.hosts_roles.roles” }
  • {role: datanode, when: “‘hadoop_datanode’ in ansible_local.hosts_roles.roles”)

This is how I am currently determining what playbooks to run against the host. All playbooks are set to local run, to avoid a push based mechanism.

When I test passing a list of roles in host_vars file

host_vars/127.0.0.1

“Ansible-pull isnt a requirement, but using a push based method seems to be difficult with our environment which has over 400 roles, and 2000+ servers”

We have some users (admittedly somewhat more heterogenous to you) pushing to 5000 nodes with one box. You will be able to increase --forks to increase parallelism.

I also suspect if they are very heterogenous you may not want to batch manage them all at once for safety reasons anyway.