1. 程式人生 > 實用技巧 >Ansible——迴圈與條件判斷

Ansible——迴圈與條件判斷

目錄

Ansible迴圈(loop)

有時您想重複執行多次任務。在計算機程式設計中,這稱為迴圈。常見的Ansible迴圈包括使用檔案模組更改多個檔案和/或目錄的所有權,使用使用者模組建立多個使用者以及重複輪詢步驟直到達到特定結果。Ansible提供了兩個用於建立迴圈的關鍵字:loop和with_

注意:目前ansible2.5中,我們習慣於用loop替代with_*

迴圈方式

簡單遍歷

重複的任務可以作為標準迴圈寫在簡單的字串列表上。可以直接在任務中定義列表

被控機上有3個使用者。想利用迴圈刪除這 3個使用者

[root@localhost ~]# id test1
uid=1001(test1) gid=1001(test1) groups=1001(test1)
[root@localhost ~]# id test2
uid=1002(test2) gid=1002(test2) groups=1002(test2),10(wheel)
[root@localhost ~]# id test3
uid=1003(test3) gid=1003(test3) groups=1003(test3),0(root)



[root@localhost project]# vim ceshi2.yml 
---
- name: test
  hosts: 192.168.190.134
  tasks:
    - name: delete user
      user: 
        name: "{{ item }}"               呼叫迴圈變數。代表loop下面的迴圈體
        state: absent
      loop:
        - test1                          建立3個列表。用來代表迴圈體
        - test2
        - test3


changed: [192.168.190.134] => (item=test1)
changed: [192.168.190.134] => (item=test2)
changed: [192.168.190.134] => (item=test3)
......

同時也可以利用變數來作為迴圈體

[root@localhost project]# !vim
vim ceshi2.yml 
---
- name: test
  hosts: 192.168.190.134
  vars:
     test_name:        定義變數
       - test1
       - test2
       - test3
  tasks:
    - name: delete user
      user:
        name: "{{ item }}"
        state: present
      loop: "{{ test_name }}"    呼叫變數
      
      
changed: [192.168.190.134] => (item=test1)
changed: [192.168.190.134] => (item=test2)
changed: [192.168.190.134] => (item=test3) 

雜湊表遍歷

[root@localhost project]# !vim
vim ceshi2.yml 
---
- name: test
  hosts: 192.168.190.134
  tasks:
    - name: delete user
      user:
        name: "{{ item.name }}"        引用雜湊表中子項
        groups: "{{ item.groups }}"
        state: present
      loop:
        - name: test1
          groups: root
        - name: test2
          groups: test1  



changed: [192.168.190.134] => (item={'name': 'test1', 'groups': 'root'})
changed: [192.168.190.134] => (item={'name': 'test2', 'groups': 'test1'})

註冊變數與loop

---
- name: test
  hosts: 192.168.190.134
  gather_facts: no
  tasks:
    - name: delete user
      shell: echo '{{ item }}'
      loop:
        - one
        - two
      register: result
    - name: print
      debug:
        msg: "{{ result.results }}"
        
ansible_facts": {
                "discovered_interpreter_python": "/usr/libexec/platform-python"
            },
            "ansible_loop_var": "item",
            "changed": true,
            "cmd": "echo 'one'",
            "delta": "0:00:00.003743",
            "end": "2020-09-06 11:27:13.127451",
            "failed": false,
            "invocation": {
......        

Ansible條件判斷(when)

條件判斷:

when的值是一個條件表示式,如果條件判斷成立,這個task就執行,如果判斷不成立,則task不執行

常見判斷符號

符號 說明
== 比較兩個物件是否相等,相等為真
=! 比較兩個物件是否不等,不等為真
> 比較兩個值的大小,如果左邊的值大於右邊的值,則為真
< 比較兩個值的大小,如果左邊的值小於右邊的值,則為真
>= 比較兩個值的大小,如果左邊的值大於右邊的值或左右相等,則為真
<= 比較兩個值的大小,如果左邊的值小於右邊的值或左右相等,則為真
and 邏輯與,當左邊與右邊同時為真,則返回真
or 邏輯或,當左邊與右邊有任意一個為真,則返回真
not 取反
is defined 變數被定義且存在
is not defined 變數不存在

簡單判斷

例:

  • 被控機必須是RedHat系統
  • 被控及版本號必須為8.1
[root@localhost project]# vim ceshi1.yml 
---
- hosts: test_group
  tasks:
    - name: when
      shell: echo 'hellp world'
      when:
        - ansible_facts.distribution == 'RedHat'
        - ansible_facts.distribution_version  == '8.1'
      register: result
    - debug:
        var: result.stdout_lines


changed: [192.168.190.134]
changed: [192.168.190.133]

ok: [192.168.190.133] => {
    "result.stdout_lines": [
        "hellp world"             兩臺主機成功列印
    ]
}
ok: [192.168.190.134] => {
    "result.stdout_lines": [
        "hellp world"
    ]
}

組合判斷

when 後加>,可以多行編輯

---
- hosts: test_group
  tasks:
    - name: when
      shell: echo 'hellp world'
      when: >
        (ansible_facts.distribution == 'RedHat' and ansible_facts.distribution_version  == '8.1') 
        or 
        (ansible_facts.distribution == 'CentOS' and ansible_facts.distribution_version == '7.1')
      register: result
    - debug:
        var: result.stdout_lines

示例

刪除test1使用者,如果change值為true則證明成功執行,否則失敗。且需要列印資訊

注意:ignore_errors"表示即使當前task執行報錯,ansible也會忽略這個錯誤,繼續執行playbook

---
- name: 測試
  hosts: test_group
  tasks:
    - name: delete  user test1
      user:
        name: test1
        state: absent
      register: result
      ignore_errors: yes                執行錯誤,play繼續。
    - debug:
        msg: "命令執行成功"
      when:
        result.changed == True
    - debug:
        msg: "命令執行失敗"
      when:     
        result.changed != True


134主機上有test1,但是133主機上沒有test1,所以134執行成功,但是133執行失敗。
TASK [debug] *******************************************************************************************   
skipping: [192.168.190.133]
ok: [192.168.190.134] => {                                  
    "msg": "命令執行成功"
}

TASK [debug] *******************************************************************************************
ok: [192.168.190.133] => {
    "msg": "命令執行失敗"
}
skipping: [192.168.190.134]