devops's docs

1.3.10: playbook-debug_register&with_items


0. 问题背景

register+with_items获得的结果,如何能用debug再次循环输出我们需要的信息?

参考链接:
https://github.com/ansible/ansible/issues/5564
如何使用debug register with_items漂亮的输出结果问题
https://github.com/openshift/openshift-ansible/issues/447
map命令无法找到的讨论


1. 官方文档上示例方法

register with_items一起使用
官方的推荐原理上可以总结为,将register.results重新传给with_items,然后再次循环,但这样做有一个特别不好的地方,就是冗余输出太多

---
- name: check jdk exist or not
  stat: path=\{\{ jdk_base_dir }}/\{\{ jdk_item }}
  with_items: \{\{ jdk_version }}"
  register: jdk
  loop_control:
    loop_var: jdk_item

- debug:
    msg: \{\{ item }}"
  with_items: \{\{ jdk.results }}"
---

执行结果

TASK [server_initialize : check jdk exist or not] ******************************
ok: [testweb] => (item=jdk1.6.0_45)
ok: [testweb] => (item=jdk1.7.0_79)
ok: [testweb] => (item=jdk1.8.0_121)

TASK [server_initialize : debug] ***********************************************

ok: [testweb] => (item={'_ansible_parsed': True, u'stat': {u'exists': False}, '_ansible_item_result': True, '_ansible_no_log': False, u'changed': False, u'jdk_item': u'jdk1.6.0_45', 'invocation': {'module_name': u'stat', u'module_args': {u'checksum_algorithm': u'sha1', u'mime': False, u'get_checksum': True, u'follow': False, u'path': u'/usr/java/jdk1.6.0_45', u'get_md5': True}}, '_ansible_item_label': u'jdk1.6.0_45'}) => {
    "item": {
        "changed": false,
        "invocation": {
            "module_args": {
                "checksum_algorithm": "sha1",
                "follow": false,
                "get_checksum": true,
                "get_md5": true,
                "mime": false,
                "path": "/usr/java/jdk1.6.0_45"
            },
            "module_name": "stat"
        },
        "jdk_item": "jdk1.6.0_45",
        "stat": {
            "exists": false
        }
    },
    "msg": {
        "changed": false,
        "invocation": {
            "module_args": {
                "checksum_algorithm": "sha1",
                "follow": false,
                "get_checksum": true,
                "get_md5": true,
                "mime": false,
                "path": "/usr/java/jdk1.6.0_45"
            },
            "module_name": "stat"
        },
        "jdk_item": "jdk1.6.0_45",
        "stat": {
            "exists": false
        }
    }
}
ok: [testweb] => (item={'_ansible_parsed': True, u'stat': {u'exists': False}, '_ansible_item_result': True, '_ansible_no_log': False, u'changed': False, u'jdk_item': u'jdk1.7.0_79', 'invocation': {'module_name': u'stat', u'module_args': {u'checksum_algorithm': u'sha1', u'mime': False, u'get_checksum': True, u'follow': False, u'path': u'/usr/java/jdk1.7.0_79', u'get_md5': True}}, '_ansible_item_label': u'jdk1.7.0_79'}) => {
    "item": {
        "changed": false,
        "invocation": {
            "module_args": {
                "checksum_algorithm": "sha1",
                "follow": false,
                "get_checksum": true,
                "get_md5": true,
                "mime": false,
                "path": "/usr/java/jdk1.7.0_79"
            },
            "module_name": "stat"
        },
        "jdk_item": "jdk1.7.0_79",
        "stat": {
            "exists": false
        }
    },
    "msg": {
        "changed": false,
        "invocation": {
            "module_args": {
                "checksum_algorithm": "sha1",
                "follow": false,
                "get_checksum": true,
                "get_md5": true,
                "mime": false,
                "path": "/usr/java/jdk1.7.0_79"
            },
            "module_name": "stat"
        },
        "jdk_item": "jdk1.7.0_79",
        "stat": {
            "exists": false
        }
    }
}
ok: [testweb] => (item={'_ansible_parsed': True, u'stat': {u'exists': False}, '_ansible_item_result': True, '_ansible_no_log': False, u'changed': False, u'jdk_item': u'jdk1.8.0_121', 'invocation': {'module_name': u'stat', u'module_args': {u'checksum_algorithm': u'sha1', u'mime': False, u'get_checksum': True, u'follow': False, u'path': u'/usr/java/jdk1.8.0_121', u'get_md5': True}}, '_ansible_item_label': u'jdk1.8.0_121'}) => {
    "item": {
        "changed": false,
        "invocation": {
            "module_args": {
                "checksum_algorithm": "sha1",
                "follow": false,
                "get_checksum": true,
                "get_md5": true,
                "mime": false,
                "path": "/usr/java/jdk1.8.0_121"
            },
            "module_name": "stat"
        },
        "jdk_item": "jdk1.8.0_121",
        "stat": {
            "exists": false
        }
    },
    "msg": {
        "changed": false,
        "invocation": {
            "module_args": {
                "checksum_algorithm": "sha1",
                "follow": false,
                "get_checksum": true,
                "get_md5": true,
                "mime": false,
                "path": "/usr/java/jdk1.8.0_121"
            },
            "module_name": "stat"
        },
        "jdk_item": "jdk1.8.0_121",
        "stat": {
            "exists": false
        }
    }
}

这显然与我们期望的输出结果不符


2. 使用jinja2的map方法过滤

- name: check jdk exist or not
  stat: path=\{\{ jdk_base_dir }}/\{\{ jdk_item }}
  with_items: \{\{ jdk_version }}"
  register: jdk
  loop_control:
    loop_var: jdk_item

- debug:
    msg: \{\{ jdk.results|map(attribute='jdk_item')|list }}"
- debug:
    msg: "stat:\{\{ jdk.results|map(attribute='stat')|list }}"

执行结果

TASK [server_initialize : check jdk exist or not] ******************************
ok: [testweb] => (item=jdk1.6.0_45)
ok: [testweb] => (item=jdk1.7.0_79)
ok: [testweb] => (item=jdk1.8.0_121)

TASK [server_initialize : debug] ***********************************************
ok: [testweb] => {
    "msg": [
        "jdk1.6.0_45",
        "jdk1.7.0_79",
        "jdk1.8.0_121"
    ]
}

TASK [server_initialize : debug] ***********************************************
ok: [testweb] => {
    "msg": "stat:[{u'exists': False}, {u'exists': False}, {u'exists': False}]"
}

值得注意的是,上面两个msg的区别仅在于是否有自定义的字符在,区别就是输出的格式不同