ansible循環


一、ansible迭代(循環)

loop循環語句

在寫 playbook 的時候發現了很多 task 都要重復引用某個相同的模塊,比如一次啟動10個服務,或者一次拷貝10個文件,如果按照傳統的寫法最少要寫10次,這樣會使得 playbook很臃腫。Ansible提供了兩個用於創建循環的關鍵字:loop和with_ (除了with_items,還有其他可用於循環的比如with_dict)

目前我們習慣於用loop替代with_*

格式:

  • 對迭代項的引用,固定變量名為"item"
  • 要在task中使用with_itemsloop關鍵字給定要迭代的元素列表;

實操:

1、使用循環批量安裝軟件

方式1

cat loop.yml
- hosts: web
  remote_user: root

  tasks:
    - name: Install Packages
      yum:
        name: "{{ item }}"
        state: present
      loop:
        - rsync
        - glances

有執行結果可知,glances安裝成功,rsync沒有改變是因為軟件已經安裝有了。

方式2:

cat loop1.yml
- hosts: web
  remote_user: root
  vars:
    packages:
      - httpd
      - glances

  tasks:
    - name: Install Packages
      yum:
        name: "{{ packages }}"
        state: present

方式采用變量方方式,顯示上不如loop直觀

方式3:loop調用vars的變量

---
- hosts: web
  vars:
     test_name:
       - test1
       - test2
       - test3
  tasks:
    - name: delete user
      user:
        name: "{{ item }}"
        state: present
      loop: "{{ test_name }}"

2、使用循環批量啟動服務

 cat loop_service.yml
- hosts: NginxWebs
  remote_user: root

  tasks:
    - name: Start Service
      service:
        name: "{{ item }}"
        state: started
      loop:
        - httpd
        - mariadb-server

3、使用循環批量創建用戶

注:此處將loop換成with_items也是一樣

- hosts: web
  tasks:
    - name: Create Groups
      group:
        name:  "{{ item }}"
        state: present
      loop:
          - group1
          - group2
          - group3
    - name: Create Users
      user:
        name:  "{{ item.user }}"
        group:  "{{ item.group }}"
        uid:  "{{ item.uid }}"
        state: present
        create_home: yes
      loop:
        - { user: user1,group: group1, uid: 2001 }
        - { user: user2,group: group2, uid: 2002 }
        - { user: user3,group: group3, uid: 2003 }

4、使用循環批量拷貝文件

- hosts: web
  tasks:
    - name: Copy Configuer File
      template:
        src: "{{ item.src }}"
        dest: "{{ item.dest }}"
        owner: "{{ item.owner }}"
        group: "{{ item.group }}"
        mode: "{{ item.mode }}"
      loop:
        - { src: "/root/conf/nginx.conf.j2", dest: "/etc/nginx/nginx.conf", owner: "root", group: "root", mode: "0644" }
        - { src: "/root/conf/example.com.conf.j2", dest: "/etc/nginx/conf.d/example.con.conf", owner: "root", group: "root", mode: "0644" }
        - { src: "/root/file/index.html", dest: "/data/nginx/example/index.html", owner: "nginx", group: "nginx", mode: 0644 }

注意:應用template時用法和copy一致,但是此處dest目標路徑需要自己提前創建好、屬主(組)都要有

copy是這樣介紹的:

= dest
        Remote absolute path where the file should be copied to.
        If `src' is a directory, this must be a directory too.   #如果 `src' 是一個目錄,dest也必須是一個目錄。 
        If `dest' is a non-existent path and if either `dest' ends with "/" or `src' is a directory, `dest' is created.  #如果 `dest' 是不存在的路徑,並且如果 `dest' 以“/”結尾或 `src' 是目錄,則創建 `dest'。
        If `dest' is a relative path, the starting directory is determined by the remote host.  #如果“dest”是相對路徑,則起始目錄由遠程主機確定。
        If `src' and `dest' are files, the parent directory of `dest' is not created and the task fails if it does not already exist. #如果 `src' 和 `dest' 是文件,則不創建 `dest' 的父目錄,如果不存在則任務失敗。

        type: path

5、嵌套循環with_nested、with_cartesian

cat loop6.yml
---
- hosts: web
  remote_user: root
  gather_facts: no
  tasks:
  - file:
      state: directory
      path: "/testdir/{{item.0}}/{{item.1}}"
    with_nested:
      - [ a, b, c ]
      - [ test1, test2 ]

效果

tree /testdir/
/testdir/
|-- a
|   |-- test1
|   `-- test2
|-- b
|   |-- test1
|   `-- test2
`-- c
    |-- test1
    `-- test2

9 directories, 0 files

分別給用戶授予3個數據庫的所有權限

- name: give users access to multiple databases
  mysql_user: name={{ item[0] }} priv={{ item[1] }}.*:ALL append_privs=yes password=foo
  with_nested:
    - [ 'alice', 'bob' ]
    - [ 'clientdb', 'employeedb', 'providerdb' ]

6、對哈希表循環(key:value)

---
- hosts: web
  vars:
    users:
      alice:
        name: Alice Appleworth
        telephone: 123-456-7890
      bob:
        name: Bob Bananarama
        telephone: 987-654-3210
  tasks:
    - name: Print phone records
      debug:
        msg: "User {{ item.key }} is {{ item.value.name }} {{ item.value.telephone }}"
      with_dict: "{{users}}"

7、對文件列表使用循環

cat loop7.yml
---
- hosts: web
  tasks:
    - copy:
        src: "{{ item }}"
        dest: /etc/fooapp/
        owner: root
        mode: 600
      with_fileglob:
        - /playbooks/files/fooapp/*

效果

8、對列表循環

如果列表數目不匹配,用None補全

---
- hosts: web
  tasks:
  - debug:
      msg: "{{ item.0 }} and {{ item.1 }}"
    with_together:
      - [ 'a', 'b', 'c' ]
      - [ 1, 2 ]

9、遍歷列表和索引:with_indexed_items

---
- hosts: web
  tasks:
  - name: indexed loop demo
    debug: "msg='at array position {{ item.0 }} there is a value {{ item.1 }}'"
    with_indexed_items: [1,2,3]

10、重試循環

---
- hosts: web
  tasks:
    - action: shell /usr/bin/foo
      register: result
      until: result.stdout.find("all systems go") != -1
      retries: 5
      delay: 10

"重試次數retries" 的默認值為3,"delay"為5

二、循環與when

如果將when與循環一起使用時,ansible會為每個循環項都執行單獨的條件判斷,不滿足條件的項就會跳過。

1、打印大於5的數字

cat loop8.yml
---
- hosts: web
  debugger: on_failed
  tasks:
     - name: print items greater than 5
       debug:
         msg: var is {{ item }}
       loop: [0,1,3,5,6,7,8,10]
       when: item > 7

效果:大於7的數字被執行

2、指定默認值default,當該集合未定義時,可以按條件跳過

---
- hosts: web
  debugger: on_failed
  tasks:
  - name: print items greater than 5
    debug:
      msg: "mylist is {{item}}"
    loop: "{{ mylist|default([4,5,6]) }}"
    when: item > 5

3、與字典循環

---
- hosts: web
  debugger: on_failed
  vars:
     mydict:  {"zhangsan":18,"lisi":19,"wangwu":20}
  tasks:
    - name: print items greater than 5
      debug:
        msg:  "item is {{item.key}}"
      loop:  "{{ query('dict', mydict|default({})) }}"
      when: item.value > 19

效果大於19歲的只有wangwu

三、注冊變量與loop

---
- hosts: web
  gather_facts: no
  tasks:
    - name: delete user
      shell: echo '{{ item }}'
      loop:
        - test1
        - test2
      register: result
    - name: print
      debug:
        msg: "{{ result.results }}"

  

 

 

 

 

 

 

 Ansible 小手冊系列 十四(條件判斷和循環) - 簡書 (jianshu.com)

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM