Ansible高级语法


一.循环迭代(loop/with_items)

1.作用 主要是用于让管理节点在需要编写多个任务时的情况下仅用一个任务来进行循环迭代完成任务,使用loop关键字对目标进行迭代,在ansible相对比较旧的版本中使用的with_item平替,现在我的2.9.27仍然兼容,loop关键字内可以是列表、变量、字典等

2.案例演示 (1)遍历输出以列表形式定义的abc

[root@main zuolaoshi]# cat loop1.yaml 
---
- hosts: servera
    tasks:
      - name: test item
        debug: 
          msg: "{{ item }}"
        loop:
          - 'a'
          - 'b'
          - 'c'

[root@main zuolaoshi]# ansible-playbook loop1.yaml
ok: [servera] => (item=a) => {
    "msg": "a"
}
ok: [servera] => (item=b) => {
    "msg": "b"
}
ok: [servera] => (item=c) => {
    "msg": "c"
}

(2)遍历输出以变量定义的webservers组内主机

[root@main zuolaoshi]# cat loop1.yaml 
---
- hosts: servera
    tasks:
      - name: test item
        debug: 
          msg: "{{ item }}"
        loop: "{{ groups.webservers }}"

[root@main zuolaoshi]# ansible-playbook loop1.yaml
ok: [servera] => (item=servera) => {
    "msg": "servera"
}
ok: [servera] => (item=serverb) => {
    "msg": "serverb"
}

(3)遍历输出以字典定义的数据 循环输出hello和nihao

[root@main zuolaoshi]# cat loop1.yaml 
---
- hosts: servera
    tasks:
      - name: test item
        debug: 
          msg: "{{ item }}"
        loop:
          - x1: 'hello'
          - x2: 'nihao'


[root@main zuolaoshi]# ansible-playbook loop1.yaml
ok: [servera] => (item={u'x1': u'hello'}) => {
"msg": {
"x1": "hello"
}
}
ok: [servera] => (item={u'x2': u'nihao'}) => {
"msg": {
"x2": "nihao"
}
}

(4)遍历嵌套定义的loop 循环创建user1和user2

[root@main zuolaoshi]# cat loopuser.yaml 
---
- hosts: servera
    tasks:
      - name: create user1 and user2
       user:
          name: "{{ item.name }}"
          state: present
          uid: "{{ item.uid }}"
       loop:
          - name: user1
            uid: 1011
          - name: user2
            uid: 1012

[root@main zuolaoshi]# ansible servera -a 'id user1'
servera | CHANGED | rc=0 >>
uid=1011(user1) gid=1011(user1) groups=1011(user1)
[root@main zuolaoshi]# ansible servera -a 'id user2'
servera | CHANGED | rc=0 >>
uid=1012(user2) gid=1012(user2) groups=1012(user2)

二.条件判断(when)

1.作用 (1)条件判断用于此任务的结果依赖变量、fact或者是上一个任务的结果,用条件判断就可以决定如何去执行对应的任务。在节点上建立了限制,捕获那些命令的输出,结果不同,执行的任务要求不同。

(2)可以判断某服务的配置文件是否发生变动时考虑是否重启。

(3)可以根据cpu状况来定制合适的调优策略

2.when语句的比较运算符 (1)!=/==用于比较两个对象是否不等/相等,可用于字符串、数字类型 示例

[root@main zuolaoshi]# cat bijiao.yaml 
---
- hosts: servera
    tasks:
      - name: com them
        debug:
          msg: '等于'
        when: name == owner
        vars:
          name: sulibao
          owner: sulibao


ok: [servera] => {
    "msg": "等于"
}

(2)>/<,>=/<=用于比较两个对象的大小 示例

[root@main zuolaoshi]# cat bijiao.yaml 
---
- hosts: servera
    tasks:
      - name: com them
        debug:
          msg: 'hello'
        when: name >= owner
        vars:
          name: sul
          owner: li

ok: [servera] => {
    "msg": "hello"
}

3.when语句的逻辑运算符 (1)and,逻辑与,两个对象同真为真

[root@main zuolaoshi]# cat when.yaml 
---

- hosts: servera
    tasks:
      - name: dis info
        debug:
          msg: "yes"
        when: 1 > 0 and 1 < 9

ok: [servera] => {
    "msg": "yes"
}

(2)or,逻辑或,两个对象见真为真

[root@main zuolaoshi]# cat when.yaml 
---

- hosts: servera
    tasks:
      - name: dis info
        debug:
          msg: "yes"
        when: 1 > 0 or 1 < 9

ok: [servera] => {
    "msg": "yes"
}

(3)not,逻辑否,取反

