Ansible系列文章:http://www.cnblogs.com/f-ck-need-u/p/7576137.htmlhtml
ansible中的循環都是藉助迭代來實現的。基本都是以"with_"開頭。如下是常見的幾種循環。shell
ansibel支持迭代功能。例如,有一大堆要輸出的命令、一大堆要安裝的軟件包、一大堆要copy的文件等等。centos
例如,要安裝一堆軟件包。數組
---
- hosts: localhost
tasks:
- yum: name="{{item}}" state=installed
with_items:
- pkg1
- pkg2
- pkg3
它會一個一個迭代到特殊變量"{{item}}"處。oop
再例如,指定一堆文件列表,而後使用grep搜索出給定文件列表中包含"www.example.com"字符串的文件:測試
---
- hosts: localhost
tasks:
- shell: grep -Rl "www\.example\.com" "{{item}}"
with_items:
- file1
- file2
- file3
register: match_file
- debug: msg="{% for i in match_file.results %} {{i.stdout}} {% endfor %}"
注意,將with_items迭代後的結果註冊爲變量時,其註冊結果也是列表式的,且其key爲"results"。具體的結果比較長,可使用debug模塊的var或msg參數觀察match_file變量的結果。ui
在上面,是使用for循環進行引用的。若是不使用for循環,那麼就須要使用數組格式。例如,引用match_file中的第一和第二個結果。this
- debug: var=match_file.results[0].stdout
- debug: var=match_file.results[1].stdout
顯然,不如循環引用更好,由於不知道match_file中到底有幾個匹配文件,也就不能肯定match_file中的列表數量。url
每一個列表項中可能都包含一個或多個字典,既然with_items迭代的是列表項,那麼確定也能迭代列表中的各字典。spa
例如:
tasks:
- command: echo {{ item }}
with_items: [ 0, 2, 4, 6, 8, 10 ]
register: num
- debug: msg="{% for i in num.results %} {{i.stdout}} {% endfor %}"
再例如:
---
- hosts: localhost
tasks:
- shell: echo "name={{item.name}},age={{item.age}}"
with_items:
- {name: zhangsan,age: 32}
- {name: lisi,age: 33}
- {name: wangwu,age: 35}
register: who
- debug: msg="{% for i in who.results %} {{i.stdout}} {% endfor %}"
使用"with_dict"能夠迭代字典項。迭代時,使用"item.key"表示字典的key,"item.value"表示字典的值。
例如:
---
- hosts: localhost tasks: - debug: msg="{{item.key}} & {{item.value}}" with_dict: { address: 1,netmask: 2,gateway: 3 }
另外一種狀況,字典是已存儲好的。例如ansible facts中的ansible_eth0.ipv4,其內容以下:
"ipv4": {
"address": "192.168.100.65",
"netmask": "255.255.255.0",
"gateway": "192.168.100.2"
}
這種狀況下,with_dict處能夠直接指定該字典的key。即:
---
- hosts: localhost tasks: - debug: msg="{{item.key}} & {{item.value}}" with_dict: ansible_eth0.ipv4
再例如,直接引用playbook中定義的vars。
---
- hosts: 192.168.100.65
gather_facts: False
vars:
user:
longshuai_key:
name: longshuai
gender: Male
xiaofang_key:
name: xiaofang
gender: Female
tasks:
- name: print hash loop var
debug: msg="{{ item.key }} & {{ item.value.name }} & {{ item.value.gender }}"
with_dict: "{{ user }}"
例如,拷貝一堆用通配符匹配出來的文件到各遠程主機上。
---
- hosts: centos
tasks:
- copy: src="{{item}}" dest=/tmp/
with_fileglob:
- /tmp/*.sh
- /tmp/*.py
注意,通配符沒法匹配"/",所以沒法遞歸到子目錄中,也就沒法迭代子目錄中的文件。
with_lines很好用,能夠將命令行的輸出結果按行迭代。
例如,find一堆文件出來,copy走。
---
- hosts: localhost
tasks:
- copy: src="{{item}}" dest=/tmp/yaml
with_lines:
- find /tmp -type f -name "*.yml"
嵌套迭代是指屢次迭代列表項。例如:
---
- hosts: localhost tasks: - debug: msg="{{item[0]}} & {{item[1]}}" with_nested: - [a,b] - [1,2,3]
結果將獲得"a & 1"、"a & 2"、"a & 3"、"b & 1"、"b & 2"和"b & 3"共6個結果。
在ansible中,只有when能夠實現條件判斷。
tasks:
- name: config the yum repo for centos 6
yum_repository:
name: epel
description: epel
baseurl: http://mirrors.aliyun.com/epel/6/$basearch/
gpgcheck: no
when: ansible_distribution_major_version == "6"
注意兩點:
此外,還支持各類邏輯組合。
tasks:
# 邏輯或
- command: /sbin/shutdown -h now
when: (ansible_distribution == "CentOS" and ansible_distribution_major_version == "6") or
(ansible_distribution == "Debian" and ansible_distribution_major_version == "7")
# 邏輯與
- command: /sbin/shutdown -t now
when:
- ansible_distribution == "CentOS"
- ansible_distribution_major_version == "6"
# 取反
- command: /sbin/shutdown -t now
when: not ansible_distribution == "CentOS"
還能夠直接直接引用布爾值的變量。
---
- hosts: localhost
vars:
epic: False
tasks:
- debug: msg="This certainly is epic!"
when: not epic
此外,可使用jinja2的defined來測試變量是否已定義,使用undefined能夠取反表示未定義。例如:
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