为受管主机收集的一些事实可能包括:
主机名称 内核版本 网络接口 IP地址 操作系统版本 各种环境变量 CPU数量 提供的或可用的内存 可用磁盘空间
Playbook以JSON格式显示ansible_facts变量的内容。
1.不准备使用任何事实 2.希望加快play速度 3.希望减小play在受管主机上造成的负载 4.受管主机因为某种原因无法运行setup模块 5.需要安装一些必备软件后再收集事实
gather_facts: no即使playbook设置了gather_facts: no,还是能够通过运行使用setup模块的任务来手动收集事实:
[root@ansible jay]# vi playbook.yml --- - hosts: all gather_facts: no tasks: - name: 提出本机的ip地址 setup : - name : debug debug: var: ansible_facts['default_ipv4']['address'] [root@ansible jay]# ansible-playbook -C playbook.yml PLAY [all] *********************************************************************** TASK [提出本机的ip地址] ***************************************************************** ok: [192.168.10.129] => { "ansible_facts['default_ipv4']['address']": "VARIABLE IS NOT DEFINED!" } PLAY RECAP *********************************************************************** 192.168.10.129 : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 [root@ansible jay]# vi playbook.yml [root@ansible jay]# ansible-playbook -C playbook.yml PLAY [all] *********************************************************************** TASK [提出本机的ip地址] ***************************************************************** ok: [192.168.10.129] TASK [debug] ********************************************************************* ok: [192.168.10.129] => { "ansible_facts['default_ipv4']['address']": "192.168.10.129" } PLAY RECAP *********************************************************************** 192.168.10.129 : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0除了使用系统捕获的事实外,我们还可以自定义事实,并将其本地存储在每个受管主机上。这些事实整合到setup模块在受管主机上运行时收集的标准事实列表中。它们让受管主机能够向Ansible提供任意变量,以用于调整play的行为。
默认情况下,setup模块从各受管主机的/etc/ansible/facts.d目录下的文件和脚本中加载自定义事实。各个文件或脚本的名称必须以.fact结尾才能被使用。动态自定义事实脚本必须输出JSON格式的事实,而且必须是可执行文件。
[users] user1 = adw user2 = jay一些变量并非事实或通过setup模块配置,但也由Ansible自动设置。这些魔法变量也可用于获取与特定受管主机相关的信息。
最常用的有四个:
魔法变量说明hostvars包含受管主机的变量,可以用于获取另一台受管主机的变量的值。如果还没有为受管主机收集事实,则它不会包含该主机的事实。group_names列出当前受管主机所属的所有组groups列出清单中的所有组和主机inventory_hostname包含清单中配置的当前受管主机的主机名称。因为各种原因有可能与事实报告的主机名称不同可以通过debug模块报告特定主机的hostvars变量的内容:
[root@ansible jay]# ansible all -m debug -a 'var=hostvars["localhost"]'利用循环,我们无需编写多个使用同一模块的任务。例如,他们不必编写五个任务来确保存在五个用户,而是只需编写一个任务来对含有五个用户的列表迭代,从而确保它们都存在。
Ansible支持使用loop关键字对一组项目迭代任务。可以配置循环以利用列表中的各个项目、列表中各个文件的内容、生成的数字序列或更为复杂的结构来重复任务。
简单循环对一组项目迭代任务。loop关键字添加到任务中,将应对其迭代任务的项目列表取为值。循环变量item保存每个迭代过程中使用的值。
--- - hosts: all tasks: - name: 运行postfix和dovecot service: name: "{{ item }}" state: started loop: - postfix - dovecot [root@ansible jay]# ansible-playbook -C playbook.yml PLAY [all] *********************************************************************** TASK [Gathering Facts] *********************************************************** ok: [192.168.10.129] TASK [运行postfix和dovecot] ********************************************************* changed: [192.168.10.129] => (item=postfix) changed: [192.168.10.129] => (item=dovecot) PLAY RECAP *********************************************************************** 192.168.10.129 : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0也可以通过一个变量提供loop所使用的列表。在以下示例中,变量mail_services含有需要处于运行状态的服务的列表。
--- - hosts: all vars: mail_ser: - postfix - dovecot tasks: - name: 运行postfix和dovecot service: name: "{{ item }}" state: started loop: "{{ mail_ser }}" [root@ansible jay]# ansible-playbook -C playbook.yml PLAY [all] *********************************************************************** TASK [Gathering Facts] *********************************************************** ok: [192.168.10.129] TASK [运行postfix和dovecot] ********************************************************* changed: [192.168.10.129] => (item=postfix) changed: [192.168.10.129] => (item=dovecot) PLAY RECAP *********************************************************************** 192.168.10.129 : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 [root@ansible jay]# vi playbook.yml [root@ansible jay]# ansible-playbook -C playbook.yml PLAY [all] *********************************************************************** TASK [Gathering Facts] *********************************************************** ok: [192.168.10.129] TASK [运行postfix和dovecot] ********************************************************* changed: [192.168.10.129] => (item=postfix) changed: [192.168.10.129] => (item=dovecot) PLAY RECAP *********************************************************************** 192.168.10.129 : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0loop列表不需要是简单值列表。在以下示例中,列表中的每个项实际上是散列或字典。示例中的每个散列或字典具有两个键,即name和groups,当前item循环变量中每个键的值可以分别通过item.name和item.groups变量来检索。
--- - hosts: all tasks: - name: user user: name: "{{ item.name }}" state: present groups: "{{ item.groups }}" loop: - name: adw groups: adidas - name: lxw groups: nike [root@ansible jay]# ansible-playbook -C playbook.yml PLAY [all] *********************************************************************** TASK [Gathering Facts] *********************************************************** ok: [192.168.10.129] TASK [user] ********************************************************************** changed: [192.168.10.129] => (item={'name': 'adw', 'groups': 'adidas'}) changed: [192.168.10.129] => (item={'name': 'lxw', 'groups': 'nike'}) PLAY RECAP *********************************************************************** 192.168.10.129 : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0register关键字也可以捕获循环任务的输出。以下代码片段显示了循环任务中register变量的结构:
--- - hosts: all tasks: - name: asdasd shell: "echo this is my item: {{ item }}" loop: - one - two register: echo_results - name: sadasd debug: var: echo_results [root@ansible jay]# ansible-playbook -C playbook.yml PLAY [all] *********************************************************************** TASK [Gathering Facts] *********************************************************** ok: [192.168.10.129] TASK [asdasd] ******************************************************************** skipping: [192.168.10.129] => (item=one) skipping: [192.168.10.129] => (item=two) TASK [sadasd] ******************************************************************** ok: [192.168.10.129] => { "echo_results": { "changed": false, "msg": "All items completed", "results": [ { "ansible_loop_var": "item", "changed": false, "failed": false, "invocation": { "module_args": { "_raw_params": "echo this is my item: one", "_uses_shell": true, "argv": null, "chdir": null, "creates": null, "executable": null, "removes": null, "stdin": null, "stdin_add_newline": true, "strip_empty_ends": true, "warn": true } }, "item": "one", "msg": "skipped, running in check mode", "skipped": true }, { "ansible_loop_var": "item", "changed": false, "failed": false, "invocation": { "module_args": { "_raw_params": "echo this is my item: two", "_uses_shell": true, "argv": null, "chdir": null, "creates": null, "executable": null, "removes": null, "stdin": null, "stdin_add_newline": true, "strip_empty_ends": true, "warn": true } }, "item": "two", "msg": "skipped, running in check mode", "skipped": true } ] } } PLAY RECAP *********************************************************************** 192.168.10.129 : ok=2 changed=0 unreachable=0 failed=0 skipped=1 rescued=0 ignored=0