0

编辑:似乎这只发生在使用--check参数运行时。实时运行此剧本不会引发此错误。但最好知道是什么原因造成的。

我开始使用 Ansible AWX 来管理一堆服务器并且以前没有使用过 Ansible,尽管我已经阅读了许多在线教程并且感觉很舒服。

我正在尝试运行一个将更新安装到多个网络服务器的剧本。

它抛出了一个错误,奇怪地出现在不同的主机上不同的运行。例如,如果我运行 playbook,主机会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

看不到我在这里缺少什么。

4

1 回答 1

2

运行 with--check无法“空运行” a command:orshell:模块,因为它无法预测什么是安全的,什么是不安全的。因此,由于command:没有运行,它不会stdout_lines在该apt_simulate变量中创建任何内容。有趣的是, usingdebug: var=apt_simulate表明它实际上确实apt_simulate.skipped=Trueapt_simulate.msg="remote module (command) does not support check mode". 因此,您可以自己决定是否只想保护该updates:引用,when: not apt_simulate.skipped甚至可以做到when: not {{ansible_check_mode}}

值得庆幸的是,您可以通过指定是否确定(就像您的命令那样)来覆盖commands 的行为,即使在检查模式下运行该命令也确实是安全的。check_mode: no

于 2018-09-20T17:10:35.440 回答