ansible-dynamic inventory,forks,serial,include,import-06

1. 关于hosts选择主机

1.1 引用清单

  • 清单中受管主机或主机组的名称就是指定该主机或主机组的主机模式
  • 在play中,hosts指定要针对其运行play的受管主机
[root@vm1 apache]#  vim inventory 
[webservers:children]
centos7
centos8

[centos7]
vm2

[centos8]
vm3
  • 可以通过设置ansible_host主机变量,在清单中将某一别名指向特定的IP地址,在相应的host_vars/主机别名目录创建文件指定别名指向的ip地址
[root@vm1 apache]# cd host_vars/
[root@vm1 host_vars]# tree .
.
├── vm2
│   ├── host.yml
│   └── pass.yml
└── vm3
    ├── host.yml
    └── pass.yml
    
[root@vm1 host_vars]# cat vm2/host.yml 
ansible_host: 172.16.104.131
[root@vm1 host_vars]# cat vm3/host.yml 
ansible_host: 172.16.104.132

1.2 使用组名指定主机

  • 该方式指定Ansible将对属于该组的所成员主机执行操作
[root@vm1 apache]# vim test.yml

---
- hosts: webservers
  
- hosts: all

- hosts: ungrouped

  • 在playbook中,指定hosts,all 表示选清单中所有主机,ungrouped表示选择所有非组的主机

1.3 使通配府匹配主机

  • 如果在Playbook中使用了任何特殊通配符或列表字符,必须将主机模式放在单引号里,确保能够正确解析主机模式。
[root@vm1 apache]# vim test.yml 
---
- name: match "*"
  hosts: '*'
  gather_facts: no
  tasks:
    - ping:

- name: match "centos*"
  hosts: 'centos*'
  gather_facts: no
  tasks:
    - ping:


[root@vm1 apache]# ansible-playbook test.yml -i inventory 

PLAY [match "*"] ***************************************************************

TASK [ping] ********************************************************************
ok: [vm2]
ok: [vm3]

PLAY [match "centos*"] *********************************************************

TASK [ping] ********************************************************************
ok: [vm2]
ok: [vm3]

  • 注意:使用通配符匹配主不区别名称是DNS名、IP地址还是组,这可能会导致一些意外的匹配(centos*,将匹配所有以centos开头的选项,可能导致重复匹配)

1.4 使用列表的形式匹配主机

  • ‘,’ ‘:’作为列表的分隔符,建议首选‘,’
  • &符号在列表中时,则从列表中所有无&项的集合中选中同时属于&所在项的主机,否则,只匹配&选项中同时存在的主机
  • !符号在列表中,则从列表中所有无!项的集合中选中同不属于!所在项的主机,否则,从所有主机中匹配同时不属于!所在项的主机
[root@vm1 apache]# vim hosts

[backup]
vm1
vm3
vm4

[web]
vm2
vm3
vm4

[data]
vm1
vm4
vm2

[root@vm1 apache]# ansible '&data,&web,vm3' --list-hosts -i hosts
[WARNING]: No hosts matched, nothing to do
  hosts (0):
[root@vm1 apache]# ansible '&data,&web,vm2' --list-hosts -i hosts
  hosts (1):
    vm2
[root@vm1 apache]# ansible '&data,&web,vm2,vm3' --list-hosts -i hosts
  hosts (1):
    vm2

[root@vm1 apache]# vim hosts

vm5

[backup]
vm1
vm3
vm4

[web]
vm2
vm3
vm4

[data]
vm1
vm4

[root@vm1 apache]# ansible '!data,!backup' --list-hosts -i hosts
  hosts (2):
    vm5
    vm2
[root@vm1 apache]# ansible '!data,!backup,vm3' --list-hosts -i hosts
[WARNING]: No hosts matched, nothing to do
  hosts (0):

[root@vm1 apache]# ansible '!data,vm2' --list-hosts -i hosts
  hosts (1):
    vm2
[root@vm1 apache]# ansible '!data' --list-hosts -i hosts
  hosts (3):
    vm5
    vm3
    vm2



2. 动态清单

  • Ansible支持动态清单脚本,这些脚本在每当Ansible执行时从这些类型的来源检索当前的信息,使清单能够实时得到更新。
  • 动态清单脚本的使用方式与静态清单文本文件一样。清单的位置可以直接在当前的ansible.cfg文件中指定,或者通过-i选项指定。
  • 如果清单文件可以执行,则它将被视为动态清单程序,Ansible会尝试运行它来生成清单。

2.1 开源社区脚本

  • 开源社区向Ansible项目贡献了大量现有的动态清单脚本,这些脚本可从Ansible GigHub网站获取
  • github开源社区

2.2 ansible-inventory

  • 编写自定义清单程序可以使用任何编程语言,但传递适当的选项时必须以JSON格式返回清单信息。
  • ansible-inventory --list命令可以将静态清单以json格式显示
[root@vm1 apache]# vim inventory 
[webservers:children]
centos7
centos8

[centos7]
vm2

[centos8]
vm3

[root@vm1 apache]# ansible-inventory --list -i inventory 
{
    "_meta": {
        "hostvars": {
            "vm2": {
                "ansible_host": "172.16.104.131",
                "ansible_password": 123456
            },
            "vm3": {
                "ansible_host": "172.16.104.132",
                "ansible_password": 123456
            }
        }
    },
    "all": {
        "children": [
            "ungrouped",
            "webservers"
        ]
    },
    "centos7": {
        "hosts": [
            "vm2"
        ]
    },
    "centos8": {
        "hosts": [
            "vm3"
        ]
    },
    "webservers": {
        "children": [
            "centos7",
            "centos8"
        ]
    }
}

2.3 编写python动态清单脚本

  • 脚本以适当的解释器行开头(例如,#!usr/bin/python3),目的是让ansible能够运行
  • 在传递--list选项时,脚本必须显清单中所有主机和组的json字典
  • 此外,可以定义--host 参数,从而以json字典显示指定主机相关信息
  • 脚本清单必须是可执行文件
  • 以下是一个python脚本清单
[root@vm1 apache]# vim dy_inventory.py 
#!/usr/bin/python3
#coding:utf8

import json
import sys
def group():
    hosts={
        "_meta": {
            "hostvars": {
                "vm2": {
                    "ansible_host": "172.16.104.131",
                    "ansible_password": 123456,
                    "service_name": "httpd"
                },
                "vm3": {
                    "ansible_host": "172.16.104.132",
                    "ansible_password": 123456,
                    "service_name": "httpd"
                }
            }
        },
        "all": {
            "children": [
                "ungrouped",
                "webservers"
            ]
        },
        "centos7": {
            "hosts": [
                "vm2"
            ]
        },
        "centos8": {
            "hosts": [
                "vm3"
            ]
        },
        "webservers": { 
            "children": [
                "centos7",
                "centos8"
            ]
        }

    }
    print(json.dumps(hosts,indent=4))

def host(ip):
    hosts={
        "vm2": {
            "ansible_host": "172.16.104.131",
            "ansible_port": 22,
            "ansible_user": "root",
            "ansible_password": "123456"

        },
        "vm3": {
            "ansible_host": "172.16.104.132",
            "ansible_port": 22,
            "ansible_user": "root",
            "ansible_password": "123456",
        }
    }
    j = json.dumps(hosts[ip],indent=4)
    print(j)

def main():
    if len(sys.argv) == 2 and (sys.argv[1] == '--list'):
        group()
    elif len(sys.argv) == 3 and (sys.argv[1] == '--host'):
        host(sys.argv[2])
    else:
        print("Usage: %s --list or --host <hostname>" % sys.argv[0])

if __name__ == '__main__':    ##表示当直接执行该文件时,运行main()函
    main()

  • 执行该脚本
[root@vm1 apache]# ll dy_inventory.py 
-rwxr-xr-x. 1 root root 1754 Sep 14 23:32 dy_inventory.py
[root@vm1 apache]# ./dy_inventory.py --host vm2
{
    "ansible_host": "172.16.104.131",
    "ansible_port": 22,
    "ansible_user": "root",
    "ansible_password": "123456"
}

[root@vm1 apache]# ansible webservers -m ping -i dy_inventory.py 
vm2 | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    },
    "changed": false,
    "ping": "pong"
}
vm3 | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/libexec/platform-python"
    },
    "changed": false,
    "ping": "pong"
}

2.4 管理多个清单

  • Ansible支持在同一运行过程中使用多个清单。如果清单的位置是一个目录(即包多个清单),将组合该目录中包含的所有清单文件(不论是静态还是动态)来确定清单。其中可执行文件用于动态清单,其文作为静态清单。
  • 清单文件不应依赖于其他清单文件或脚本来解析。从而确保不论清单文件以什么顺序解析,它们在内部都一致。
  • 多个清单文件的解析顺序是以按字母排序的。若一个清单文件依赖另一个清单文件则很有可能因解析顺序不同造成影响。
  • ansible会忽略清单目录中某些特定后缀结尾的文件.(~, .orig, .bak, .ini, .cfg, .retry, .pyc, .pyo)
  • 使用动态清单
    link

  • 开发动态清单
    link

3. forks,serial的使用

3.1 forks

  • 理论上Ansible可以同时连接play中所有主机来执行每项任务。实际上受主机太多(上百台)则可能会给控制节点带来沉重负担。
  • 因此,forks参数用来指定ansible每次对受管主机操作的最大数量(默认为5)
##ansible.cfg配置文件
[root@vm1 apache]# grep forks /etc/ansible/ansible.cfg 
#forks          = 5

[root@vm1 apache]# ansible-config --help
usage: ansible-config [-h] [--version] [-v] {list,dump,view} ...
##选项
    list    Print all config options
    dump    Dump configuration ## 参数默认值
    view    View configuration file

[root@vm1 apache]# ansible-config dump | grep -i forks  ##-i忽略大小写
DEFAULT_FORKS(default) = 5

  • 默认情况下,ansible对play的执行是根据forks值分批对受管主机进行操作的,只有当所有受管主机执行完一个任务时才能开始执行下一个任务。
  • 根据控制机承受负载的能力适当调整forks值大小,从而提高ansible效率
  • 可以从命令行覆盖Ansible配置文件中forks的默认设置。ansible和ansible-playbook命令均提供-f或--forks选项以指定要使用的forks数量。

3.2 serial

  • serial参数值(也可以是百分比形式)指定每批次执行完play中所有任务的受管主机数量,下一批次再开始执行play
  • 此方式可以应用到更新一组服务器,又可以避免在更新期间所有服务停止服务。此外,若第一组执行play失败,整个play将会中断,从而确保剩下的主机还能正常运行。
  • 启用serial后的效果
[root@vm1 apache]# vim serial.yml 
---
- name: how serial to work
  hosts: webservers
  gather_facts: no
  serial: 1
  tasks:
    - name: reload httpd
      service:
        name: httpd
        state: reloaded
    - name: reuturn result
      debug:
        msg: "http servcie is reloaded"

## 执行play
[root@vm1 apache]# ansible-playbook serial.yml -i inventory 

PLAY [how serial to work] ******************************************************

TASK [reload httpd] ************************************************************
changed: [vm2]

TASK [reuturn result] **********************************************************
ok: [vm2] => {
    "msg": "http servcie is reloaded"
}

PLAY [how serial to work] ******************************************************

TASK [reload httpd] ************************************************************
changed: [vm3]

TASK [reuturn result] **********************************************************
ok: [vm3] => {
    "msg": "http servcie is reloaded"
}

  • 关闭serial的执行效果
TASK [reload httpd] ************************************************************
changed: [vm2]
changed: [vm3]

TASK [reuturn result] **********************************************************
ok: [vm2] => {
    "msg": "http servcie is reloaded"
}
ok: [vm3] => {
    "msg": "http servcie is reloaded"
}
  • 不启用serial,执行play失败后的效果
[root@vm1 apache]# ansible-playbook serial.yml -i inventory 

PLAY [how serial to work] ******************************************************

TASK [stop httpd] **************************************************************
changed: [vm2]
changed: [vm3]

TASK [reuturn result] **********************************************************
fatal: [vm2]: FAILED! => {"changed": false, "msg": "failed tasks"}
fatal: [vm3]: FAILED! => {"changed": false, "msg": "failed tasks"}

##检查受管主机状态
[root@vm1 apache]# ansible webservers -m command -a  "systemctl status httpd" -i inventory 

vm2 | FAILED | rc=3 >>
● httpd.service - The Apache HTTP Server
   Loaded: loaded (/usr/lib/systemd/system/httpd.service; enabled; vendor preset: disabled)
   Active: inactive (dead)
.............................
Sep 14 01:46:30 vm2 systemd[1]: Reloading The Apache HTTP Server.
Sep 14 01:46:31 vm2 systemd[1]: Reloaded The Apache HTTP Server.
Sep 14 01:54:17 vm2 systemd[1]: Stopping The Apache HTTP Server...
Sep 14 01:54:18 vm2 systemd[1]: Stopped The Apache HTTP Server.non-zero return code

