# Run a command on just 1 server (like pause)

**URL:** <https://forum.ansible.com/t/run-a-command-on-just-1-server-like-pause/15239>\
**Category:** Ansible Project\
**Created:** [May 14, 2014, 9:07pm UTC](https://forum.ansible.com/t/run-a-command-on-just-1-server-like-pause/15239 "2014-05-14T21:07:02Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![Michael\_Peters](https://avatars.discourse-cdn.com/v4/letter/m/c2a13f/32.png) [@Michael\_Peters](https://forum.ansible.com/u/Michael_Peters)\
**Post date:** [May 14, 2014, 9:07pm UTC](https://forum.ansible.com/t/run-a-command-on-just-1-server-like-pause/15239/1 "2014-05-14T21:07:02Z")

</div>

I feel like I'm missing something, but I couldn't find it in the  
documentation. Please feel free to RTFM me.

I was just playing around with the pause module in a playbook and  
noticed that it only ran on a single host no matter how many hosts  
were being executed in the play. That makes sense because pausing on  
multiple machines would just be silly.

The real question is how do I do that explicitly in my own tasks? I  
have a lot of places in playbooks where I have data that needs to be  
inserted on some centralized storage (like a database or files on an  
NFS server, etc). At best this data is pointless to insert/update  
multiple times. And most of the time it's difficult to make sure it's  
done in a idempotent way (think ALTER statements in SQL migrations).

Currently I deal with this by breaking up my playbook into multiple  
plays where most of the tasks are in parallel, then another play is  
done in serial with just 1 host at a time with some pre-condition  
checks to see if it needs to be run and skipping it when it doesn't.  
This has the effect of the first host through the serial section does  
the work and every other host gets a turn to waste cycles checking  
that it actually happened. Then after the "critical section" is done  
the rest of the tasks are done in a parallel play.

If I could just explicitly label a task as "just run this on the first  
server in the group" like the pause module does I'd be really happy.

---

<div class="post-metadata">

**Author:** ![adam2](https://avatars.discourse-cdn.com/v4/letter/a/ecae2f/32.png) [@adam2](https://forum.ansible.com/u/adam2)\
**Post date:** [May 14, 2014, 9:21pm UTC](https://forum.ansible.com/t/run-a-command-on-just-1-server-like-pause/15239/2 "2014-05-14T21:21:58Z")

</div>

By default, ansible looks for tasks in $PWD. tasks are sent to the remote host, and don't run local.

If you create ansible.cfg in $PWD, and override defaults.library, then you can have local modules; these run on the local machine.

The following works when ansible is installed thru a package manager(I use debian):

cat $work\_tree/ansible.cfg

---

<div class="post-metadata">

**Author:** ![Michael\_DeHaan1](https://avatars.discourse-cdn.com/v4/letter/m/5e9695/32.png) [@Michael\_DeHaan1](https://forum.ansible.com/u/Michael_DeHaan1)\
**Post date:** [May 14, 2014, 10:15pm UTC](https://forum.ansible.com/t/run-a-command-on-just-1-server-like-pause/15239/3 "2014-05-14T22:15:34Z")

</div>

The multiple play method is correct because the tasks would not be executed for every host in the host loop.

Pause is a bit of an exception.

(Sidenote, it appears Adam is replying to another question above I think?)

---

<div class="post-metadata">

**Author:** ![adam2](https://avatars.discourse-cdn.com/v4/letter/a/ecae2f/32.png) [@adam2](https://forum.ansible.com/u/adam2)\
**Post date:** [May 14, 2014, 10:23pm UTC](https://forum.ansible.com/t/run-a-command-on-just-1-server-like-pause/15239/4 "2014-05-14T22:23:46Z")

</div>

Nope, to this one. If you want to run something on the current machine, where ansible is running, you need to write a module, which would reside in the library. Ansible doesn't look in $PWD for modules, like it does for tasks.

If you are running a module on the local machine, then you can do things like pause does, where it only runs once.

---

<div class="post-metadata">

**Author:** ![Michael\_DeHaan1](https://avatars.discourse-cdn.com/v4/letter/m/5e9695/32.png) [@Michael\_DeHaan1](https://forum.ansible.com/u/Michael_DeHaan1)\
**Post date:** [May 14, 2014, 11:46pm UTC](https://forum.ansible.com/t/run-a-command-on-just-1-server-like-pause/15239/5 "2014-05-14T23:46:33Z")

</div>

“Nope, to this one. If you want to run something on the current machine, where ansible is running, you need to write a module, which would reside in the library. Ansible doesn’t look in $PWD for modules, like it does for tasks.”

I think you’re confused about the question. The question was about how to run one task, in the middle of a series of multi-host tasks, on just one host, and then resume running steps on a wide array of hosts.

The OP should not be seeking to write a module to solve the above.

---

<div class="post-metadata">

**Author:** ![Michael\_Peters](https://avatars.discourse-cdn.com/v4/letter/m/c2a13f/32.png) [@Michael\_Peters](https://forum.ansible.com/u/Michael_Peters)\
**Post date:** [May 15, 2014, 2:25pm UTC](https://forum.ansible.com/t/run-a-command-on-just-1-server-like-pause/15239/6 "2014-05-15T14:25:01Z")

</div>

> The multiple play method is correct because the tasks would not be executed  
> for every host in the host loop.

Well, then maybe I'm doing it wrong. How do you tell a play to just  
execute on one host in the host loop?  
Right now I run the "critical section" play with a serial of 1 and try  
to leave some indicator that it was run (which is sometimes harder  
than others) and then the subsequent hosts skip the tasks in the place  
after they detect they weren't the first to try.

So my approach is still wasteful since I know ahead of time that it's  
only ever going to run once but every host in the loop besides the  
first one has to detect the skip condition and skip every task in  
serial.

> Pause is a bit of an exception.

Does it have to be an exception? Can we expose that functionality to  
other tasks or plays? I'd be willing to help with coding something if  
you think it's worth it.

---

<div class="post-metadata">

**Author:** ![Ernest0x](https://avatars.discourse-cdn.com/v4/letter/e/ed655f/32.png) [@Ernest0x](https://forum.ansible.com/u/Ernest0x)\
**Post date:** [May 15, 2014, 3:33pm UTC](https://forum.ansible.com/t/run-a-command-on-just-1-server-like-pause/15239/7 "2014-05-15T15:33:37Z")

</div>

If a play acts on all hosts in 'somegroup' group, you can restrict a  
task in that play to run only on the first host in the group by adding  
the following conditional:

when: inventory\_hostname == groups["somegroup"][0]

---

<div class="post-metadata">

**Author:** ![Michael\_Peters](https://avatars.discourse-cdn.com/v4/letter/m/c2a13f/32.png) [@Michael\_Peters](https://forum.ansible.com/u/Michael_Peters)\
**Post date:** [May 15, 2014, 3:51pm UTC](https://forum.ansible.com/t/run-a-command-on-just-1-server-like-pause/15239/8 "2014-05-15T15:51:50Z")

</div>

Thanks, that actually helps a lot. Although, it does litter all my  
tasks in the "critical section" play with that conditional and makes  
existing conditionals more complex.

It would still be cleaner to have an option on the play itself and/or  
individual tasks. I know there's some hesitation to add new keywords  
(which is good imo) but this seems common enough for lots of  
update/deployment scenarios. I'd be willing to code something like  
that if there's any interest in seeing it

---

<div class="post-metadata">

**Author:** ![Michael\_DeHaan1](https://avatars.discourse-cdn.com/v4/letter/m/5e9695/32.png) [@Michael\_DeHaan1](https://forum.ansible.com/u/Michael_DeHaan1)\
**Post date:** [May 15, 2014, 6:18pm UTC](https://forum.ansible.com/t/run-a-command-on-just-1-server-like-pause/15239/9 "2014-05-15T18:18:40Z")

</div>

See discussion here: [https://github.com/ansible/ansible/pull/7421](https://github.com/ansible/ansible/pull/7421)
