ansible变量注册多种方式

【ansible变量注册多种方式】缥帙各舒散,前后互相逾。这篇文章主要讲述ansible变量注册多种方式相关的知识,希望能为你提供帮助。
使用过ansible的同学都知道,注册变量并使用,是一个很常见的场景。今天就总结下常见的一些情况,了解ansible变量定义、引用及格式化相关内容。

目录

  • 1.使用register注册变量
    • 1.1 执行一条命令并把返回结果注册为变量
    • 1.2 列表遍历的结果注册为变量
  • 2.使用set_fact注册变量
    • 2.1 使用set_fact注册一个普通变量
    • 2.2 使用set_fact给list变量循环添加元素

1.使用register注册变量 当playbook运行的时候,经常需要中途收集一些数据,后面使用它。使用register注册变量是最简单、最常用的一种方式。
1.1 执行一条命令并把返回结果注册为变量 我们最常用的是,执行一条shell命令,并将返回结果注册为一个变量,例如:
tasks: - name: define a var1 shell: "whoami" register: whoami- debug: msg: "whoami: {{ whoami }}"- debug: msg: "whoami.stdout: {{whoami.stdout}}"

这里要注意,ansible执行结果一般都会返回一个字典类型的数据,你会看到很多你不关心的字段,可以通过指定字典的key,例如stdout或stdout_lines,只看到你关心的数据。
请看返回结果:
TASK [define a var1] ************************************************************************************************************************************************************************ changed: [vagrant1]TASK [debug] ******************************************************************************************************************************************************************************** ok: [vagrant1] => { "msg": "whoami: {\'stderr_lines\': [], u\'changed\': True, u\'end\': u\'2020-04-19 15:18:18.278098\', \'failed\': False, u\'stdout\': u\'vagrant\', u\'cmd\': u\'whoami\', u\'rc\': 0, u\'start\': u\'2020-04-19 15:18:18.274052\', u\'stderr\': u\'\', u\'delta\': u\'0:00:00.004046\', \'stdout_lines\': [u\'vagrant\']}" }TASK [debug] ******************************************************************************************************************************************************************************** ok: [vagrant1] => { "msg": "whoami.stdout: vagrant" }

1.2 列表遍历的结果注册为变量 这种场景,一般是列表中的元素逐个要参与运算,将运算后的结果存入一个变量,看一个示例:
---- hosts: "{{ hosts_group }}" remote_user: vagrant vars: userss: []tasks: - name: define users in a loop shell: "grep {{ item }} /etc/passwd|cat" register: users with_items: - vagrant - root - nginx- name: show users debug: msg: "{{ users }}"- name: show users.results debug: msg: "{{ users.results }}"- name: define userss by set_fact set_fact: userss: "{{userss +item.stdout_lines}}" with_list: "{{ users.results }}"- name: print userss debug: msg: "{{ userss }}"- name: print userss one by one debug: msg: "{{ item }}" with_list: "{{ userss}}"- name: print part of userss one by one debug: msg: "{{ item.split(\':\')[6] }}" with_list: "{{ userss}}"

