Ansible 小手冊系列 十四(條件判斷和循環)

條件判斷


When 語句

在when 後面使用Jinja2 表達式,結果爲True則執行任務。javascript

tasks:
  - name: "shut down Debian flavored systems" command: /sbin/shutdown -t now when: ansible_os_family == "Debian" 

若操做系統是Debian 時就執行關機操做php

能夠對條件進行分組在比較。java

tasks:
  - name: "shut down CentOS 6 and Debian 7 systems" command: /sbin/shutdown -t now when: (ansible_distribution == "CentOS" and ansible_distribution_major_version == "6") or (ansible_distribution == "Debian" and ansible_distribution_major_version == "7") 

能夠使用列表形式來表示條件爲and的關係python

tasks:
  - name: "shut down CentOS 6 systems" command: /sbin/shutdown -t now when: - ansible_distribution == "CentOS" - ansible_distribution_major_version == "6" 

使用jinja2過濾器mysql

tasks:
  - command: /bin/false register: result ignore_errors: True - command: /bin/something when: result|failed - command: /bin/something_else when: result|succeeded - command: /bin/still/something_else when: result|skipped 

忽略一個語句的錯誤,而後決定基於成功或失敗有條件地作一些事情。web

字符串轉換爲數字型再去比較sql

tasks:
  - shell: echo "only on Red Hat 6, derivatives, and later" when: ansible_os_family == "RedHat" and ansible_lsb.major_release|int >= 6 

使用變量進行判斷shell

vars:
  epic: true tasks: - shell: echo "This certainly is epic!" when: epic tasks: - shell: echo "This certainly isn't epic!" when: not epic 

判斷變量是否認義數據庫

tasks:
    - shell: echo "I've got '{{ foo }}' and am not afraid to use it!" when: foo is defined - fail: msg="Bailing out. this play requires 'bar'" when: bar is undefined 

與循環一塊兒使用ruby

tasks:
    - command: echo {{ item }} with_items: [ 0, 2, 4, 6, 8, 10 ] when: item > 5 

依次遍歷列表,當列表裏得數字大於5時執行任務

- command: echo {{ item }} with_items: "{{ mylist|default([]) }}" when: item > 5 - command: echo {{ item.key }} with_dict: "{{ mydict|default({}) }}" when: item.value > 5 

當變量不存在時,直接跳過

使用自定義的facts值作判斷

tasks:
    - name: gather site specific fact data
      action: site_facts
    - command: /usr/bin/thingy when: my_custom_fact_just_retrieved_from_the_remote_system == '1234' 

角色包含使用when

- include: tasks/sometasks.yml when: "'reticulating splines' in output" - hosts: webservers roles: - { role: debian_stock_config, when: ansible_os_family == 'Debian' } 

基於變量選擇文件和模板

- name: template a file template: src={{ item }} dest=/etc/myapp/foo.conf with_first_found: - files: - {{ ansible_distribution }}.conf - default.conf paths: - search_location_one/somedir/ - /opt/other_location/somedir/ 

使用註冊變量判斷

- name: test play hosts: all tasks: - shell: cat /etc/motd register: motd_contents - shell: echo "motd contains the word hi" when: motd_contents.stdout.find('hi') != -1 

failed_when

知足條件時,使任務失敗

tasks:
    - command: echo faild. register: command_result failed_when: "'faild' in command_result.stdout" - debug: msg="echo test" 

還能夠寫成這樣

tasks:
    - command: echo faild. register: command_result ignore_errors: True - name: fail the echo fail: msg="the command failed" when: "'faild' in command_result.stdout" - debug: msg="echo test" 

changed_when

更改任務的狀態。

- name: Install dependencies via Composer.
  command: "/usr/local/bin/composer global require phpunit/phpunit --prefer-dist" register: composer changed_when: "'Nothing to install or update' not in composer.stdout" 

當使用PHP Composer做爲安裝項目依賴項的命令時,知道何時是有用的Composer安裝了一些東西,或什麼都沒有改變。

循環


標準循環
添加多個用戶

- name: add several users
  user: name={{ item }} state=present groups=wheel
  with_items:
     - testuser1
     - testuser2

添加多個用戶,並將用戶加入不一樣的組內。

- name: add several users
  user: name={{ item.name }} state=present groups={{ item.groups }}
  with_items:
    - { name: 'testuser1', groups: 'wheel' } - { name: 'testuser2', groups: 'root' } 

嵌套循環

分別給用戶授予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' ] 

遍歷字典

輸出用戶的姓名和電話

tasks:
  - name: Print phone records debug: msg="User {{ item.key }} is {{ item.value.name }} ({{ item.value.telephone }})" with_dict: {'alice':{'name':'Alice Appleworth', 'telephone':'123-456-789'},'bob':{'name':'Bob Bananarama', 'telephone':'987-654-3210'} } 

並行遍歷列表

tasks:
  - debug: "msg={{ item.0 }} and {{ item.1 }}" with_together: - [ 'a', 'b', 'c', 'd','e' ] - [ 1, 2, 3, 4 ] 

若是列表數目不匹配,用None補全

遍歷列表和索引

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

