# Setting vars dynamically in command from stdout.  (like bcfg2 probes)

**URL:** <https://forum.ansible.com/t/setting-vars-dynamically-in-command-from-stdout-like-bcfg2-probes/11541>\
**Category:** Ansible Project\
**Created:** [May 12, 2012, 1:19pm UTC](https://forum.ansible.com/t/setting-vars-dynamically-in-command-from-stdout-like-bcfg2-probes/11541 "2012-05-12T13:19:09Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![kindly](https://avatars.discourse-cdn.com/v4/letter/k/b782af/32.png) [@kindly](https://forum.ansible.com/u/kindly)\
**Post date:** [May 12, 2012, 1:19pm UTC](https://forum.ansible.com/t/setting-vars-dynamically-in-command-from-stdout-like-bcfg2-probes/11541/1 "2012-05-12T13:19:09Z")

</div>

Hello

I have a use case where I want to create a user in a postgres database  
only if it does not exist. A separate module could be written for  
this but I think a general solution for this kind of situation makes  
sense.

My suggestion is to have a way to assign stdout to a variable to be  
used later on in the playbook. I think this could be added to command.  
As a very simple example (even though this is covered by facts/ohai).

command uname -i stdout\_var=architecture

So architecture can be used as var later on in the templates/  
conditionals.

This seems pretty trivial to implement, but does require a change to  
the runner code. I have made a quick hack attempt but it seems that  
currently the way to do this is to add these variables to setup\_cache,  
which is badly named, and the comments say it is going away anyway.

I would suggest that having a way for any module to add vars would be  
useful. So adding an optional

"extra\_vars" : {"var1" : "value", ...}

to any module result json/dict could make sense. This would mean that  
ohai/factor could use this and would not be a special case anymore.

I am happy to work on this and give you a patch, but want to make sure  
that you also think this kind of feature is valuable.

Thanks

David

---

<div class="post-metadata">

**Author:** ![Michael\_DeHaan](https://avatars.discourse-cdn.com/v4/letter/m/c4cdca/32.png) [@Michael\_DeHaan](https://forum.ansible.com/u/Michael_DeHaan)\
**Post date:** [May 12, 2012, 2:31pm UTC](https://forum.ansible.com/t/setting-vars-dynamically-in-command-from-stdout-like-bcfg2-probes/11541/2 "2012-05-12T14:31:09Z")

</div>

> My suggestion is to have a way to assign stdout to a variable to be  
> used later on in the playbook. I think this could be added to command.

This has been suggested before. It's a good idea, just being able to access a $last\_result  
variable per host.

In this case, stdout would actually be

${last\_result.stdout}

I'll file a ticket so we do this for 0.5

Already you can have a custom module return a dictionary called ansible\_facts, and create variables in this way, though it's a bit heavy handed for something like last\_result, which you may just as easily want to use from the command module.

> This seems pretty trivial to implement, but does require a change to  
> the runner code. I have made a quick hack attempt but it seems that  
> currently the way to do this is to add these variables to setup\_cache,  
> which is badly named, and the comments say it is going away anyway.

It has nothing to do with the runner code, and everything to do with playbooks.

It may or may not go away, that is to be determined. In any event, much refactoring is due in 0.5 that will change the way it all works quite a bit, as we expose Host objects directly into the core of Runner, Tasks become real objects, etc.

Each Host, if we do things right, will know the last command it executed and the result, without having to access the various hashes as it does now.

> I would suggest that having a way for any module to add vars would be  
> useful. So adding an optional
> 
> "extra\_vars" : {"var1" : "value", ...}
> 
> to any module result json/dict could make sense. This would mean that  
> ohai/factor could use this and would not be a special case anymore.

I don't understand how --extra-vars, which is a way of injecting variables into a playbook, would be relevant in a module.

---

<div class="post-metadata">

**Author:** ![kindly](https://avatars.discourse-cdn.com/v4/letter/k/b782af/32.png) [@kindly](https://forum.ansible.com/u/kindly)\
**Post date:** [May 12, 2012, 3:38pm UTC](https://forum.ansible.com/t/setting-vars-dynamically-in-command-from-stdout-like-bcfg2-probes/11541/3 "2012-05-12T15:38:59Z")

</div>

> In this case, stdout would actually be
> 
> ${last\_result.stdout}
> 
> I'll file a ticket so we do this for 0.5

That would be great. It could be useful though to hold onto a  
variable for the length of that host. Nonetheless, the 'creates'  
param in command is also a bit a hack due to namespacing issues i.e if  
a command has is own 'creates' param. So adding another one (such as  
stdout\_var) is probably bad practice.

The other solution is to pass on the whole stack of results. i.e $  
{results[-1].stdout} but I do not know how your parser or the jinja  
handles lists. The simple solution, as you suggested, would be good  
enough for most cases including mine.

> Already you can have a custom module return a dictionary called ansible\_facts, and create variables in this way, though it's a bit heavy handed for something like last\_result, which you may just as easily want to use from the command module.

Great, missed that. That is all I was after in with the extra\_vars  
that I mentioned.

---

<div class="post-metadata">

**Author:** ![Michael\_DeHaan](https://avatars.discourse-cdn.com/v4/letter/m/c4cdca/32.png) [@Michael\_DeHaan](https://forum.ansible.com/u/Michael_DeHaan)\
**Post date:** [May 12, 2012, 3:41pm UTC](https://forum.ansible.com/t/setting-vars-dynamically-in-command-from-stdout-like-bcfg2-probes/11541/4 "2012-05-12T15:41:19Z")

</div>

> > In this case, stdout would actually be
> > 
> > ${last\_result.stdout}
> > 
> > I’ll file a ticket so we do this for 0.5
> 
> That would be great. It could be useful though to hold onto a  
> variable for the length of that host. Nonetheless, the ‘creates’  
> param in command is also a bit a hack due to namespacing issues i.e if  
> a command has is own ‘creates’ param. So adding another one (such as  
> stdout\_var) is probably bad practice.

Creates doesn’t alter the variable space or have any sort of namespacing issues.  
It’s no different than any other type of parameter.

I don’t find it being a hack at all. I think it fulfills a decent use case.

> The other solution is to pass on the whole stack of results. i.e $  
> {results[-1].stdout} but I do not know how your parser or the jinja  
> handles lists. The simple solution, as you suggested, would be good  
> enough for most cases including mine.

Jinja is not relevant here, as it’s not guaranteed you only want it in a template… and Jinaj2 isn’t used except in templates in 0.4 (there are other ways  
to get variables).

We may offer up $last\_result in 0.5

TBD. Likely.

---

<div class="post-metadata">

**Author:** ![kindly](https://avatars.discourse-cdn.com/v4/letter/k/b782af/32.png) [@kindly](https://forum.ansible.com/u/kindly)\
**Post date:** [May 12, 2012, 4:14pm UTC](https://forum.ansible.com/t/setting-vars-dynamically-in-command-from-stdout-like-bcfg2-probes/11541/5 "2012-05-12T16:14:37Z")

</div>

> I don't find it being a hack at all. I think it fulfills a decent use case.

My point was that if I had a odd command line tool say

fake\_command.sh creates='2005-01-01'

was a valid way of using fake\_command.sh

So in this case.  
command /usr/bin/fake\_command.sh creates='2005-01-01'

the creates='2005-01-01' would not get passed to fake\_command.

Its such a minor edge case, and it definitely should be kept, just  
saying that a proliferation of these is probably bad.

---

<div class="post-metadata">

**Author:** ![Michael\_DeHaan](https://avatars.discourse-cdn.com/v4/letter/m/c4cdca/32.png) [@Michael\_DeHaan](https://forum.ansible.com/u/Michael_DeHaan)\
**Post date:** [May 12, 2012, 4:19pm UTC](https://forum.ansible.com/t/setting-vars-dynamically-in-command-from-stdout-like-bcfg2-probes/11541/6 "2012-05-12T16:19:42Z")

</div>

The module still sees it, so as long as it goes to the module, I don’t see it being so much as an edge case.

Anyway, the idea of returning a last\_result is generalizable to all modules, and would not be an argument you would pass to a module.

–Michael

---

<div class="post-metadata">

**Author:** ![kindly](https://avatars.discourse-cdn.com/v4/letter/k/b782af/32.png) [@kindly](https://forum.ansible.com/u/kindly)\
**Post date:** [May 12, 2012, 4:28pm UTC](https://forum.ansible.com/t/setting-vars-dynamically-in-command-from-stdout-like-bcfg2-probes/11541/7 "2012-05-12T16:28:55Z")

</div>

Yes the core code has no problems and your solution is definitely the  
cleanest.

Thanks for the excellent work on this, it is really a breath of fresh  
air compared to other config management software out there.
