EDIT: It seems this only occurs when running with the --check
parameter. Running this playbook live doesn't throw this error. But it would still be good to know what is causing this.
I'm starting to use Ansible AWX to manage a bunch of servers and haven't used Ansible before, though I've gone through a number of online tutorials and feel quite comfortable with it.
I'm attempting to run a playbook which installs updates to a number of webservers.
It's throwing an error up, which strangely appears on different hosts on different runs. For example, if I run the playbook, the host server3.mydomain.com
fails with this error. If I remove that server from the inventory, then I get the same error on server2.mydomain.com
, and so on and so on.
The error output doesn't provide enough information for me to figure out why this is failing, even though it isolates it to one small section, and I haven't managed to find the issue through an online search.
This is the playbook (from an template I found online, with some changes):
---
- name: ensure services are up before doing anything
hosts: webservers
become: true
any_errors_fatal: true
serial: 1
tasks:
- name: upgrade packages and reboot (if necessary)
hosts: webservers
become: true
serial: 1
any_errors_fatal: true
max_fail_percentage: 0
tasks:
- name: apt-get update
apt:
update-cache: yes
changed_when: 0
- name: get list of pending upgrades
command: apt-get --simulate dist-upgrade
args:
warn: false
register: apt_simulate
changed_when: 0
- name: parse apt-get output to get list of changed packages
set_fact:
updates: '{{ apt_simulate.stdout_lines | select("match", "^Inst ") | list | sort }}'
changed_when: 0
- name: show pending updates
debug:
var: updates
when: updates.0 is defined
- name: apt-get autoremove
command: apt-get -y autoremove
args:
warn: false
when: '"Inst linux-image-" in apt_simulate.stdout'
changed_when: 0
- name: apt-get dist-upgrade
apt:
upgrade: dist
register: upgrade_output
- name: check if reboot needed
stat: path=/var/run/reboot-required
register: file_reboot_required
- meta: end_play
when: not file_reboot_required.stat.exists
- name: reboot node
shell: sleep 2 && shutdown -r now "Reboot triggered by ansible"
async: 1
poll: 0
ignore_errors: true
- name: wait for node to finish booting
wait_for_connection:
connect_timeout=10
delay=30
timeout=120
- name: wait for ssh to start fully
pause:
seconds: 45
And this is the error:
fatal: [server3.mydomain.com]: FAILED! => {
"msg": "The task includes an option with an undefined variable. The error was: 'dict object' has no attribute 'stdout_lines'\n\nThe error appears to have been in '/var/lib/awx/projects/_8__infrastructure_management/projects/infrastructure-management/test/test.yml': line 30, column 7, but may\nbe elsewhere in the file depending on the exact syntax problem.\n\nThe offending line appears to be:\n\n\n - name: parse apt-get output to get list of changed packages\n ^ here\n"
So, the error appears to relate to this block, but beyond that I'm stuck:
- name: parse apt-get output to get list of changed packages
set_fact:
updates: '{{ apt_simulate.stdout_lines | select("match", "^Inst ") | list | sort }}'
changed_when: 0
Can't see what I am missing here.
Running with --check
has no way to "dry run" a command:
or shell:
module, since it cannot predict what is safe to run versus not. Thus, since the command:
doesn't run, it doesn't create any stdout_lines
in that apt_simulate
variable. Interestingly enough, using debug: var=apt_simulate
shows that it actually does say apt_simulate.skipped=True
as well as apt_simulate.msg="remote module (command) does not support check mode"
. So you can decide for yourself if you wish to just guard that updates:
reference with when: not apt_simulate.skipped
or even go so far as when: not {{ansible_check_mode}}
Thankfully, you can override command
s behavior by specifying check_mode: no
if you are certain -- as appears to be the case with your command -- that it truly is safe to run the command even in check mode.