vm3 | FAILED | rc=3 >>
● httpd.service - The Apache HTTP Server
   Loaded: loaded (/usr/lib/systemd/system/httpd.service; enabled; vendor preset: disabled)
   Active: inactive (dead)
...............................
Sep 14 01:46:31 vm3 systemd[1]: Reloaded The Apache HTTP Server.
Sep 14 01:46:31 vm3 httpd[4605]: Server configured, listening on: port 81, port 80
Sep 14 01:54:17 vm3 systemd[1]: Stopping The Apache HTTP Server...
Sep 14 01:54:18 vm3 systemd[1]: Stopped The Apache HTTP Server.non-zero return code
  • 开启serial后,play执行失败后的效果
[root@vm1 apache]# ansible webservers -m command -a  "systemctl start httpd" -i inventory 
vm2 | CHANGED | rc=0 >>

vm3 | CHANGED | rc=0 >>

[root@vm1 apache]# vim serial.yml 
---
- name: how serial to work
  hosts: webservers
  gather_facts: no
  serial: 1
  tasks:
    - name: stop httpd
      service:
        name: httpd
        state: stopped
    - name: reuturn result
      fail:
        msg: "failed tasks"
~                             


##执行效果
[root@vm1 apache]# ansible-playbook serial.yml -i inventory 

PLAY [how serial to work] ******************************************************

TASK [stop httpd] **************************************************************
changed: [vm2]

TASK [reuturn result] **********************************************************
fatal: [vm2]: FAILED! => {"changed": false, "msg": "failed tasks"}

PLAY RECAP *********************************************************************
vm2                        : ok=1    changed=1    unreachable=0    failed=1    skipped=0    rescued=0    ignored=0

##检测受管主机http状态
[root@vm1 apache]# ansible webservers -m command -a  "systemctl status httpd" -i inventory 
vm2 | FAILED | rc=3 >>
● httpd.service - The Apache HTTP Server
   Loaded: loaded (/usr/lib/systemd/system/httpd.service; enabled; vendor preset: disabled)
   Active: inactive (dead) since Mon 2020-09-14 02:03:50 CST; 1min 26s ago
......................................
Sep 14 02:01:30 vm2 systemd[1]: Starting The Apache HTTP Server...
Sep 14 02:01:31 vm2 systemd[1]: Started The Apache HTTP Server.
Sep 14 02:03:49 vm2 systemd[1]: Stopping The Apache HTTP Server...
Sep 14 02:03:50 vm2 systemd[1]: Stopped The Apache HTTP Server.non-zero return code

vm3 | CHANGED | rc=0 >>
● httpd.service - The Apache HTTP Server
   Loaded: loaded (/usr/lib/systemd/system/httpd.service; enabled; vendor preset: disabled)
   Active: active (running) since Mon 2020-09-14 02:01:31 CST; 3min 46s 
........................................
Sep 14 02:01:30 vm3 systemd[1]: Starting The Apache HTTP Server...
Sep 14 02:01:31 vm3 systemd[1]: Started The Apache HTTP Server.
Sep 14 02:01:31 vm3 httpd[6016]: Server configured, listening on: port 81, port 80

4. include,import

  • Ansible可以使用两种操作将内容带入playbook。include以及import
  • include是一个动态操作。在playbook运行期间,Ansible会在内容到达时处理所包含的内容。
  • import是一个静态操作。在运行开始之前,Ansible在最初解析playbook时预处理导入的内容。

4.1 import_playbook

  • import_playbook指令允许将外部文件按导入顺序导入playbook并顺序执。
  • 由于导入的内容是一个完整的playbook,因此import_playbook功能只能在playbook的顶层使用,不能在play的tasks内使用。
  • 导入案例1
[root@vm1 apache]# cat test.yml 
- import_playbook: main.yml
- import_playbook: import.yml

## 执行效果
[root@vm1 apache]# ansible-playbook test.yml -i inventory 
PLAY [import main.yml] *********************************************************

TASK [debug] *******************************************************************
ok: [vm2] => {
    "msg": "the information of vm2 :"
}

PLAY [import import.yml] *******************************************************

TASK [Gathering Facts] *********************************************************
ok: [vm2]