[root@main zuolaoshi]# cat when.yaml 
---
- hosts: servera
    tasks:
      - name: dis info
        debug:
          msg: "yes"
        when: not 1 > 0 and 1 < 9

skipping: [servera]

(4)(),作为一个更大的表达式包含一组表达式

[root@main zuolaoshi]# cat when.yaml 
---

- hosts: servera
    tasks:
      - name: dis info
        debug:
          msg: "yes"
        when: (not 1 > 0 and 1 < 9) or 5 < 6

ok: [servera] => {
    "msg": "yes"
}

4.when语句的exists判断 (1)判断目录是否存在

[root@main zuolaoshi]# cat test.yaml 
---
- hosts: servera
    tasks:
      - debug:
        msg: "directory exist"
        when: path is exists
        vars:
          path: /root

ok: [servera] => {
    "msg": "directory exist"
}

(2)判断文件是否不存在,取反操作

[root@main zuolaoshi]# cat test.yaml 
---

- hosts: servera
    tasks:
      - debug:
        msg: "file not exist"
        when: not path is exists
        vars:
          path: /root/ansible.bak

ok: [servera] => {
    "msg": "file not exist"
}

5.when语句对于变量的判断 (1)defined,变量已被定义

[root@main zuolaoshi]# cat varswhen.yaml 
---

- hosts: servera
    tasks:
      - name: test vars
        debug:
          msg: "var defined"
        when: inventory_hostname is defined

ok: [servera] => {
    "msg": "var defined"
}

(2)变量未被定义

[root@main zuolaoshi]# cat varswhen.yaml 
---
- hosts: servera
    tasks:
      - name: test vars
        debug:
          msg: "var undefined"
        when: a is undefined

ok: [servera] => {
    "msg": "var undefined"
}

(3)变量被定义为空

[root@main zuolaoshi]# cat varswhen.yaml 
---

- hosts: servera
    vars:
      a:
    tasks:
      - name: test vars
        debug:
          msg: "var none"
        when: a is none

ok: [servera] => {
    "msg": "var none"
}

6.when语句对于结果的判断 (1)success/succeeded,failure/failed判断任务任性成功与否

[root@main zuolaoshi]# cat result.yaml 
---

- hosts: servera
    tasks:
      - name: cd result
        shell: "cd /cevd"
        ignore_errors: true   #为了测试结果完整,忽略错误
        register: result
      - name: test result
        debug:
          msg: "no directory /cevd"
        when: not result is success

ok: [servera] => {
    "msg": "no directory /cevd"
}

(2)change/changed,skip/skipped判断任务执行状态

[root@main zuolaoshi]# cat result.yaml 
---

- hosts: servera
    tasks:
      - name: cd result
       shell: "touch /a.txt"
       ignore_errors: true
       register: result
      - name: test result
       debug:
          msg: "touch success"
        when: result is changed

ok: [servera] => {
    "msg": "touch success"
}

三.整体条件判断block

1.作用 解决when语句多个判断需要书写多个when的情况,使用block将多个任务组合起来,对这个整体进行when条件判断,条件成立了才会去执行块中的所有任务。在playbook中可以给block定义name,也可以直接使用when,但不能直接对其使用loop循环。这里主要介绍block常规用法,rescue错误处理用法和always固定执行用法

2.block用法示例

[root@main zuolaoshi]# cat block.yaml 
---

- hosts: servera
    tasks:
      - name: carry block
        block:
          - name: free 
            shell: "free -m"
          - name: echo 
            shell: "free -m > /a.txt"
            when: 1 < 2

[root@main zuolaoshi]# ansible servera -a 'cat /a.txt'
servera | CHANGED | rc=0 >>
              total        used        free      shared  buff/cache   available
Mem:           5848         306        5348          11         193        5313
Swap:          2047           0        2047

3.block错误处理时用法演示 没有/my目录,shell模块执行错误,执行rescue部分

注意:block模块中只要有一个任务执行失败都会跳转执行rescue部分

[root@main zuolaoshi]# cat rescue.yaml 
---

- hosts: servera
    tasks:
      - name: test rescue
        block:
          - shell: "ls /my"
            rescue:
          - debug: 
            msg: "no directory"

ok: [servera] => {
    "msg": "no directory"
}

4.block固定执行用法演示 不管bloack块执行成功还是失败,都执行alway部分

[root@main zuolaoshi]# cat always.yaml 
---

- hosts: servera
    tasks:
      - name: test rescue
        block:
          - shell: "ls /my"
            rescue:
          - debug: 
            msg: "no directory"
            always:
          - debug:
            msg: "there always"

ok: [servera] => {
    "msg": "no directory"
}

ok: [servera] => {
    "msg": "there always"
}