实施任务控制

实施任务控制

编写循环和条件任务

利用循环迭代任务

通过利用循环,我们无需编写多个使用同一模块的任务。例如,他们不必编写五个任务来确保存在五个用户,而是只需编写一个任务来对含有五个用户的列表迭代,从而确保它们都存在。

Ansible支持使用loop关键字对一组项目迭代任务。可以配置循环以利用列表中的各个项目、列表中各个文件的内容、生成的数字序列或更为复杂的结构来重复任务。

简单循环

简单循环对一组项目迭代任务。loop关键字添加到任务中,将应对其迭代任务的项目列表取为值。循环变量item保存每个迭代过程中使用的值。

创建用户不用循环
[root@control book]# cat   debug/loop.yml---
- name: look
  hosts: server1
  tasks:
    - name: cat  loop
      user: 
        name: tom
        uid: 1201
        state: present 

[root@server1 ~]# id  tom
uid=1201(tom) gid=1201(tom) groups=1201(tom)

用循环创建用户
[root@control book]# cat   debug/loop.yml 
---
- name: look
  hosts: server1
  tasks:
    - name: cat  loop
      user: 
        name: '{{ item  }}'
        state: present 

      loop:
        - time1
        - time2
        - time3

[root@control book]# ansible-playbook debug/loop.yml   

PLAY [look] ********************************************************************

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

TASK [cat  loop] ***************************************************************
changed: [192.168.56.130] => (item=time1)
changed: [192.168.56.130] => (item=time2)
changed: [192.168.56.130] => (item=time3)

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

//查看结果

[root@server1 ~]# id  time1
uid=1202(time1) gid=1202(time1) groups=1202(time1)
[root@server1 ~]# id  time2
uid=1203(time2) gid=1203(time2) groups=1203(time2)
[root@server1 ~]# id  time3
uid=1204(time3) gid=1204(time3) groups=1204(time3)
在循环里使用变量
---
- name: look
  hosts: server1
  vars_files:         //局外变量模块
    - /opt/book/debug/users.yml   //变量文件地址
  tasks:
    - name: cat  loop
      user:                   //创建用户模块
        name: '{{ item  }}'    //loop循环关键字
        state: present
      loop: "{{ users  }}"     //引用变量


//创建变量文件
[root@control book]# cat   debug/users.yml 
users: 
 - time1
 - time2
 - time3
 - time4

//运行
[root@control book]# ansible-playbook debug/loop.yml 

PLAY [look] ********************************************************************

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

TASK [cat  loop] ***************************************************************
changed: [192.168.56.130] => (item=time1)
changed: [192.168.56.130] => (item=time2)
changed: [192.168.56.130] => (item=time3)
changed: [192.168.56.130] => (item=time4)

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


//查看结果
[root@server1 ~]# id  time1
uid=1001(time1) gid=1001(time1) groups=1001(time1)
[root@server1 ~]# id  time2
uid=1002(time2) gid=1002(time2) groups=1002(time2)
[root@server1 ~]# id  time3
uid=1003(time3) gid=1003(time3) groups=1003(time3)
[root@server1 ~]# id  time4
uid=1004(time4) gid=1004(time4) groups=1004(time4)
循环散列或字典表

loop列表不需要是简单值列表。在以下示例中,列表中的每个项实际上是散列或字典。示例中的每个散列或字典具有两个键,即namegroups,当前item循环变量中每个键的值可以分别通过item.nameitem.groups变量来检索。

//编写变量文件
[root@control book]# cat debug/users.yml 
users: 
 - name: time1
   uid: 2000
 - name: time2
   uid: 2001
 - name: time3
   uid: 2002


[root@control book]# cat debug/loop.yml 
---
- name: look
  hosts: server1
  vars_files:
    - /opt/book/debug/users.yml
  tasks:
    - name: cat  loop
      user: 
        name: "{{ item.name  }}"
        uid: "{{ item.uid  }}"
        state: present 
      loop: "{{ users  }}"

//执行
[root@control book]# ansible-playbook debug/loop.yml 

PLAY [look] ********************************************************************

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

TASK [cat  loop] ***************************************************************
changed: [192.168.56.130] => (item={'name': 'time1', 'uid': 2000})
changed: [192.168.56.130] => (item={'name': 'time2', 'uid': 2001})
changed: [192.168.56.130] => (item={'name': 'time3', 'uid': 2002})

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


//结果
[root@server1 ~]# id  time1
uid=2000(time1) gid=2000(time1) groups=2000(time1)
[root@server1 ~]# id  time2
uid=2001(time2) gid=2001(time2) groups=2001(time2)
[root@server1 ~]# id  time3
uid=2002(time3) gid=2002(time3) groups=2002(time3)
将Register变量与Loop一起使用

register关键字也可以捕获循环任务的输出。以下代码片段显示了循环任务中register变量的结构:

[root@control book]# cat   debug/loop.yml ---
- name: look
  hosts: server1
  tasks:
    - name: cat  loop
      command: "echo hello {{ item  }} ,your  name?"  
      loop:         //循环
        - lisi
        - wangwu
        - xiaohong
      register: result       //注册变量

    - debug:           //收集事实模块        
        var: result     //输出指定事实


[root@control book]# ansible-playbook debug/loop.yml 

PLAY [look] ********************************************************************

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

TASK [cat  loop] ***************************************************************
changed: [192.168.56.130] => (item=lisi)
changed: [192.168.56.130] => (item=wangwu)
changed: [192.168.56.130] => (item=xiaohong)

TASK [debug] *******************************************************************
ok: [192.168.56.130] => {
    "result": {
        "changed": true,
        "msg": "All items completed",
        "results": [
            {
                "ansible_loop_var": "item",
                "changed": true,
                "cmd": [
                    "echo",
                    "hello",
                    "lisi",
                    ",your",
                    "name?"
                ],
                "delta": "0:00:00.002498",
                "end": "2021-07-25 12:47:50.353290",
                "failed": false,
                "invocation": {
                    "module_args": {
                        "_raw_params": "echo hello lisi ,your  name?",
                        "_uses_shell": false,
                        "argv": null,
                        "chdir": null,
                        "creates": null,
                        "executable": null,
                        "removes": null,
                        "stdin": null,
                        "stdin_add_newline": true,
                        "strip_empty_ends": true,
                        "warn": true
                    }
                },
                "item": "lisi",
                "rc": 0,
                "start": "2021-07-25 12:47:50.350792",
                "stderr": "",
                "stderr_lines": [],
                "stdout": "hello lisi ,your name?",
                "stdout_lines": [
                    "hello lisi ,your name?"
                ]
            },
            {
                "ansible_loop_var": "item",
                "changed": true,
                "cmd": [
                    "echo",
                    "hello",
                    "wangwu",
                    ",your",
                    "name?"
                ],
                "delta": "0:00:00.001697",
                "end": "2021-07-25 12:47:50.551735",
                "failed": false,
                "invocation": {
                    "module_args": {
                        "_raw_params": "echo hello wangwu ,your  name?",
                        "_uses_shell": false,
                        "argv": null,
                        "chdir": null,
                        "creates": null,
                        "executable": null,
                        "removes": null,
                        "stdin": null,
                        "stdin_add_newline": true,
                        "strip_empty_ends": true,
                        "warn": true
                    }
                },
                "item": "wangwu",
                "rc": 0,
                "start": "2021-07-25 12:47:50.550038",
                "stderr": "",
                "stderr_lines": [],
                "stdout": "hello wangwu ,your name?",
                "stdout_lines": [
                    "hello wangwu ,your name?"
                ]
            },
            {
                "ansible_loop_var": "item",
                "changed": true,
                "cmd": [
                    "echo",
                    "hello",
                    "xiaohong",
                    ",your",
                    "name?"
                ],
                "delta": "0:00:00.001758",
                "end": "2021-07-25 12:47:50.751189",
                "failed": false,
                "invocation": {
                    "module_args": {
                        "_raw_params": "echo hello xiaohong ,your  name?",
                        "_uses_shell": false,
                        "argv": null,
                        "chdir": null,
                        "creates": null,
                        "executable": null,
                        "removes": null,
                        "stdin": null,
                        "stdin_add_newline": true,
                        "strip_empty_ends": true,
                        "warn": true
                    }
                },
                "item": "xiaohong",
                "rc": 0,
                "start": "2021-07-25 12:47:50.749431",
                "stderr": "",
                "stderr_lines": [],
                "stdout": "hello xiaohong ,your name?",
                "stdout_lines": [
                    "hello xiaohong ,your name?"
                ]
            }
        ]
    }
}


有条件地运行任务

Ansible可使用conditionals在符合特定条件时执行任务或play。例如,可以利用一个条件在Ansible安装或配置服务前确定受管主机上的可用内存。