TASK [debug] *******************************************************************
ok: [vm2] => {
    "ansible_facts['default_ipv4']": {
        "address": "172.16.104.131",
        "alias": "eth0",
        "broadcast": "172.16.104.255",
        "gateway": "172.16.104.2",
        "interface": "eth0",
        "macaddress": "00:0c:29:46:19:84",
        "mtu": 1500,
        "netmask": "255.255.255.0",
        "network": "172.16.104.0",
        "type": "ether"
    }
}

  • 导入案例2
[root@vm1 apache]# vim main.yml 
---
- name: import main.yml
  hosts: vm2
  gather_facts: no
  tasks:
    - debug:
        msg: "the information of vm2 :"

- import_playbook: import.yml  ##顶层使用

[root@vm1 apache]# ansible-playbook  main.yml -i inventory 

PLAY [import main.yml] *********************************************************

TASK [debug] *******************************************************************
ok: [vm2] => {
    "msg": "the information of vm2 :"
}

PLAY [import import.yml] *******************************************************

TASK [Gathering Facts] *********************************************************
ok: [vm2]

TASK [debug] *******************************************************************
ok: [vm2] => {
    "ansible_facts['default_ipv4']": {
        "address": "172.16.104.131",
        "alias": "eth0",
        "broadcast": "172.16.104.255",
        "gateway": "172.16.104.2",
        "interface": "eth0",
        "macaddress": "00:0c:29:46:19:84",
        "mtu": 1500,
        "netmask": "255.255.255.0",
        "network": "172.16.104.0",
        "type": "ether"
    }
}

4.2 import_tasks

  • 使用import_tasks功能将任务文件静态导入playbook内的tasks中,解析该playbook时将直接插入导入的任务。
[root@vm1 apache]# vim import_tasks.yml 
- setup:
- name: get information of vm2
  debug:
    var: ansible_facts['default_ipv4']
    
[root@vm1 apache]# vim main.yml    
---
- hosts: vm2
  gather_facts: no
  tasks:
    - debug:
        msg: "the information of vm2 :"
    - import_tasks: import_tasks.yml

[root@vm1 apache]# ansible-playbook main.yml -i inventory 

PLAY [vm2] *********************************************************************

TASK [debug] *******************************************************************
ok: [vm2] => {
    "msg": "the information of vm2 :"
}

TASK [setup] *******************************************************************
ok: [vm2]

TASK [get information of vm2] **************************************************
ok: [vm2] => {
    "ansible_facts['default_ipv4']": {
        "address": "172.16.104.131",
        "alias": "eth0",
        "broadcast": "172.16.104.255",
        "gateway": "172.16.104.2",
        "interface": "eth0",
        "macaddress": "00:0c:29:46:19:84",
        "mtu": 1500,
        "netmask": "255.255.255.0",
        "network": "172.16.104.0",
        "type": "ether"
    }
}
  • 由于是静态导入,会出现以下问题
  1. 使用import_tasks功能时,导入时设置的when等条件语句应用于导入的每个任务(并且在每次应用时会重新检测条件)
  2. 由于import_tasks会对其内的每一个task重新检查when条件,执行导入的任务时可能会修改条件值,因此import_tasks不能使用循环功能
  3. 如果使用变量来指定要导入的文件的名称,则将无法使用动态变量,也不能使用主机或者组清单变量
[root@vm1 apache]# vim import_tasks.yml 
- name: get information of vm2
  debug:
    var: ansible_facts['default_ipv4']

- set_fact: boolean=false
- service:
    name: httpd
    state: reloaded

[root@vm1 apache]# vim main.yml 
---
- hosts: vm2
  vars:
    taskname: import_tasks.yml
    boolean: true
  tasks:
    - debug:
        msg: "the information of vm2 :"
    - import_tasks: "{{taskname}}"
      when: boolean

## 执行效果
[root@vm1 apache]# ansible-playbook  main.yml  -i inventory 

PLAY [vm2] *********************************************************************

TASK [Gathering Facts] *********************************************************
ok: [vm2]

TASK [debug] *******************************************************************
ok: [vm2] => {
    "msg": "the information of vm2 :"
}

TASK [get information of vm2] **************************************************
ok: [vm2] => {
    "ansible_facts['default_ipv4']": {
        "address": "172.16.104.131",
        "alias": "eth0",
        "broadcast": "172.16.104.255",
        "gateway": "172.16.104.2",
        "interface": "eth0",
        "macaddress": "00:0c:29:46:19:84",
        "mtu": 1500,
        "netmask": "255.255.255.0",
        "network": "172.16.104.0",
        "type": "ether"
    }
}

