运行 剧本时,各种主机上的未定义变量错误 'dict object'
Undefined variable error 'dict object' on various hosts when running playbook
编辑:这似乎只发生在 运行 --check
参数时。 运行 这个 playbook live 不会抛出这个错误。但最好知道是什么原因造成的。
我开始使用 Ansible AWX 来管理一堆服务器并且之前没有使用过 Ansible,虽然我已经阅读了一些在线教程并且感觉很舒服。
我正在尝试 运行 一个为多个网络服务器安装更新的剧本。
它正在抛出一个错误,它奇怪地出现在不同 运行 的不同主机上。例如,如果我 运行 剧本,主机 server3.mydomain.com
失败并出现此错误。如果我从清单中删除该服务器,那么我会在 server2.mydomain.com
上收到相同的错误,依此类推。
错误输出没有提供足够的信息让我弄清楚失败的原因,即使它把它隔离为一小部分,我也没有通过在线搜索找到问题。
这是剧本(来自我在网上找到的模板,有一些改动):
---
- 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
这是错误:
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"
所以,错误似乎与这个块有关,但除此之外我还卡住了:
- 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
看不到我在这里遗漏了什么。
运行 --check
无法 "dry run" 一个 command:
或 shell:
模块,因为它无法预测什么对 [=31= 是安全的] 与否。因此,由于 command:
没有 运行,它不会在那个 apt_simulate
变量中创建任何 stdout_lines
。有趣的是,使用 debug: var=apt_simulate
表明它实际上确实表示 apt_simulate.skipped=True
以及 apt_simulate.msg="remote module (command) does not support check mode"
。因此,您可以自己决定是否只想使用 when: not apt_simulate.skipped
来保护 updates:
引用,或者甚至 when: not {{ansible_check_mode}}
值得庆幸的是,您可以通过指定 check_mode: no
来覆盖 command
的行为,前提是您确定 - 正如您的命令所显示的那样 - [=31] 确实是安全的=] 即使在检查模式下的命令。
编辑:这似乎只发生在 运行 --check
参数时。 运行 这个 playbook live 不会抛出这个错误。但最好知道是什么原因造成的。
我开始使用 Ansible AWX 来管理一堆服务器并且之前没有使用过 Ansible,虽然我已经阅读了一些在线教程并且感觉很舒服。
我正在尝试 运行 一个为多个网络服务器安装更新的剧本。
它正在抛出一个错误,它奇怪地出现在不同 运行 的不同主机上。例如,如果我 运行 剧本,主机 server3.mydomain.com
失败并出现此错误。如果我从清单中删除该服务器,那么我会在 server2.mydomain.com
上收到相同的错误,依此类推。
错误输出没有提供足够的信息让我弄清楚失败的原因,即使它把它隔离为一小部分,我也没有通过在线搜索找到问题。
这是剧本(来自我在网上找到的模板,有一些改动):
---
- 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
这是错误:
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"
所以,错误似乎与这个块有关,但除此之外我还卡住了:
- 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
看不到我在这里遗漏了什么。
运行 --check
无法 "dry run" 一个 command:
或 shell:
模块,因为它无法预测什么对 [=31= 是安全的] 与否。因此,由于 command:
没有 运行,它不会在那个 apt_simulate
变量中创建任何 stdout_lines
。有趣的是,使用 debug: var=apt_simulate
表明它实际上确实表示 apt_simulate.skipped=True
以及 apt_simulate.msg="remote module (command) does not support check mode"
。因此,您可以自己决定是否只想使用 when: not apt_simulate.skipped
来保护 updates:
引用,或者甚至 when: not {{ansible_check_mode}}
值得庆幸的是,您可以通过指定 check_mode: no
来覆盖 command
的行为,前提是您确定 - 正如您的命令所显示的那样 - [=31] 确实是安全的=] 即使在检查模式下的命令。