Hello community!
Question, it is a little hard for me to read the ansible-navigator output. Looks like variables are serialized and the whole text is printed in a single line with \n. Worse when it is a json/code output. Is there a best practice for avoid this behavior? Maybe a filter that beautify the var? {{x|beautify}}
For example:
- hosts: servera.lab.example.com
become: yes
tasks:
- command:
cmd: head /etc/passwd
register: x
- debug:
msg: "{{x['stdout']}}"
# var: x['stdout']
this returns:
ok: [servera.lab.example.com] => {
"msg": "root:x:0:0:root:/root:/bin/bash\nbin:x:1:1:bin:/bin:/sbin/nologin\ndaemon:x:2:2:daemon:/sbin:/sbin/nologin\nadm:x:3:4:adm:/var/adm:/sbin/nologin\nlp:x:4:7:lp:/var/spool/lpd:/sbin/nologin\nsync:x:5:0:sync:/sbin:/bin/sync\nshutdown:x:6:0:shutdown:/sbin:/sbin/shutdown\nhalt:x:7:0:halt:/sbin:/sbin/halt\nmail:x:8:12:mail:/var/spool/mail:/sbin/nologin\noperator:x:11:0:operator:/root:/sbin/nologin"
}
this does not happen in the core version:
[adouser@adoocp ansible]$ ansible servera.lab.example.com -a 'head /etc/passwd'
servera.lab.example.com | CHANGED | rc=0 >>
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
sync:x:5:0:sync:/sbin:/bin/sync
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
operator:x:11:0:operator:/root:/sbin/nologin
[adouser@adoocp ansible]$
Well, first off, you're comparing the ansible ad-hoc command to ansible-navigator. Really, a better comparison would be between ansible-playbook and ansible-navigator (with -m stdout) because they have similar output modes.
You're looking at the raw JSON content of the x['stdout'] variable. If you parsed just the contents of the variable through a JSON processor, you'd get what you're expecting. But the CLI tools don't present those contents that way, which in theory should make it easier for you to figure out how to parse those contents with Jinja2 templates and JSON filters in your play.
For ansible, if you'd had two hosts you might have gotten something like this:
a.lab.example.com | CHANGED | rc=0 >>
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
sync:x:5:0:sync:/sbin:/bin/sync
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
operator:x:11:0:operator:/root:/sbin/nologin
b.lab.example.com | CHANGED | rc=0 >>
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
sync:x:5:0:sync:/sbin:/bin/sync
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
operator:x:11:0:operator:/root:/sbin/nologin
...which is human-readable, mostly, but hard to tease the hosts apart. It's definitely not raw JSON.
If you're just trying to simply view the content in the output and you don't care about some extra characters, then try using x['stdout_lines'] instead. It'll break stdout into a list of lines, but the way the command displays the JSON output in stdout mode might be more legible as a side-effect.
For ansible-playbook or ansible-navigator -m stdout with the playbook like this:
- name: Pretty output
hosts: all
become: false
gather_facts: false
tasks:
- name: Register a variable with the results
ansible.builtin.command:
cmd: head /etc/passwd
register: x
- name: Print the contents of the variable
ansible.builtin.debug:
var: x['stdout_lines']
Then you'd get output like this instead:
TASK [Print the contents of the variable] **************************************
ok: [a.lab.example.com] => {
"x['stdout_lines']": [
"root:x:0:0:root:/root:/bin/bash",
"bin:x:1:1:bin:/bin:/sbin/nologin",
"daemon:x:2:2:daemon:/sbin:/sbin/nologin",
"adm:x:3:4:adm:/var/adm:/sbin/nologin",
"lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin",
"sync:x:5:0:sync:/sbin:/bin/sync",
"shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown",
"halt:x:7:0:halt:/sbin:/sbin/halt",
"mail:x:8:12:mail:/var/spool/mail:/sbin/nologin",
"operator:x:11:0:operator:/root:/sbin/nologin"
]
}
ok: [b.lab.example.com] => {
"x['stdout_lines']": [
"root:x:0:0:root:/root:/bin/bash",
"bin:x:1:1:bin:/bin:/sbin/nologin",
"daemon:x:2:2:daemon:/sbin:/sbin/nologin",
"adm:x:3:4:adm:/var/adm:/sbin/nologin",
"lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin",
"sync:x:5:0:sync:/sbin:/bin/sync",
"shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown",
"halt:x:7:0:halt:/sbin:/sbin/halt",
"mail:x:8:12:mail:/var/spool/mail:/sbin/nologin",
"operator:x:11:0:operator:/root:/sbin/nologin"
]
}
If you're planning to have the playbook parse this output in some way, then that depends on what you want to do with the data.
Here's another option for you: use ansible-navigator in interactive mode rather than stdout mode: ansible-navigator run playbook.yml -m interactive
In that case, navigate the TUI and look at the output of the play. It looks more readable in that mode. I'm going to try to include some screenshots here:
Run the playbook. You get the results of the only play in the playbook as item 0:
Press 0 to get the results of each task in that play for each host:
Press 2 to get the results of the servera "Print the contents of the variable" task:
That might also be a reasonable way to see what you want with ansible-navigator. This example used the variable x['stdout'] instead of x['stdout_lines'], by the way.
As a side note, as a style thing that first ansible.builtin.command task doesn't change anything ever by running head. So I'd probably change that task to
- name: Register a variable with the results
ansible.builtin.command:
cmd: head /etc/passwd
register: x
changed_when: false
to suppress the "changed" notices that aren't real.
Well, first off, you're comparing the ansible ad-hoc command to ansible-navigator. Really, a better comparison would be between ansible-playbook and ansible-navigator (with -m stdout) because they have similar output modes.
You're looking at the raw JSON content of the x['stdout'] variable. If you parsed just the contents of the variable through a JSON processor, you'd get what you're expecting. But the CLI tools don't present those contents that way, which in theory should make it easier for you to figure out how to parse those contents with Jinja2 templates and JSON filters in your play.
For ansible, if you'd had two hosts you might have gotten something like this:
a.lab.example.com | CHANGED | rc=0 >>
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
sync:x:5:0:sync:/sbin:/bin/sync
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
operator:x:11:0:operator:/root:/sbin/nologin
b.lab.example.com | CHANGED | rc=0 >>
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
sync:x:5:0:sync:/sbin:/bin/sync
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
operator:x:11:0:operator:/root:/sbin/nologin
...which is human-readable, mostly, but hard to tease the hosts apart. It's definitely not raw JSON.
If you're just trying to simply view the content in the output and you don't care about some extra characters, then try using x['stdout_lines'] instead. It'll break stdout into a list of lines, but the way the command displays the JSON output in stdout mode might be more legible as a side-effect.
For ansible-playbook or ansible-navigator -m stdout with the playbook like this:
- name: Pretty output
hosts: all
become: false
gather_facts: false
tasks:
- name: Register a variable with the results
ansible.builtin.command:
cmd: head /etc/passwd
register: x
- name: Print the contents of the variable
ansible.builtin.debug:
var: x['stdout_lines']
Then you'd get output like this instead:
TASK [Print the contents of the variable] **************************************
ok: [a.lab.example.com] => {
"x['stdout_lines']": [
"root:x:0:0:root:/root:/bin/bash",
"bin:x:1:1:bin:/bin:/sbin/nologin",
"daemon:x:2:2:daemon:/sbin:/sbin/nologin",
"adm:x:3:4:adm:/var/adm:/sbin/nologin",
"lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin",
"sync:x:5:0:sync:/sbin:/bin/sync",
"shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown",
"halt:x:7:0:halt:/sbin:/sbin/halt",
"mail:x:8:12:mail:/var/spool/mail:/sbin/nologin",
"operator:x:11:0:operator:/root:/sbin/nologin"
]
}
ok: [b.lab.example.com] => {
"x['stdout_lines']": [
"root:x:0:0:root:/root:/bin/bash",
"bin:x:1:1:bin:/bin:/sbin/nologin",
"daemon:x:2:2:daemon:/sbin:/sbin/nologin",
"adm:x:3:4:adm:/var/adm:/sbin/nologin",
"lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin",
"sync:x:5:0:sync:/sbin:/bin/sync",
"shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown",
"halt:x:7:0:halt:/sbin:/sbin/halt",
"mail:x:8:12:mail:/var/spool/mail:/sbin/nologin",
"operator:x:11:0:operator:/root:/sbin/nologin"
]
}
If you're planning to have the playbook parse this output in some way, then that depends on what you want to do with the data.
Here's another option for you: use ansible-navigator in interactive mode rather than stdout mode: ansible-navigator run playbook.yml -m interactive
In that case, navigate the TUI and look at the output of the play. It looks more readable in that mode. I'm going to try to include some screenshots here:
Run the playbook. You get the results of the only play in the playbook as item 0:
Press 0 to get the results of each task in that play for each host:
Press 2 to get the results of the servera "Print the contents of the variable" task:
That might also be a reasonable way to see what you want with ansible-navigator. This example used the variable x['stdout'] instead of x['stdout_lines'], by the way.
As a side note, as a style thing that first ansible.builtin.command task doesn't change anything ever by running head. So I'd probably change that task to
- name: Register a variable with the results
ansible.builtin.command:
cmd: head /etc/passwd
register: x
changed_when: false
to suppress the "changed" notices that aren't real.
Red Hat
Learning Community
A collaborative learning environment, enabling open source skill development.