该示例是通过关键字是查询系统的用户及shell信息,ansible会返回一个字典,查询的结果存储在字典名称为results的key对应的value中,这个value本身是一个list。因为我们都不知道到底会查到几个用户,所以再把结果list遍历一遍,存储到另外一个变量中。我们使用set_fact实现了循环给空list变量添加数据的效果。最后,我们分别获取每行的数据,并且进行拆分,获取到了第7个字段。
请看返回结果:
TASK [define users in a loop] *************************************************************************************************************************************************************** changed: [vagrant1] => (item=vagrant) changed: [vagrant1] => (item=root) changed: [vagrant1] => (item=nginx)TASK [show users] *************************************************************************************************************************************************************************** ok: [vagrant1] => { "msg": { "changed": true, "msg": "All items completed", "results": [ { "_ansible_ignore_errors": null, "_ansible_item_label": "vagrant", "_ansible_item_result": true, "_ansible_no_log": false, "_ansible_parsed": true, "changed": true, "cmd": "grep vagrant /etc/passwd|cat", "delta": "0:00:00.004695", "end": "2020-04-19 15:18:19.129083", "failed": false, "invocation": { "module_args": { "_raw_params": "grep vagrant /etc/passwd|cat", "_uses_shell": true, "argv": null, "chdir": null, "creates": null, "executable": null, "removes": null, "stdin": null, "warn": true } }, "item": "vagrant", "rc": 0, "start": "2020-04-19 15:18:19.124388", "stderr": "", "stderr_lines": [], "stdout": "vagrant:x:1000:1000:vagrant:/home/vagrant:/bin/bash", "stdout_lines": [ "vagrant:x:1000:1000:vagrant:/home/vagrant:/bin/bash" ] }, { "_ansible_ignore_errors": null, "_ansible_item_label": "root", "_ansible_item_result": true, "_ansible_no_log": false, "_ansible_parsed": true, "changed": true, "cmd": "grep root /etc/passwd|cat", "delta": "0:00:00.004695", "end": "2020-04-19 15:18:19.421598", "failed": false, "invocation": { "module_args": { "_raw_params": "grep root /etc/passwd|cat", "_uses_shell": true, "argv": null, "chdir": null, "creates": null, "executable": null, "removes": null, "stdin": null, "warn": true } }, "item": "root", "rc": 0, "start": "2020-04-19 15:18:19.416903", "stderr": "", "stderr_lines": [], "stdout": "root:x:0:0:root:/root:/bin/bash\\noperator:x:11:0:operator:/root:/sbin/nologin", "stdout_lines": [ "root:x:0:0:root:/root:/bin/bash", "operator:x:11:0:operator:/root:/sbin/nologin" ] }, { "_ansible_ignore_errors": null, "_ansible_item_label": "nginx", "_ansible_item_result": true, "_ansible_no_log": false, "_ansible_parsed": true, "changed": true, "cmd": "grep nginx /etc/passwd|cat", "delta": "0:00:00.004500", "end": "2020-04-19 15:18:19.714496", "failed": false, "invocation": { "module_args": { "_raw_params": "grep nginx /etc/passwd|cat", "_uses_shell": true, "argv": null, "chdir": null, "creates": null, "executable": null, "removes": null, "stdin": null, "warn": true } }, "item": "nginx", "rc": 0, "start": "2020-04-19 15:18:19.709996", "stderr": "", "stderr_lines": [], "stdout": "", "stdout_lines": [] } ] } }TASK [show users.results] ******************************************************************************************************************************************************************* ok: [vagrant1] => { "msg": [ { "_ansible_ignore_errors": null, "_ansible_item_label": "vagrant", "_ansible_item_result": true, "_ansible_no_log": false, "_ansible_parsed": true, "changed": true, "cmd": "grep vagrant /etc/passwd|cat", "delta": "0:00:00.004695", "end": "2020-04-19 15:18:19.129083", "failed": false, "invocation": { "module_args": { "_raw_params": "grep vagrant /etc/passwd|cat", "_uses_shell": true, "argv": null, "chdir": null, "creates": null, "executable": null, "removes": null, "stdin": null, "warn": true } }, "item": "vagrant", "rc": 0, "start": "2020-04-19 15:18:19.124388", "stderr": "", "stderr_lines": [], "stdout": "vagrant:x:1000:1000:vagrant:/home/vagrant:/bin/bash", "stdout_lines": [ "vagrant:x:1000:1000:vagrant:/home/vagrant:/bin/bash" ] }, { "_ansible_ignore_errors": null, "_ansible_item_label": "root", "_ansible_item_result": true, "_ansible_no_log": false, "_ansible_parsed": true, "changed": true, "cmd": "grep root /etc/passwd|cat", "delta": "0:00:00.004695", "end": "2020-04-19 15:18:19.421598", "failed": false, "invocation": { "module_args": { "_raw_params": "grep root /etc/passwd|cat", "_uses_shell": true, "argv": null, "chdir": null, "creates": null, "executable": null, "removes": null, "stdin": null, "warn": true } }, "item": "root", "rc": 0, "start": "2020-04-19 15:18:19.416903", "stderr": "", "stderr_lines": [], "stdout": "root:x:0:0:root:/root:/bin/bash\\noperator:x:11:0:operator:/root:/sbin/nologin", "stdout_lines": [ "root:x:0:0:root:/root:/bin/bash", "operator:x:11:0:operator:/root:/sbin/nologin" ] }, { "_ansible_ignore_errors": null, "_ansible_item_label": "nginx", "_ansible_item_result": true, "_ansible_no_log": false, "_ansible_parsed": true, "changed": true, "cmd": "grep nginx /etc/passwd|cat", "delta": "0:00:00.004500", "end": "2020-04-19 15:18:19.714496", "failed": false, "invocation": { "module_args": { "_raw_params": "grep nginx /etc/passwd|cat", "_uses_shell": true, "argv": null, "chdir": null, "creates": null, "executable": null, "removes": null, "stdin": null, "warn": true } }, "item": "nginx", "rc": 0, "start": "2020-04-19 15:18:19.709996", "stderr": "", "stderr_lines": [], "stdout": "", "stdout_lines": [] } ] }TASK [define userss by set_fact] ************************************************************************************************************************************************************ ok: [vagrant1] => (item={\'_ansible_parsed\': True, \'stderr_lines\': [], \'_ansible_item_result\': True, u\'end\': u\'2020-04-19 15:18:19.129083\', \'_ansible_no_log\': False, u\'stdout\': u\'vagrant:x:1000:1000:vagrant:/home/vagrant:/bin/bash\', u\'cmd\': u\'grep vagrant /etc/passwd|cat\', u\'rc\': 0, \'item\': u\'vagrant\', u\'delta\': u\'0:00:00.004695\', \'_ansible_item_label\': u\'vagrant\', u\'stderr\': u\'\', u\'changed\': True, u\'invocation\': {u\'module_args\': {u\'warn\': True, u\'executable\': None, u\'_uses_shell\': True, u\'_raw_params\': u\'grep vagrant /etc/passwd|cat\', u\'removes\': None, u\'argv\': None, u\'creates\': None, u\'chdir\': None, u\'stdin\': None}}, \'stdout_lines\': [u\'vagrant:x:1000:1000:vagrant:/home/vagrant:/bin/bash\'], u\'start\': u\'2020-04-19 15:18:19.124388\', \'_ansible_ignore_errors\': None, \'failed\': False}) ok: [vagrant1] => (item={\'_ansible_parsed\': True, \'stderr_lines\': [], \'_ansible_item_result\': True, u\'end\': u\'2020-04-19 15:18:19.421598\', \'_ansible_no_log\': False, u\'stdout\': u\'root:x:0:0:root:/root:/bin/bash\\noperator:x:11:0:operator:/root:/sbin/nologin\', u\'cmd\': u\'grep root /etc/passwd|cat\', u\'rc\': 0, \'item\': u\'root\', u\'delta\': u\'0:00:00.004695\', \'_ansible_item_label\': u\'root\', u\'stderr\': u\'\', u\'changed\': True, u\'invocation\': {u\'module_args\': {u\'warn\': True, u\'executable\': None, u\'_uses_shell\': True, u\'_raw_params\': u\'grep root /etc/passwd|cat\', u\'removes\': None, u\'argv\': None, u\'creates\': None, u\'chdir\': None, u\'stdin\': None}}, \'stdout_lines\': [u\'root:x:0:0:root:/root:/bin/bash\', u\'operator:x:11:0:operator:/root:/sbin/nologin\'], u\'start\': u\'2020-04-19 15:18:19.416903\', \'_ansible_ignore_errors\': None, \'failed\': False}) ok: [vagrant1] => (item={\'_ansible_parsed\': True, \'stderr_lines\': [], \'_ansible_item_result\': True, u\'end\': u\'2020-04-19 15:18:19.714496\', \'_ansible_no_log\': False, u\'stdout\': u\'\', u\'cmd\': u\'grep nginx /etc/passwd|cat\', u\'rc\': 0, \'item\': u\'nginx\', u\'delta\': u\'0:00:00.004500\', \'_ansible_item_label\': u\'nginx\', u\'stderr\': u\'\', u\'changed\': True, u\'invocation\': {u\'module_args\': {u\'warn\': True, u\'executable\': None, u\'_uses_shell\': True, u\'_raw_params\': u\'grep nginx /etc/passwd|cat\', u\'removes\': None, u\'argv\': None, u\'creates\': None, u\'chdir\': None, u\'stdin\': None}}, \'stdout_lines\': [], u\'start\': u\'2020-04-19 15:18:19.709996\', \'_ansible_ignore_errors\': None, \'failed\': False})TASK [print userss] ************************************************************************************************************************************************************************* ok: [vagrant1] => { "msg": [ "vagrant:x:1000:1000:vagrant:/home/vagrant:/bin/bash", "root:x:0:0:root:/root:/bin/bash", "operator:x:11:0:operator:/root:/sbin/nologin" ] }TASK [print userss one by one] ************************************************************************************************************************************************************** ok: [vagrant1] => (item=vagrant:x:1000:1000:vagrant:/home/vagrant:/bin/bash) => { "msg": "vagrant:x:1000:1000:vagrant:/home/vagrant:/bin/bash" } ok: [vagrant1] => (item=root:x:0:0:root:/root:/bin/bash) => { "msg": "root:x:0:0:root:/root:/bin/bash" } ok: [vagrant1] => (item=operator:x:11:0:operator:/root:/sbin/nologin) => { "msg": "operator:x:11:0:operator:/root:/sbin/nologin" }TASK [print part of userss one by one] ****************************************************************************************************************************************************** ok: [vagrant1] => (item=vagrant:x:1000:1000:vagrant:/home/vagrant:/bin/bash) => { "msg": "/bin/bash" } ok: [vagrant1] => (item=root:x:0:0:root:/root:/bin/bash) => { "msg": "/bin/bash" } ok: [vagrant1] => (item=operator:x:11:0:operator:/root:/sbin/nologin) => { "msg": "/sbin/nologin" }

2.使用set_fact注册变量 其实上个示例,已经提到了set_fact,因为set_fact配合register可以实现一些重要和灵活的功能。
2.1 使用set_fact注册一个普通变量
tasks: - name: define a var1 shell: "whoami" register: whoami- debug: msg: "whoami: {{ whoami }}"- debug: msg: "whoami.stdout: {{whoami.stdout}}"- name: define a var by set_fact set_fact: whoami: "{{ whoami.stdout}}"- name:show a var after defined by set_fact debug: msg: "{{ whoami }}"

使用这种方式,会简化变量的调用。
2.2 使用set_fact给list变量循环添加元素 这个功能只有通过set_fact可以显示,在好多场景都会用到,尤其是你不知道自己注册的变量有多少个元素,而且配合register可以大大简化变量的后续调用和重新格式化。其实示例1.2的示例代码已经用了这种方式:
vars: userss: []- name: define userss by set_fact set_fact: userss: "{{userss +item.stdout_lines}}" with_list: "{{ users.results }}"- name: print userss debug: msg: "{{ userss }}"- name: print userss one by one debug: msg: "{{ item }}" with_list: "{{ userss}}"- name: print part of userss one by one debug: msg: "{{ item.split(\':\')[6] }}" with_list: "{{ userss}}"

尤其要注意,循环给list变量添加元素的时候,这个变量要已经定义过了,才可以循环添加元素。最后print part的时候,在ansible中调用了python的字符串拆分函数,对遍历到的每行元素进行拆分,获取我们最需要的字段。 先组合字符串,再拆分字符串,会简化整体playbook,避免使用难以理解容易出错的嵌套循环。
完整的示例,可以看这里: https://github.com/byygyy/ansible-best-practice/blob/master/test-vars-define.yml

    推荐阅读