Closed jhutar closed 5 years ago
+1 to the proposal It will help a lot while trying to debug as well as when someone just wants to run a single role. Saves a lot of time to write a playbook which just acts as a boilerplate with only one role involved in the execution.
+1 to the proposal This type of feature is required to debug ansible-playbooks when they in development stage. Moreover, in a production playbook as well, to skip some tasks/roles, I've to comment them. This will definitely help when one particular role is a concern when there is a very long series of tasks to be done and debugged.
I'm trying to write mine code in roles, but often I find myself creating a playbook which only uses one role.
I think writing a playbook that uses one role is exactly the appropriate
thing to do. Otherwise ansible-role
would either have arbitrary and
weird limitations, or have to grow numerous options to allow things like
setting "gather_facts" and "serial" and various other things you expect
to be able to do in a playbook. (Not to mention the risk of a role that
is written to be run with various options specified that does something
undesirable if someone runs it without all of the correct options.)
Plus it's already possible to set tags on roles and use --tags foo to execute only one role in a playbook.
I think writing a playbook that uses one role is exactly the appropriate thing to do. Otherwise
ansible-role
would either have arbitrary and weird limitations, or have to grow numerous options to allow things like setting "gather_facts" and "serial" and various other things you expect to be able to do in a playbook. (Not to mention the risk of a role that is written to be run with various options specified that does something undesirable if someone runs it without all of the correct options.) Plus it's already possible to set tags on roles and use --tags foo to execute only one role in a playbook.
I agree it would require lots of options to be perfect, but IMO it is same as ansible
for ad-hoc tasks - you do not write a playbook when you want to execute one task.
Adding tags for roles into a playbook is possible, but it often feels bit redundant - to achieve what I'm talking about it means to basically duplicate role name (as a tag name). It would not allow you to specify hosts to run on - say you have do_something
role in webservers.yaml
playbook, but just to try something you want to run it on your DB servers.
Another simpler option would be to allow: ansible localhost -m include_role -a name=myrole
.
This wouldn't require any new cli tool.
This was not easy to do, kudos to @sivel for making the changes that made this possible.
The PR above removes the 'nice error' we had before to avoid the nastier crashes that used to appear, but the real work was done before in the revamping of include/import code.
@bcoca Thank you for explanation. I've seen your commit and though to myself that this can't be that easy.
Awesome, thank you!
This worked with Ansible 2.7, but is broken with 2.8.0 for me:
$ ansible all -i hosts.yml -m include_role -a "name=myrole"
ERROR! 'async_val' is not a valid attribute for a IncludeRole
The error appears to be in 'None': line 0, column 0, but may
be elsewhere in the file depending on the exact syntax problem.
(could not open file to display line)
Create an issue at https://github.com/ansible/ansible/issues for that
There was an unofficial attempt to get this functionality in a (personal opinion :)) cleaner way than -m include_role -a "name=<role_name>"
.
The archived repo is here: https://github.com/larsks/ansible-toolbox
I've used it a bit and it makes ansible development so much simpler.
Perhaps there is a better approach to this problem problem lurking there?
It is possible to run not only the role but specific task with: ansible -m include_tasks -a file=tasks/create-os-user.yml all
A note to readers: while was re-fixed in cd95843, this invocation with
$ ansible name-of-hostgroup -m include_role -a "name=role-name-here"
will not implicitly gather facts; so, if you have a role with a task that references something like ansible_date_time
, this invocation will fail. I'm not sure if there's a workaround to that; it seems like you'd just need to use an 'entry-point' playbook instead, as is traditionally done with ansible-playbook
, where the invoked playbook points to a role.
I'm not sure if there's a workaround to that;
Put a gather_facts
/setup
task in your role that is conditionally run on whether or not a fact you need is available or not.
@sivel appreciate the tip, but seems a little over-engineered in my personal opinion.
@jhutar's original proposal makes a lot of sense to me given that it's such a common scenario to use an "entry-point" playbook invoked with ansible-playbook
that serves to map a role or roles to an inventory group.
- hosts: xxxx
roles:
- role: zzzz
From the perspective of doing development of roles, it's a bit clunky to document "oh, but you'll also need to stitch together a three-line boilerplate playbook to actually run this thing against a series of managed nodes."
@brsolomon-deloitte that is not what he is saying, you can have a task on top of your role:
- gather_facts:
when: "'myfact' not in ansible_facts"
@bcoca I'm following the suggestion, I just think it seems a bit brittle that the answer to something that was originally aiming at simplifying an invocation of a role ended up in needing to add an explicit gather_facts
into the role's tasks.
I would argue you still need it in the case of a playbook/ansible.cfg that disable gathering by default, either that or use role argspec to ensure you have the required variables.
- hosts: all
gather_facts: false
roles:
- rolethatneedsfacts
I would argue you still need it in the case of a playbook/ansible.cfg that disable gathering by default, either that or use role argspec to ensure you have the required variables.
I guess that's fair, though in my experience turning off the implicit fact gathering is the exception not the norm. If the proposal here was implemented in some way and someone then chose to shoot themselves in the foot by invoking that with ANSIBLE_GATHERING=explicit ansible-role ...
, and the role fails because it needs a certain fact, then that's on them, and doesn't diminish the value of having a dedicated and formally documented way to run roles from the command line in a concise fashion.
which we have, but for your use case it just happens to require facts and you need to make those available, either using the fact cache and/or having the role ensure the gathering.
In any case the ansible-role proposal had nothing about fact gathering, i would say this is more of a request to add the ability to adhoc
to also be able to gather facts before running the task indicated. https://github.com/ansible/ansible/pull/75678
Proposal: provide an
ansible-role
tool similar toansible
, but to run specific role, not a taskAuthor: Jan Hutar <@jhutar> IRC: jhutar
Date: 2018-07-20
Motivation
It is possible to run ad-hoc task using
ansible
tool. It is possible to run a playbook usingansible-playbook
, but it is not possible to run a role. I'm trying to write mine code in roles, but often I find myself creating a playbook which only uses one role.Problems
What problems exist that this proposal will solve?
Solution proposal
ansible-role -i inventory.ini -e "port=80" role_name webservers
which would allow me to run "ad-hoc" roleDependencies (optional)
Explain any dependencies. This section is optional but could be helpful.
Testing (optional)
Does / should this require testing, and if so, how? Describe here. This section is optional but could be helpful.
Documentation (optional)
Does / should this require documentation? If so, describe here. This section is optional but could be helpful.
Anything else?
If you'd like to add anything else beyond the above required and optional sections, you are welcome to do so.