TASK [set_fact] ****************************************************************
ok: [vm2]

TASK [service] *****************************************************************
skipping: [vm2]

## 导入的任务二中由于boolean变量值被覆盖,所以再次检测when语句时任务二条件成立
  • 测试import不能使用动态变量,主机或组清单变量
[root@vm1 apache]# vim main.yml 
---
- hosts: vm2
  vars:
    boolean: true
  tasks:
    - set_fact:     ## 设置一个动态变量
        taskname: import_tasks.yml
    - debug:
        msg: "the information of vm2 :"
    - import_tasks: "{{taskname}}"    
      when: boolean

## 测试效果
[root@vm1 apache]# ansible-playbook --syntax-check main.yml -i inventory 
ERROR! Error when evaluating variable in import path: {{taskname}}.

When using static imports, ensure that any variables used in their names are defined in vars/vars_files
or extra-vars passed in from the command line. Static imports cannot use variables from facts or inventory
sources like group or host vars.
[root@vm1 apache]# cat host_vars/vm2/xx.yml 
taskname: import_tasks.yml

[root@vm1 apache]# vim main.yml 
---
- hosts: vm2
  vars:
    boolean: true
  tasks:
    - debug:
        msg: "the information of vm2 :"
    - import_tasks: "{{taskname}}"
      when: boolean
[root@vm1 apache]# ansible-playbook --syntax-check main.yml -i inventory 
ERROR! Error when evaluating variable in import path: {{taskname}}.

When using static imports, ensure that any variables used in their names are defined in vars/vars_files
or extra-vars passed in from the command line. Static imports cannot use variables from facts or inventory
sources like group or host vars.

4.3 include_tasks

  • include_tasks功能将任务文件动态导入playbook内的play中
  • include_tasks本身会被当做是一个task,这个task会把include的文件路径输出在控制台中,import_tasks则不会。
  • 使用include_tasks功能时,包含时设置的when等条件语句只会应用于"include_tasks"任务本身,当执行被包含的任务时,不会对这些被包含的任务重新进行条件判断。
[root@vm1 apache]# vim main.yml 
---
- hosts: vm2
  vars:
    boolean: true
  tasks:
    - set_fact:
        taskname: include_tasks.yml
    - debug:
        msg: "the information of vm2 :"
    - include_tasks: "{{taskname}}"
      when: boolean
    - debug:
        var: boolean

[root@vm1 apache]# vim include_tasks.yml 
- name: get information of vm2
  debug:
    var: ansible_facts['default_ipv4']

- set_fact: boolean=false
- service:
    name: httpd
    state: reloaded

## 执行效果
[root@vm1 apache]# ansible-playbook  main.yml -i inventory 

PLAY [vm2] *********************************************************************

TASK [Gathering Facts] *********************************************************
ok: [vm2]

TASK [set_fact] ****************************************************************
ok: [vm2]

TASK [debug] *******************************************************************
ok: [vm2] => {
    "msg": "the information of vm2 :"
}

TASK [include_tasks] ***********************************************************
included: /opt/apache/include_tasks.yml for vm2

TASK [get information of vm2] **************************************************
ok: [vm2] => {
    "ansible_facts['default_ipv4']": {
        "address": "172.16.104.131",
        "alias": "eth0",
        "broadcast": "172.16.104.255",
        "gateway": "172.16.104.2",
        "interface": "eth0",
        "macaddress": "00:0c:29:46:19:84",
        "mtu": 1500,
        "netmask": "255.255.255.0",
        "network": "172.16.104.0",
        "type": "ether"
    }
}

TASK [set_fact] ****************************************************************
ok: [vm2]

TASK [service] *****************************************************************
changed: [vm2]

TASK [debug] *******************************************************************
ok: [vm2] => {
    "boolean": false
}
## 可以看到,使用include_tasks时,包含任务里修改了主play的条件值,但这并不影响
  • 不能使用ansible-playbook --start-at-task从已包含任务文件中的任务开始执行playbook
  • 不能使用notify语句触发包含任务文件中的处理程序名称。可以在包含整个任务文件的主playbook中触发处理程序,在这种情况下,已包含文件中的所有任务都将运行
  • include_tasks使用notify情况1
[root@vm1 apache]# vim include_tasks.yml 
- name: get information of vm2
  debug:
    var: ansible_facts['default_ipv4']
