ansible / proposals

Repository for sharing and tracking progress on enhancement proposals for Ansible.
Creative Commons Zero v1.0 Universal
93 stars 19 forks source link

provide an `ansible-role` tool similar to `ansible`, but to run specific role, not a task #131

Closed jhutar closed 5 years ago

jhutar commented 6 years ago

Proposal: provide an ansible-role tool similar to ansible, but to run specific role, not a task

Author: 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 using ansible-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

Dependencies (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.

h4xr commented 6 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.

chawlanikhil24 commented 6 years ago

+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.

amenonsen commented 6 years ago

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.

jhutar commented 6 years ago

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.

barlik commented 6 years ago

Another simpler option would be to allow: ansible localhost -m include_role -a name=myrole. This wouldn't require any new cli tool.

bcoca commented 5 years ago

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.

barlik commented 5 years ago

@bcoca Thank you for explanation. I've seen your commit and though to myself that this can't be that easy.

jhutar commented 5 years ago

Awesome, thank you!

ChristianCiach commented 5 years ago

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)
agaffney commented 5 years ago

Create an issue at https://github.com/ansible/ansible/issues for that

TheMeaningfulEngineer commented 4 years ago

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?

gavenkoa commented 3 years ago

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

brsolomon-deloitte commented 2 years ago

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.

sivel commented 2 years ago

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.

brsolomon-deloitte commented 2 years ago

@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."

bcoca commented 2 years ago

@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"
brsolomon-deloitte commented 2 years ago

@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.

bcoca commented 2 years ago

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
brsolomon-deloitte commented 2 years ago

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.

bcoca commented 2 years ago

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