results from a multi-item Ansible task lacks the 'stdout_lines' attribute in the returned data structure

Hi Michael,

One of the pain points for us often times is the Ansible lack of the human-readable representability of the output of the task that has been run. A workaround up to now has been to use the debug: var=output.stdout_lines which while not perfect is at least more bearable in terms that one does not have to unwrap the ‘\n’ into the new lines in his mind while reading the output:

  • name: post-deployment tasks executed
    local_action: shell cd tasks; ls
    when: cf_post_deployment_tasks is defined
    register: post
    tags:

  • post-deploy

  • debug: var=post.stdout_lines
    tags:

  • post-deploy

TASK: [debug var=post.stdout_lines] *******************************************
ok: [localhost] => {
“item”: “”,
“post.stdout_lines”: [
“cf_app_remap.yml”,
“cf_deployment.yml”,
“concat_files.yml”,
“npm_install.yml”
]
}

However, once a task is a multi-item one, the returned data structure lacks the stdout_lines attribute:

  • name: post-deployment tasks executed
    local_action: shell {{ item }}
    with_items: cf_post_deployment_tasks
    when: cf_post_deployment_tasks is defined
    register: post
    tags:

  • cf

  • post-deploy

  • debug: var=post
    tags:

  • post-deploy

TASK: [debug var=post] ********************************************************
ok: [localhost] => {
“item”: “”,
“post”: {
“changed”: true,
“cmd”: "cd tasks; ls ",
“delta”: “0:00:00.004343”,
“end”: “2014-02-21 08:31:01.088304”,
“invocation”: {
“module_args”: “cd tasks; ls”,
“module_name”: “shell”
},
“item”: “”,
“rc”: 0,
“start”: “2014-02-21 08:31:01.083961”,
“stderr”: “”,
“stdout”: “cf_app_remap.yml\ncf_deployment.yml\nconcat_files.yml\nnpm_install.yml”,
“stdout_lines”: [
“cf_app_remap.yml”,
“cf_deployment.yml”,
“concat_files.yml”,
“npm_install.yml”
]
}
}

Could you tell if it’s something you would consider fixing if I create an issue on github?

Thanks,

With kind regards,
Roman

Sorry, posted wrong output for the multi-item task (too early in the morning I guess :-). Here’s the evidence the multi-item ‘results’ return data structure lacks the ‘stdout_lines’ attribute for the individual items:

TASK: [debug var=post] ********************************************************
ok: [localhost] => {
“item”: “”,
“post”: {
“changed”: true,
“msg”: “All items completed”,
“results”: [
{
“changed”: true,
“cmd”: "cd tasks; ls ",
“delta”: “0:00:00.006166”,
“end”: “2014-02-21 08:30:32.003038”,
“invocation”: {
“module_args”: “cd tasks; ls”,
“module_name”: “shell”
},
“item”: “cd tasks; ls”,
“rc”: 0,
“start”: “2014-02-21 08:30:31.996872”,
“stderr”: “”,
“stdout”: “cf_app_remap.yml\ncf_deployment.yml\nconcat_files.yml\nnpm_install.yml”
}
]
}
}

I’m not sure.

If the output is many pages long, that would be a lot of redundant data.

That being said, that is true of the original.

There could be a lot of redundant data if the output is many pages long even in the case of a one-item task - in the current implementation.
So I do not take your point on that one.

An alternative solution would be, of course to make Ansible to format the output in a human readable way on the user’s request. Then there would be no need in duplicating stdout with stdout_lines at all.

you have |pprint and |to_nice_json filters to make the output 'human friendly. I use this on debug: all the time.

Hey Brian,

Could you please provide an example (say based on the tasks I’ve posted earlier in my post), as I could not make use of those filters in ‘debug’ task.

Thank you!

its very simple:

  • debug: msg={{post|pprint}}

Hey Brian,

I do not think that the pprint filter on a multi-item task make the output any readable. Based on my previous example, if I do

  • name: post-deployment tasks executed
    local_action: shell {{ item }}
    with_items: cf_post_deployment_tasks
    when: cf_post_deployment_tasks is defined
    register: post
    tags:

  • cf

  • post-deploy

  • debug: msg=“{{ post | pprint }}”
    when: post is defined
    tags:

  • cf

  • post-deploy

and cf_post_deployment_tasks is a list of the following items:

cf_post_deployment_tasks:

  • cd tasks; ls
  • echo -e “blah blah blah\nsecond line”

I get:

TASK: [debug msg=“Undefined”] *************************************************
ok: [localhost] => {
“item”: “”,
“msg”: “{‘changed’: True,\n ‘msg’: ‘All items completed’,\n ‘results’: [{u’changed’: True,\n u’cmd’: u’cd tasks; ls ‘,\n u’delta’: u’0:00:00.004785’,\n u’end’: u’2014-02-21 15:17:40.739631’,\n ‘invocation’: {‘module_args’: u’cd tasks; ls’,\n ‘module_name’: ‘shell’},\n ‘item’: ‘cd tasks; ls’,\n u’rc’: 0,\n u’start’: u’2014-02-21 15:17:40.734846’,\n u’stderr’: u’‘,\n u’stdout’: u’cf_app_remap.yml\ncf_app_route.yml\ncf_deployment.yml\nconcat_files.yml\nnpm_install.yml’},\n {u’changed’: True,\n u’cmd’: u’echo -e blah”
}

If I use the item-by-item approach to output, that is

  • debug: msg=“{{ item | pprint }}”
    when: post is defined
    with_items: post.results
    tags:
  • cf
  • post-deploy

the output is lengthier and still a mess:

TASK: [debug msg=“‘’”] ********************************************************
ok: [localhost] => (item={‘item’: ‘cd tasks; ls’, u’delta’: u’0:00:00.004356’, u’cmd’: u’cd tasks; ls ‘, u’end’: u’2014-02-21 15:18:59.617802’, u’stderr’: u’‘, u’stdout’: u’cf_app_remap.yml\ncf_app_route.yml\ncf_deployment.yml\nconcat_files.yml\nnpm_install.yml’, ‘invocation’: {‘module_name’: ‘shell’, ‘module_args’: u’cd tasks; ls’}, u’changed’: True, u’rc’: 0, u’start’: u’2014-02-21 15:18:59.613446’}) => {
“item”: {
“changed”: true,
“cmd”: "cd tasks; ls ",
“delta”: “0:00:00.004356”,
“end”: “2014-02-21 15:18:59.617802”,
“invocation”: {
“module_args”: “cd tasks; ls”,
“module_name”: “shell”
},
“item”: “cd tasks; ls”,
“rc”: 0,
“start”: “2014-02-21 15:18:59.613446”,
“stderr”: “”,
“stdout”: “cf_app_remap.yml\ncf_app_route.yml\ncf_deployment.yml\nconcat_files.yml\nnpm_install.yml”
},
“msg”: “{u’changed’: True,\n u’cmd’: u’cd tasks; ls ‘,\n u’delta’: u’0:00:00.004356’,\n u’end’: u’2014-02-21 15:18:59.617802’,\n ‘invocation’: {‘module_args’: u’cd tasks; ls’, ‘module_name’: ‘shell’},\n ‘item’: ‘cd tasks; ls’,\n u’rc’: 0,\n u’start’: u’2014-02-21 15:18:59.613446’,\n u’stderr’: u’‘,\n u’stdout’: u’cf_app_remap.yml\ncf_app_route.yml\ncf_deployment.yml\nconcat_files.yml\nnpm_install.yml’}”
}
ok: [localhost] => (item={‘item’: ‘echo -e “blah blah blah\nsecond line”’, u’delta’: u’0:00:00.003149’, u’cmd’: u’echo -e “blah blah blah\nsecond line” ‘, u’end’: u’2014-02-21 15:18:59.703624’, u’stderr’: u’‘, u’stdout’: u’-e blah blah blah\nsecond line’, ‘invocation’: {‘module_name’: ‘shell’, ‘module_args’: u’echo -e “blah blah blah\nsecond line”‘}, u’changed’: True, u’rc’: 0, u’start’: u’2014-02-21 15:18:59.700475’}) => {
“item”: {
“changed”: true,
“cmd”: "echo -e "blah blah blah\nsecond line" ",
“delta”: “0:00:00.003149”,
“end”: “2014-02-21 15:18:59.703624”,
“invocation”: {
“module_args”: “echo -e "blah blah blah\nsecond line"”,
“module_name”: “shell”
},
“item”: “echo -e "blah blah blah\nsecond line"”,
“rc”: 0,
“start”: “2014-02-21 15:18:59.700475”,
“stderr”: “”,
“stdout”: “-e blah blah blah\nsecond line”
},
“msg”: “{u’changed’: True,\n u’cmd’: u’echo -e blah”
}

+ 1 for Romans issue.

I also find the output of debug to be highly irritating and the missing stdout_lines attribute on multi-item tasks void the only possible way of getting human readable output.

Hey Florian,

Thanks for your support on this issue.
I have meanwhile discovered that there is an alternative way to handle the output and format it to your liking by using callback plugins, here’s a couple of good examples on how to use this feature:

http://blog.cliffano.com/2014/04/06/human-readable-ansible-playbook-log-output-using-callback-plugin

http://jpmens.net/2012/09/11/watching-ansible-at-work-callbacks

It obviously has some drawbacks - such as one would need to reimplement the highlighting etc, but it’s at least something to workaround the issue.
Hope that helps.

Best regards,
Roman