item.0 爲索引,item.1爲值

遍歷文件列表的內容

---
- hosts: all
  tasks:
       - debug: "msg={{ item }}" with_file: - first_example_file - second_example_file 

遍歷目錄文件
with_fileglob匹配單個目錄中的全部文件,非遞歸匹配模式。

---
- hosts: all
  tasks:
    - file: dest=/etc/fooapp state=directory - copy: src={{ item }} dest=/etc/fooapp/ owner=root mode=600 with_fileglob: - /playbooks/files/fooapp/* 

當在role中使用with_fileglob的相對路徑時,Ansible解析相對於roles/<rolename>/files目錄的路徑。

遍歷ini文件

lookup.ini
[section1]
value1=section1/value1
value2=section1/value2

[section2]
value1=section2/value1
value2=section2/value2
- debug: msg="{{ item }}" with_ini: value[1-2] section=section1 file=lookup.ini re=true 

獲取section1 裏的value1和value2的值

重試循環 until

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

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

查找第一個匹配文件

tasks:
  - debug: "msg={{ item }}" with_first_found: - "/tmp/a" - "/tmp/b" - "/tmp/default.conf" 

依次尋找列表中的文件,找到就返回。若是列表中的文件都找不到,任務會報錯。

隨機選擇with_random_choice

隨機選擇列表中得一個值

- debug: msg={{ item }}
  with_random_choice:
     - "go through the door" - "drink from the goblet" - "press the red button" - "do nothing" 

循環程序的結果

tasks:
  - debug: "msg={{ item }}" with_lines: ps aux 

循環子元素

定義好變量

#varfile --- users: - name: alice authorized: - /tmp/alice/onekey.pub - /tmp/alice/twokey.pub mysql: password: mysql-password hosts: - "%" - "127.0.0.1" - "::1" - "localhost" privs: - "*.*:SELECT" - "DB1.*:ALL" - name: bob authorized: - /tmp/bob/id_rsa.pub mysql: password: other-mysql-password hosts: - "db1" privs: - "*.*:SELECT" - "DB2.*:ALL" 
---
- hosts: web
  vars_files: varfile
  tasks:

  - user: name={{ item.name }} state=present generate_ssh_key=yes
    with_items: "{{ users }}" - authorized_key: "user={{ item.0.name }} key='{{ lookup('file', item.1) }}'" with_subelements: - "{{ users }}" - authorized - name: Setup MySQL users mysql_user: name={{ item.0.name }} password={{ item.0.mysql.password }} host={{ item.1 }} priv={{ item.0.mysql.privs | join('/') }} with_subelements: - "{{ users }}" - mysql.hosts 

{{ lookup('file', item.1) }} 是查看item.1文件的內容
with_subelements 遍歷哈希列表,而後遍歷列表中的給定(嵌套)的鍵。

在序列中循環with_sequence

with_sequence以遞增的數字順序生成項序列。 您能夠指定開始,結束和可選步驟值。
參數應在key = value對中指定。 'format'是一個printf風格字符串。

數字值能夠以十進制,十六進制(0x3f8)或八進制(0600)指定。 不支持負數。

---
- hosts: all

  tasks:

    # 建立組 - group: name=evens state=present - group: name=odds state=present # 建立格式爲testuser%02x 的0-32 序列的用戶 - user: name={{ item }} state=present groups=evens with_sequence: start=0 end=32 format=testuser%02x # 建立4-16之間得偶數命名的文件 - file: dest=/var/stuff/{{ item }} state=directory with_sequence: start=4 end=16 stride=2 # 簡單實用序列的方法:建立4 個用戶組分表是組group1 group2 group3 group4 - group: name=group{{ item }} state=present with_sequence: count=4 

隨機選擇with_random_choice
隨機選擇列表中得一個值

- debug: msg={{ item }}
  with_random_choice:
     - "go through the door" - "drink from the goblet" - "press the red button" - "do nothing" 

合併列表

# 安裝全部列表中的軟件 - name: flattened loop demo yum: name={{ item }} state=installed with_flattened: - [ 'foo-package', 'bar-package' ] - [ ['one-package', 'two-package' ]] - [ ['red-package'], ['blue-package']] 

註冊變量使用循環

- shell: echo "{{ item }}" with_items: - one - two register: echo - name: Fail if return code is not 0 fail: msg: "The command ({{ item.cmd }}) did not have a 0 return code" when: item.rc != 0 with_items: "{{ echo.results }}" 

循環主機清單

# 輸出全部主機清單裏的主機 - debug: msg={{ item }} with_items: "{{ groups['all'] }}" # 輸出全部執行的主機 - debug: msg={{ item }} with_items: play_hosts #輸出全部主機清單裏的主機 - debug: msg={{ item }} with_inventory_hostnames: all # 輸出主機清單中不在www中的全部主機 - debug: msg={{ item }} with_inventory_hostnames: all:!www 

改變循環的變量項

# main.yml - include: inner.yml with_items: - 1 - 2 - 3 loop_control: loop_var: outer_item # inner.yml - debug: msg="outer item={{ outer_item }} inner item={{ item }}" with_items: - a - b - c
相關文章
相關標籤/搜索