- set_fact: boolean=false
- service:
    name: httpd
    state: reloaded
  notify: 
    - reload httpd

[root@vm1 apache]# vim main.yml 
---
- hosts: vm2
  vars:
    boolean: true
    - debug:
        msg: "the information of vm2 :"
    - include_tasks: include_tasks.yml
      when: boolean
  
  handlers: 
    - name: reload httpd
      debug:
        msg: " httpd is reloaded!"
[root@vm1 apache]# ansible-playbook --syntax-check main.yml -i inventory 

playbook: main.yml

[root@vm1 apache]# ansible-playbook main.yml -i inventory 
PLAY [vm2] *********************************************************************

TASK [Gathering Facts] *********************************************************
ok: [vm2]

TASK [service] *****************************************************************
changed: [vm2]

TASK [debug] *******************************************************************
ok: [vm2] => {
    "msg": "the information of vm2 :"
}

TASK [include_tasks] ***********************************************************
included: /opt/apache/include_tasks.yml for vm2

TASK [get information of vm2] **************************************************
ok: [vm2] => {
    "ansible_facts['default_ipv4']": {
        "address": "172.16.104.131",
        "alias": "eth0",
        "broadcast": "172.16.104.255",
        "gateway": "172.16.104.2",
        "interface": "eth0",
        "macaddress": "00:0c:29:46:19:84",
        "mtu": 1500,
        "netmask": "255.255.255.0",
        "network": "172.16.104.0",
        "type": "ether"
    }
}

TASK [set_fact] ****************************************************************
ok: [vm2]

RUNNING HANDLER [reload httpd] *************************************************
ok: [vm2] => {
    "msg": " httpd is reloaded!"
}
  • 使用handlers情况2
[root@vm1 apache]# vim main.yml 
---
- hosts: vm2
  tasks:
    - file:
        path: /opt/wisan
        state: directory
      notify:
        - reload httpd
  handlers:
    - name: reload httpd
      include_tasks: include_tasks.yml

[root@vm1 apache]# ansible-playbook  main.yml -i inventory 

PLAY [vm2] *********************************************************************

TASK [Gathering Facts] *********************************************************
ok: [vm2]

TASK [file] ********************************************************************
changed: [vm2]

RUNNING HANDLER [reload httpd] *************************************************
included: /opt/apache/include_tasks.yml for vm2

RUNNING HANDLER [service] ******************************************************
changed: [vm2]

4.4 管理任务文件

  • 为方便管理,可以创建专门用于任务文件的目录,并将所有任务文件保存在该目录中。然后playbook就可以从该目录包含或导入任务文件。这样就可以构建复杂的playbook,同时简化其结构和组件的管理。

4.5 为外部文件定义变量

  • 使用Ansible的导入和包含功能将外部文件中的play或任务合并到playbook中极大地增强了在Ansible环境中重用任务和playbook的能力。为了最大限度地提高重用可能性,这些任务和play文件应尽可能通用。
  • import_tasks 变量在外部定义
[root@vm1 apache]# cat reload.yml 
- name: Start the {{ service }} service
  service:
    name: "{{ service }}"
    state: reloaded
[root@vm1 apache]# cat main.yml 
---
- hosts: vm2
  tasks:
    - name: Import task file and set variables
      import_tasks: reload.yml
      vars:
        service: httpd      
        
[root@vm1 apache]# ansible-playbook  main.yml -i inventory 

PLAY [vm2] *********************************************************************

TASK [Gathering Facts] *********************************************************
ok: [vm2]

TASK [Start the httpd service] *************************************************
changed: [vm2]

PLAY RECAP *********************************************************************
vm2                        : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

  • include_tasks 在外部定义变量
[root@vm1 apache]# vim main.yml 
---
- hosts: vm2
  tasks:
    - name: Import task file and set variables
      include_tasks: reload.yml
      vars:
        service: httpd

[root@vm1 apache]# ansible-playbook  main.yml -i inventory 

PLAY [vm2] *********************************************************************

TASK [Gathering Facts] *********************************************************
ok: [vm2]

TASK [Import task file and set variables] **************************************
included: /opt/apache/reload.yml for vm2

TASK [Start the httpd service] *************************************************
changed: [vm2]

PLAY RECAP *********************************************************************
vm2                        : ok=3    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0  
posted @ 2020-09-14 13:39  小芃总  阅读(247)  评论(0)    收藏  举报