applying sudo_user to a list of tasks

880 views
Skip to first unread message

Jerome Wagner

unread,
Jun 28, 2013, 11:35:21 AM6/28/13
to ansible...@googlegroups.com
Hello,

My playbook is run with sudo: yes
Inside this playbook, I would like to run a task list several times. Each time it would be for a different user.

for simplification, the task list could be:

tasks:
 - ping:
 - ping:
 - ping

I managed to write the task list as

tasks:
 - ping:
   sudo_user: {{ u }}
 - ping:
   sudo_user: {{ u }}
 - ping
   sudo_user: {{ u }}

and reuse this task list. But this does not seem right. I wish I could parametrize the sudo_user outside of the task list.

the "include" directive does not seem to accept a sudo_user parameter.

of course, the sudo_user can be set at the play level

 - hosts: all
   sudo: yes
   sudo_user: john
   roles:
     - developer

but is there any way i can "loop" over a play ; something in the order of :

 - hosts: all
   sudo: yes
   sudo_user: {{ item }}
   roles:
     - developer
   with_items:
     - john
     - dave

thank you very much for your insight !
Jerome





Michael DeHaan

unread,
Jun 28, 2013, 11:39:19 AM6/28/13
to ansible...@googlegroups.com
No, you can't do this.

You should do any looping inside of the task files.

Also, stuff like sudo_user: {{ item}} needs to be quoted, like so, sudo_user: "{{ item }}" since YAML will think the "{" is starting a hash.


Jerome





--
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.
For more options, visit https://groups.google.com/groups/opt_out.
 
 



--
Michael DeHaan <mic...@ansibleworks.com>
CTO, AnsibleWorks, Inc.
http://www.ansibleworks.com/

Jerome Wagner

unread,
Jun 28, 2013, 11:48:45 AM6/28/13
to ansible...@googlegroups.com
ok thank you I will try that.

it seems to me that in this case, each task will have to change the sudo user in a loop. It sounds like a lot of sudo user switching ( Number of task * Number of users in the loop) but why not.

what is the rationale behind your sentence "you should do any looping inside of the task files" ? is that a strong design decision to protect something else in the architecture or could it evolve at some point ?

thanks
Jerome

Michael DeHaan

unread,
Jun 28, 2013, 12:29:36 PM6/28/13
to ansible...@googlegroups.com
I'm not really sure why you need to ping as a sudo user from 3 different accounts, can you explain the use case before we start to figure out how to model it?  :)


Jerome Wagner

unread,
Jun 28, 2013, 4:32:20 PM6/28/13
to ansible...@googlegroups.com
Hello,
no ;-) the 3 pings where just for a simplified example of what I was trying to achieve. I confirm they are useless !

given a list of users (john, dave, ...) I want to setup several configs / applications in their /home dir.
I have 2 options :
 - install everything with sudo=yes and then try to correctly change all the ownership modes so that it appears as if the user had actually set up the environment
 - install everything with sudo=yes and sudo_user=item, so that the configuration / installation takes place under the correct user and all the ownership modes are immediatly correct

for example i want each user to start with its own installation of nvm with a pre-installed set of node.js versions

I hope this clarifies my use case. Maybe there are other ways to do this ?

Michael DeHaan

unread,
Jun 28, 2013, 4:57:29 PM6/28/13
to ansible...@googlegroups.com
I think this is ultimately about being able to pass sudo_user to a role and have it automatically apply that to all tasks in the role that don't have the "sudo_user" set.

Can't do that now, but then you could just have:

roles:
   - { role: install_things, user: bob, sudo_user: bob }
   - { role: install_things, user: sam, sudo_user: sam }


Jerome Wagner

unread,
Jun 29, 2013, 8:02:33 AM6/29/13
to ansible...@googlegroups.com
Hello,

yes, sudo_user at the role level could be a solution. Are you open for a patch on something like that ?

however, is there a way to iterate over the addition of roles in a play ? something like

roles:
   - { role: install_things, user: "{{item}}", sudo_user: "{{item}}" }
     with_items: userlist

in order to avoid repeating the same line with N users ?

Thank you
Jerome

Michael DeHaan

unread,
Jun 29, 2013, 2:25:37 PM6/29/13
to ansible...@googlegroups.com
Totally fine with sudo_user being acceptable as a role parameter and doing the right thing.

Include + with_items was a patch we got a long time ago that caused a lot of user questions because everybody wanted to use it with inventory variables, and tasks must exist prior to inventory being parsed, so no, I'm not ok with with_items being applied to roles like that.  The solution is to either list all the items out flat, or do the looping inside the tasks files.

Jerome Wagner

unread,
Jun 29, 2013, 4:09:28 PM6/29/13
to ansible...@googlegroups.com
ok thank you for the clarification
I will try to understand how the roles are implemented. 

I appreciate that you are totally fine with a patch as long as it does the right thing ;-)

thanks a lot for creating ansible and nurturing a great community btw !
Jerome

Jerome Wagner

unread,
Jul 5, 2013, 4:09:30 PM7/5/13
to ansible...@googlegroups.com
Hello,

I had a look at the code in order to see how we could add the sudo & sudo_user options at the role level just like so :

roles:
   - { role: install_things, user: bob, sudo_user: bob }
   - { role: install_things, user: sam, sudo_user: sam }

extract from the code:

if os.path.isfile(task):
                nt = dict(include=task, vars=has_dict)
                if when:
                    nt['when'] = when
                if with_items:
                    nt['with_items'] = with_items
                new_tasks.append(nt)


The problem I see is that the tasks of the role are injected in the play as an "include" task. So basically if we add the sudo/sudo_user at the role level, we would currently need to add it also at the "include" level in order for it to work.

Since you seemed to be against adding sudo/sudo_user at the include level, I prefer asking you what you think about this (and maybe I am wrong with my understanding of how the code actually works)

Thank you
Jerome

Michael DeHaan

unread,
Jul 5, 2013, 4:52:55 PM7/5/13
to ansible...@googlegroups.com
Yes!


Jerome Wagner

unread,
Jul 18, 2013, 6:59:29 PM7/18/13
to ansible...@googlegroups.com
Hello,

I understood the "Yes!" as a "go for it !".

Here is a pull request for the implementation of sudo/sudo_user at the role level (and and include level because roles are implemented as include tasks)


Usage is pretty straight forward :

 - include: myfile.yml
   sudo: yes
   sudo_user: tom

or
- hosts: all
  roles:
  - { role: myrole, sudo: yes, sudo_user: jerry }

As explained in the pull request comment, "the deepest setting encountered in the hierarchy of playbook/play/role/include/tasks is kept for any task below." which is I think the intuitive expectation.

I hope I didn't break anything.
Existing playbooks should be pretty safe since sudo/sudo_user were failing at the "include" level, and not extracted from the dict at the "role" level.

Best regards,
Jerome

Mark Mandel

unread,
Jul 18, 2013, 7:23:54 PM7/18/13
to ansible...@googlegroups.com
Nice!

I've wanted this for a while!

Thanks!

Mark

Michael DeHaan

unread,
Jul 18, 2013, 7:57:33 PM7/18/13
to ansible...@googlegroups.com
Merging a ton of bits and doing a lot of bug fixing on things this weekend, so hope to get to this soon.

Thanks!

Lorin Hochstein

unread,
Jul 18, 2013, 8:54:32 PM7/18/13
to ansible...@googlegroups.com
+1, me too. Looking forward to this new functionality.


Lorin


On Thu, Jul 18, 2013 at 7:23 PM, Mark Mandel <mark....@gmail.com> wrote:



--
Lorin Hochstein
Lead Architect - Cloud Services
Nimbis Services, Inc.
Reply all
Reply to author
Forward
0 new messages