Ansible寄存器多个命令的结果

Ask*_*arn 19 ansible

我有一个任务来验证所有Linux服务器的一些路由条目,这是我如何使用Ansible playbook完成的

---
  - hosts: Linux
    serial: 1

    tasks:
      - name: Check first
        command: /sbin/ip route list xxx.xxx.xxx.xxx/24
        register: result
        changed_when: false

      - debug: msg="{{result.stdout}}"

      - name: Check second
        command: /sbin/ip route list xxx.xxx.xxx.xxx/24
        register: result
        changed_when: false

      - debug: msg="{{result.stdout}}"
Run Code Online (Sandbox Code Playgroud)

您可以看到我必须为每个路由条目重复相同的任务,我相信我应该能够避免这种情况.我尝试使用with_items循环但得到以下错误消息

One or more undefined variables: 'dict object' has no attribute 'stdout'
Run Code Online (Sandbox Code Playgroud)

有没有办法为每个命令注册变量并逐个循环它们?

yae*_*shi 36

从Ansible 1.6.1开始,使用多个项目注册的结果将result.results作为数组存储.所以你可以使用result.results[0].stdout等等.

测试剧本:

---
- hosts: localhost
  gather_facts: no
  tasks:
    - command: "echo {{item}}"
      register: result
      with_items: [1, 2]
    - debug:
        var: result
Run Code Online (Sandbox Code Playgroud)

结果:

$ ansible-playbook -i localhost, test.yml

PLAY [localhost] ************************************************************** 

TASK: [command echo {{item}}] ************************************************* 
changed: [localhost] => (item=1)
changed: [localhost] => (item=2)

TASK: [debug ] **************************************************************** 
ok: [localhost] => {
    "var": {
        "result": {
            "changed": true, 
            "msg": "All items completed", 
            "results": [
                {
                    "changed": true, 
                    "cmd": [
                        "echo", 
                        "1"
                    ], 
                    "delta": "0:00:00.002502", 
                    "end": "2015-08-07 16:44:08.901313", 
                    "invocation": {
                        "module_args": "echo 1", 
                        "module_name": "command"
                    }, 
                    "item": 1, 
                    "rc": 0, 
                    "start": "2015-08-07 16:44:08.898811", 
                    "stderr": "", 
                    "stdout": "1", 
                    "stdout_lines": [
                        "1"
                    ], 
                    "warnings": []
                }, 
                {
                    "changed": true, 
                    "cmd": [
                        "echo", 
                        "2"
                    ], 
                    "delta": "0:00:00.002516", 
                    "end": "2015-08-07 16:44:09.038458", 
                    "invocation": {
                        "module_args": "echo 2", 
                        "module_name": "command"
                    }, 
                    "item": 2, 
                    "rc": 0, 
                    "start": "2015-08-07 16:44:09.035942", 
                    "stderr": "", 
                    "stdout": "2", 
                    "stdout_lines": [
                        "2"
                    ], 
                    "warnings": []
                }
            ]
        }
    }
}

PLAY RECAP ******************************************************************** 
localhost                  : ok=2    changed=1    unreachable=0    failed=0   
Run Code Online (Sandbox Code Playgroud)


gam*_*eld 6

情况略有不同,需要一段时间才能弄清楚。如果要使用多个项目的结果,但要使用changed_when,则register变量将没有var.results!而是changed_when为每个项目评估,您可以直接使用寄存器var。

一个简单的示例,它将导致更改:false:

- action: command echo {{item}}
  register: out
  changed_when: "'z' in out.stdout"
  with_items:
    - hello
    - foo
    - bye
Run Code Online (Sandbox Code Playgroud)

另一个例子:

- name: Create fulltext index for faster text searches.
  mysql_db: name={{SO_database}} state=import target=/tmp/fulltext-{{item.tableName}}-{{item.columnName}}.sql
  with_items: 
    - {tableName: Posts,  columnName: Title}
    - {tableName: Posts,  columnName: Body}
    - {tableName: Posts,  columnName: Tags}
    - {tableName: Comments, columnName: Text}
  register: createfulltextcmd
  changed_when: createindexcmd.msg.find('already exists') == -1
Run Code Online (Sandbox Code Playgroud)

最后,当您确实想在其他上下文中循环搜索结果时,以编程方式访问索引似乎有些棘手,因为该索引未公开。我确实找到了一个可能很有前途的例子:

- name: add hosts to known_hosts
shell: 'ssh-keyscan -H {{item.host}}>> /home/testuser/known_hosts'
with_items:
  - { index: 0, host: testhost1.test.dom }
  - { index: 1, host: testhost2.test.dom }
  - { index: 2, host: 192.168.202.100 }
when: ssh_known_hosts.results[{{item.index}}].rc == 1
Run Code Online (Sandbox Code Playgroud)