ansible-pull dynamic roles

917 views
Skip to first unread message

E.C. Raymond

unread,
Aug 22, 2014, 3:26:55 PM8/22/14
to ansible...@googlegroups.com
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

---
  - hosts: 127.0.0.1
    connection: local
    sudo: yes

    roles:
      - common
      - python
      - database

I previously found that trying to pass a list it to roles via command line or in the local.yml, doesnt work as it seems looping isnt supported for the roles stanza, only under tasks, and trying to pass --extra-vars from the command line to the local.yml file to roles is ignored.

Anyone else doing something similar to this in their environments?  We are trying to work with a master-less setup, but seems like its more of a challenge than using traditional playbooks.

Thanks.

Michael DeHaan

unread,
Aug 22, 2014, 5:15:20 PM8/22/14
to ansible...@googlegroups.com
"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.









--
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.
To post to this group, send email to ansible...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/ansible-project/16ecd8ef-51ac-4bd0-95bb-6fb0e0f29e8f%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

E.C. Raymond

unread,
Aug 26, 2014, 2:12:53 PM8/26/14
to ansible...@googlegroups.com
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.

E.C. Raymond

unread,
Aug 26, 2014, 2:58:35 PM8/26/14
to ansible...@googlegroups.com
When I test passing a list of roles in host_vars file

# host_vars/127.0.0.1
---
  myroles:
   - base_install
   - hadoop_datanode

# playbook.yml
..
roles: "{{ myroles }}"

It gives me the error:
ERROR: value of 'roles:' must be a list

# playbook.yml
..
roles: {{ item }}
with_items: myroles

ERROR: with_items is not a legal parameter in an Ansible Playbook

To verify I have an actual list, i ran a task to print in debug

TASK: [debug roles] ***********************************************************
ok: [127.0.0.1] => (item=base_install) => {
    "item": "base_install",
    "msg": "Role base_install"
}
ok: [127.0.0.1] => (item=hadoop_datanode) => {
    "item": "hadoop_datanode",
    "msg": "Role hadoop_datanode"
}

I am not sure how I can pass in a list to the roles stanza then.

Michael DeHaan

unread,
Aug 26, 2014, 6:59:33 PM8/26/14
to ansible...@googlegroups.com
"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.




--
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.
To post to this group, send email to ansible...@googlegroups.com.
Reply all
Reply to author
Forward
0 new messages