# shell/command json output into variables

**URL:** <https://forum.ansible.com/t/shell-command-json-output-into-variables/15665>\
**Category:** Ansible Project\
**Tags:** aws\
**Created:** [July 14, 2014, 3:15pm UTC](https://forum.ansible.com/t/shell-command-json-output-into-variables/15665 "2014-07-14T15:15:39Z")\
**Posts on this page:** 11\
**Page:** 1

<div class="post-metadata">

**Author:** ![Stuart\_Reynolds](https://avatars.discourse-cdn.com/v4/letter/s/90ced4/32.png) [@Stuart\_Reynolds](https://forum.ansible.com/u/Stuart_Reynolds)\
**Post date:** [July 14, 2014, 3:15pm UTC](https://forum.ansible.com/t/shell-command-json-output-into-variables/15665/1 "2014-07-14T15:15:39Z")

</div>

(1) Many command line tools (such as the aws CLI tools) output results directory as JSON. Is there a way to slurp up stdout and json-to-pydict it?  
In many cases this would be preferable to using modules which are i) highly coupled to fast-paced external code sources, ii) only implement a subset of the available functionality of tools they use.

(2) Better yet if I had a command that returned a result as a JSON-like object, can I (in my task/playbooks) run in-place python to filter/modify that?

---

<div class="post-metadata">

**Author:** ![Stuart\_Reynolds](https://avatars.discourse-cdn.com/v4/letter/s/90ced4/32.png) [@Stuart\_Reynolds](https://forum.ansible.com/u/Stuart_Reynolds)\
**Post date:** [July 14, 2014, 3:37pm UTC](https://forum.ansible.com/t/shell-command-json-output-into-variables/15665/2 "2014-07-14T15:37:26Z")

</div>

Re:(1) I’ve found that I can do this:

`

- hosts: localhost
- name: Describe instances  
hosts: localhost  
gather\_facts: false # Prevents immediately logging in to hosts  
tasks:
- command: aws ec2 describe-instances  
register: result
- debug: var=result.stdout|from\_json  
`  
However, really what I want to do is:

`

- hosts: localhost
- name: Describe instance  
hosts: localhost  
gather\_facts: **false** # Prevents immediately logging in to host  
tasks:
- command: aws ec2 describe-instances  
register: x=from\_json(result.stdout)
- debug: var=x

`  
Possible?

---

<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:** [July 14, 2014, 7:08pm UTC](https://forum.ansible.com/t/shell-command-json-output-into-variables/15665/3 "2014-07-14T19:08:15Z")

</div>

callback plugins exist in ansible for this purpose and there is the ‘–tree’ flag to ad-hoc /usr/bin/ansible mode.

However, we’re not really trying to be a system that emits arbitrary JSON as many playbooks will include results for multiple systems and this would get very very large and unwieldy.

---

<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:** [July 14, 2014, 7:15pm UTC](https://forum.ansible.com/t/shell-command-json-output-into-variables/15665/4 "2014-07-14T19:15:01Z")

</div>

Would it be possible to have an extra option to command to so that it  
can work similar to the uri module's "return\_content" option? That way  
results that are registered would be the same except for an extra json  
key with the structured data. Not sure what to call it as  
"return\_content" isn't particularly descriptive.

---

<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:** [July 14, 2014, 7:39pm UTC](https://forum.ansible.com/t/shell-command-json-output-into-variables/15665/5 "2014-07-14T19:39:19Z")

</div>

well it does return content already, all the stdout and such.

I think what you are saying is that have a flag that if the output of the command is already JSON and you requested this behavior, return the JSON datastructure in an element called “json”?

I’m somewhat open to it, but also think that because it’s possible to do the “from\_json” stuff with set fact, we have a bit of a solution, and it _might_ be used in such a minority set of use cases skimming over the option for most might cause greater confusion.  
I don’t know.

To be clear, I’m suggesting this:

- set\_fact:  
foo: “{{ x | from\_json }}”

Which I believe will keep data typed-ness if you use that form and not “foo=” on one line.

Would need to check.

---

<div class="post-metadata">

**Author:** ![Stuart\_Reynolds](https://avatars.discourse-cdn.com/v4/letter/s/90ced4/32.png) [@Stuart\_Reynolds](https://forum.ansible.com/u/Stuart_Reynolds)\
**Post date:** [July 14, 2014, 8:57pm UTC](https://forum.ansible.com/t/shell-command-json-output-into-variables/15665/6 "2014-07-14T20:57:13Z")

</div>

> well it does return content already, all the stdout and such.

I see – but I don’t see how to usefully use that in subsequent tasks (beyond debug).  
I can do:  
`  
register: result=std\_out|to\_json

`  
Or some such?

> I think what you are saying is that have a flag that if the output of the command is already JSON and you requested this behavior, return the JSON datastructure in an element called “json”?

Yes. That’s my specific problem.

More generally, it raises the question: how can I operate on the results of an action (in code I write in playbooks and tasks vs modules)? The scope of what’s possible isn’t clear to me from the docs. Can I say, filter a list of results (e.g. from ec2\_describe) and store the results in another list with an named value?

> I’m somewhat open to it, but also think that because it’s possible to do the “from\_json” stuff with set fact, we have a bit of a solution, and it _might_ be used in such a minority set of use cases skimming over the option for most might cause greater confusion.  
> I don’t know.
> 
> To be clear, I’m suggesting this:
> 
> - set\_fact:  
> foo: “{{ x | from\_json }}”

Doesn’t this only assign a fact to the target host?  
In many cases, that’s not the desired behavior. Suppose I want to collect a list of RDS instances ids by tag and perform simple operations on them over and over?

Being able to:

- add variables
- trigger conditions
- filter output, join lists… etc…

would be tremendously useful. I guess something like:

`

- hosts: localhost
- name: Describe instances  
hosts: localhost  
gather\_facts: false # Prevents immediately logging in to hosts  
tasks:
- command: aws ec2 describe-instances  
after: \>  
some python code to filter the results

some python code to register 5 groups

some python code to register 2 variables (register)

`

isn’t possible?

This is just an example, I’m already using ec2.py for much of this. But more fined-grained controlled is required (such as having tasks conditionally execute or wait on ec2\_instance states which may change in response to prior tasks).

- Stu

---

<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:** [July 15, 2014, 3:33pm UTC](https://forum.ansible.com/t/shell-command-json-output-into-variables/15665/7 "2014-07-15T15:33:37Z")

</div>

You cannot register the result of an expression.

See what was posted about “set\_fact” above, however.

---

<div class="post-metadata">

**Author:** ![Mark1](https://avatars.discourse-cdn.com/v4/letter/m/e0b2c6/32.png) [@Mark1](https://forum.ansible.com/u/Mark1)\
**Post date:** [November 3, 2014, 1:14pm UTC](https://forum.ansible.com/t/shell-command-json-output-into-variables/15665/8 "2014-11-03T13:14:10Z")

</div>

I was searching for exactly this feature. set\_fact doesn’t work for me because in my case i need to create AWS API keys for a newly created IAM user. The docs in set\_fact says that the new fact will be available between plays, which means those keys will be cached on disk which represents a security risk.

What I really would like is the same as the original poster - a way to get the stdout from the command module in a way that can be used later. E.g. after creating a new IAM user and registering the output as ‘iam’, and running:

- name: Create access keys for the new user  
local\_action: command aws iam create-access-key --user-name {{ iam.stack\_outputs.UserName }}  
register: keys

- name: debug keys  
debug: var=keys

I see:

ok: [localhost] =\> {  
“keys”: {  
“changed”: true,  
…  
“stdout”: “{\n "AccessKey": {\n "UserName": "MyUser-UMF4KM2DRQWQ", \n "Status": "Active", \n "CreateDate": "2014-11-03T12:52:44.458Z", \n "SecretAccessKey": "_ **", \n "AccessKeyId": "AK** _"\n }\n}”,

I’d like to then pass the SecretAccessKey and AccessKeyId into another cloudformation template as parameters. The simplest way would be if this json could be parsed by the ‘command’ module and made available as a dict.

Alternatively, is there any way of using ‘set\_fact’ in a transient mode so the fact won’t persist between invocations?

---

<div class="post-metadata">

**Author:** ![sivel](https://sea1.discourse-cdn.com/ansible/user_avatar/forum.ansible.com/sivel/32/1198_2.png) [@sivel](https://forum.ansible.com/u/sivel)\
**Post date:** [November 3, 2014, 1:26pm UTC](https://forum.ansible.com/t/shell-command-json-output-into-variables/15665/9 "2014-11-03T13:26:07Z")

</div>

I think you are misunderstanding terminology slightly.

Vars set with set\_fact will be across plays but not invocations of ansible.

A playbook can have multiple plays and multiple playbooks can be included and executed in 1 invocation of ansible.

set\_fact is in memory only, and will not persist between invocations.

---

<div class="post-metadata">

**Author:** ![Mark1](https://avatars.discourse-cdn.com/v4/letter/m/e0b2c6/32.png) [@Mark1](https://forum.ansible.com/u/Mark1)\
**Post date:** [November 3, 2014, 1:48pm UTC](https://forum.ansible.com/t/shell-command-json-output-into-variables/15665/10 "2014-11-03T13:48:55Z")

</div>

Ah OK. Yes, I understood “These variables will survive between plays” meant survive between invocations of ansible. If that’s not the case and the fact is not cached to disk, then I can go with that approach.

Thanks

---

<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:** [November 3, 2014, 2:35pm UTC](https://forum.ansible.com/t/shell-command-json-output-into-variables/15665/11 "2014-11-03T14:35:12Z")

</div>

“The docs in set\_fact says that the new fact will be available between plays, which means those keys will be cached on disk which represents a security risk.”

Yeah don’t assume that. Not the case.