我们可以利用条件来区分不同的受管主机,并根据它们所符合的条件来分配功能角色。Playbook变量、注册的变量和Ansible事实都可通过条件来进行测试。可以使用比较字符串、数字数据和布尔值的运算符。

以下场景说明了在Ansible中使用条件的情况:

  • 可以在变量中定义硬限制(如min_memory)并将它与受管主机上的可用内存进行比较。
  • Ansible可以捕获并评估命令的输出,以确定某一任务在执行进一步操作前是否已经完成。例如,如果某一程序失败,则将路过批处理。
  • 可以利用Ansible事实来确定受管主机网络配置,并决定要发送的模板文件(如,网络绑定或中继)。
  • 可以评估CPU的数量,来确定如何正确调节某一Web服务器。
  • 将注册的变量与预定义的变量进行比较,以确定服务是否已更改。例如,测试服务配置文件的MD5检验以和查看服务是否已更改。
条件语法

when语句用于有条件地运行任务。它取要测试的条件为值。如果条件满足,则运行任务。如果条件不满足,则跳过任务。

可以测试的一个最简单条件是某一布尔变量是True还是False。以下示例中的when语句导致任务仅在run_my_taskTrue时运行:

[root@control book]# cat  debug/us.yml 
---
- name: look
  hosts: server1
  vars_files:
    - /opt/book/debug/users.yml
  vars:
    power: False        //布尔值 否
  tasks:
    - name: cat  where
      user:
        name: "{{ item.name  }}"
        uid: "{{ item.uid  }}"
        state: present 
      loop: "{{ users  }}"
      when: power


[root@control book]# ansible-playbook debug/us.yml 

PLAY [look] ********************************************************************

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

TASK [cat  where] **************************************************************
skipping: [192.168.56.130] => (item={'name': 'time1', 'uid': 2000}) 
skipping: [192.168.56.130] => (item={'name': 'time2', 'uid': 2001}) 
skipping: [192.168.56.130] => (item={'name': 'time3', 'uid': 2002}) 
//略过
PLAY RECAP *********************************************************************
192.168.56.130             : ok=1    changed=0    unreachable=0    failed=0    skipped=1    rescued=0    ignored=0   

[root@control debug]# cat users.yml 
users: 
 - name: time1
   uid: 2000
 - name: time2
   uid: 2001
 - name: time3
   uid: 2002


[root@control book]# cat  debug/us.yml 
---
- name: look
  hosts: server1
  vars_files:
    - /opt/book/debug/users.yml
  tasks:
    - name: cat  where
      user:
        name: "{{ item.name  }}"
        uid: "{{ item.uid  }}"
        state: present 
      loop: "{{ users  }}"
      when: '"{{ item.name }}"  ==  "time1"' //只允许time1执行

//运行结果
[root@control book]# ansible-playbook debug/us.yml 

PLAY [look] ********************************************************************

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

TASK [cat  where] **************************************************************
[WARNING]: conditional statements should not include jinja2 templating
delimiters such as {{ }} or {% %}. Found: "{{ item.name }}"  ==  "time1"
changed: [192.168.56.130] => (item={'name': 'time1', 'uid': 2000})   //通过
skipping: [192.168.56.130] => (item={'name': 'time2', 'uid': 2001}) 
skipping: [192.168.56.130] => (item={'name': 'time3', 'uid': 2002}) 

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


[root@server1 ~]# id  time1
uid=2000(time1) gid=2000(time1) groups=2000(time1)

以下示例测试my_service变量是否具有值。若有值,则将my_service的值用作要安装的软件包的名称。如果未定义my_service变量,则跳过任务且不显示错误。

[root@control book]# cat  debug/us.yml 
---
- name: look
  hosts: server1
  vars_files:
    - /opt/book/debug/users.yml
  tasks:
    - name: cat  where
      user:
        name: "{{ users.name }}"
        state: present 
      when: user is  defined  //只执行变量存在的值

下表显示了在处理条件时可使用的一些运算:

示例条件

操作示例
等于(值为字符串)ansible_machine == “x86_64”
等于(值为数字)max_memory == 512
小于min_memory < 128
大于min_memory > 256
小于等于min_memory <= 256
大于等于min_memory >= 512
不等于min_memory != 512
变量存在min_memory is defined
变量不存在min_memory is not defined
布尔变量是True。1、True或yes的求值为Truememory_available
布尔变量是False。0、False或no的求值为Falsenot memory_available
第一个变量的值存在,作为第二个变量的列表中的值ansible_distribution in supported_distros
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值