通過(guò)對(duì) AD-HOC 的學(xué)習(xí)糟港,我們發(fā)現(xiàn) AD-HOC 每次只能在被管理節(jié)點(diǎn)上執(zhí)行簡(jiǎn)單的命令攀操。而日常工作中,我們往往面臨的是一系列的復(fù)雜操作秸抚,例如我們有可能需要安裝軟件速和、更新配置、啟動(dòng)服務(wù)等等一系列操作的結(jié)合剥汤。此時(shí)再通過(guò) AD-HOC 去完成任務(wù)就有些力不從心了颠放。在這種場(chǎng)景下,Ansible引進(jìn)了 PLAYBOOK 來(lái)幫忙我們解決這樣復(fù)雜問(wèn)題吭敢。
1. PlayBook是什么
Playbook 也通常被大家翻譯成劇本碰凶。可以認(rèn)為它是Ansible 自定義的一門(mén)語(yǔ)言(可以將 Playbook 比作 Linux 中的
shell鹿驼,而 Ansible 中的 Module 可以比作為 Linux 中的各種命令欲低。通過(guò)這樣的類(lèi)比,我們對(duì)PlayBook就有了一
個(gè)更形象的認(rèn)識(shí)了)畜晰。既然 Playbook 是一門(mén)語(yǔ)言砾莱,那么它遵循什么樣的語(yǔ)法格式? 有哪些語(yǔ)言呢性? 我們將通過(guò)下面
的學(xué)習(xí)逐步了解。
2. YAML 學(xué)習(xí)
PlayBook遵循YAML 的語(yǔ)法格式凄鼻。 因此在學(xué)習(xí)PlayBook之前腊瑟,我們必須要先弄明白YAML 相關(guān)知識(shí)點(diǎn)面哼。
YAML特點(diǎn)
- YAML 文件以 # 為注釋符
- YAML 文件以 .yml 或者.yaml 結(jié)尾
- YAML 文件以 --- 開(kāi)始 , 以 ... 結(jié)束, 但開(kāi)始和結(jié)束標(biāo)志都是可選的
基本語(yǔ)法
大小寫(xiě)敏感
使用縮進(jìn)表示層級(jí)關(guān)系
縮進(jìn)時(shí)是使用Tab鍵還是使用空格一定要達(dá)到統(tǒng)一,建議使用空格扫步。
相同層級(jí)的元素必須左側(cè)對(duì)齊即可
YAML 支持的數(shù)據(jù)結(jié)構(gòu)有三種: 字符串、列表匈子、字典河胎。
字符串
---
# YAML 中的字符串可以不使用引號(hào),即使里面存在空格的時(shí)候虎敦,當(dāng)然了使用單引號(hào)和雙引號(hào)也沒(méi)有錯(cuò)游岳。
this is a string
'this is a string'
"this is a string"
# YAML 中若一行寫(xiě)不下你要表述的內(nèi)容,可以進(jìn)行折行其徙。寫(xiě)法如下:
long_line: |
Example 1
Example 2
Example 3
# 或者
long_line: >
Example 1
Example 2
Example 3
...
列表
---
# 若熟悉 Python 的話(huà)胚迫, 可以認(rèn)為它就是Python中的List ,若熟悉 C 語(yǔ)言的話(huà), 可以認(rèn)為它是 C 中的數(shù)組唾那。
# 如何定義: 以短橫線(xiàn)開(kāi)頭 + 空格 + 具體的值
- red
- green
- blue
# 以上的值假如轉(zhuǎn)換成 python 的 List 會(huì)是這樣:
# ['red', 'green', 'blue']
...
字典
---
# 若熟悉Python 的話(huà)访锻, 可以認(rèn)為它就是Python中的 Dict
# 如何定義: key + 冒號(hào)(:) + 空格 + 值(value), 即 key: value
name: Using Ansible
code: D1234
# 轉(zhuǎn)換為 python 的 Dict
# {'name': 'Using Ansibel', 'code': 'D1234'}
...
混合結(jié)構(gòu)
以上,針對(duì)YAML 的所有基礎(chǔ)知識(shí)點(diǎn)就介紹完了。但是在生產(chǎn)中闹获,往往需要的數(shù)據(jù)結(jié)構(gòu)會(huì)特別復(fù)雜期犬,有可能會(huì)是字符串、列表避诽、字典的組合形式龟虎。 這里舉一個(gè)小例子:
所有人都上過(guò)學(xué),都知道到學(xué)校里是以班級(jí)為單位沙庐。我們?nèi)ナ褂昧斜砗妥值涞男问饺ッ枋鲆粋€(gè)班級(jí)的組成鲤妥。
---
class:
- name: stu1
num: 001
- name: stu2
num: 002
- name: stu3
num: 003
# {'class': [{'name': 'stu1', 'num': 1},{'name': 'stu2', 'num': 2},...]}
...
驗(yàn)證YAML 語(yǔ)法
// 將YAML文件,通過(guò)Python 的YAML 模塊驗(yàn)證拱雏, 若不正確則報(bào)錯(cuò)棉安。若正確則會(huì)輸出YAML 里的內(nèi)容。
// 注意使用時(shí)古涧,一定確保安裝了yaml 軟件包垂券。
python -c 'import yaml,sys; print yaml.load(sys.stdin)' < myyaml.yml
python3 -c 'import yaml,sys; print(yaml.load(sys.stdin))' < myyaml.yml
一般不使用這種方法驗(yàn)證,在下面會(huì)介紹使用yml自帶參數(shù)驗(yàn)證的方法
示例:
// 正確的情況
# cat myyaml.yml
---
- red
- green
- blue
...
# python -c 'import yaml,sys; print yaml.load(sys.stdin)' < myyaml.yml
['red', 'green', 'blue']
// 錯(cuò)誤的情況羡滑, 將YAML文件寫(xiě)錯(cuò)
# cat myyaml.yml
---
- red
- green
-blue
...
# python -c 'import yaml,sys; print yaml.load(sys.stdin)' < myyaml.yml
Traceback (most recent call last):
File "<string>", line 1, in <module>
File "/usr/local/lib/python2.7/site-packages/yaml/__init__.py", line 71, in load
return loader.get_single_data()
File "/usr/local/lib/python2.7/site-packages/yaml/constructor.py", line 37, in get_single_data
node = self.get_single_node()
...
...
3. Play 定義
Playbook 是由一個(gè)或者多個(gè)Play組成,那么如果我們熟悉Play 的寫(xiě)法菇爪,就自然掌握了PlayBook。
那如何定義一個(gè)Play呢
1柒昏、每一個(gè)Play 都是以短橫杠開(kāi)始的
2凳宙、每一個(gè)Play 都是一個(gè)YAML 字典格式
根據(jù)上面兩條Play 的規(guī)則,一個(gè)假想的 Play 應(yīng)該是如下的樣子
---
- key1: value1
key2: value2
key3: value3
...
由于一個(gè)Playbook 是由一個(gè)或者多個(gè)Play構(gòu)成职祷, 那么一個(gè)含有多個(gè)Play的Playbook 結(jié)構(gòu)上應(yīng)該是如下的樣子
---
# 一個(gè)含有3個(gè)Play 的偽PlayBook構(gòu)成
- key1: value1
key2: value2
key3: value3
- key4: value1
key5: value2
key6: value3
- key1: value1
key2: value2
key3: value3
...
4. Play 屬性
Play中的每一個(gè)key, key1氏涩、key2届囚、key3等;這些key在PlayBook中被定義為Play的屬性是尖。這些屬性都具有特殊的意義,我們不能隨意的自定義Play 的屬性意系。
常用屬性
(1)、name 屬性饺汹, 每個(gè)play的名字
(2)蛔添、hosts 屬性, 每個(gè)play 涉及的被管理服務(wù)器,同ad hoc 中的patten
(3)兜辞、tasks 屬性, 每個(gè)play 中具體要完成的任務(wù)迎瞧,以列表的形式表達(dá)
(4)、become 屬性逸吵,如果需要提權(quán)凶硅,則加上become 相關(guān)屬性
(5)、become_user 屬性, 若提權(quán)的話(huà)扫皱,提權(quán)到哪個(gè)用戶(hù)上
(6)足绅、remote_user屬性,指定連接用戶(hù)韩脑。若不指定编检,則默認(rèn)使用當(dāng)前執(zhí)行 ansible Playbook 的用戶(hù)
5. 一個(gè)完整劇本
根據(jù)上面介紹的真實(shí)的屬性,一個(gè)含有一個(gè)Play 的 Playbook 應(yīng)該是如下的樣子
---
- name: the first play example
hosts: all
remote_user: root
tasks:
- name: install nginx package //:后面自定義扰才,name是屬性
yum: name=nginx state=present // yum是模塊允懂,后面是動(dòng)作
- name: copy nginx.conf to remote server
copy: src=nginx.conf dest=/etc/nginx/nginx.conf
- name: start nginx server
service:
name: nginx
enabled: true
state: started
tasks 屬性中任務(wù)的多種寫(xiě)法
# 以啟動(dòng) nginx 服務(wù),并增加開(kāi)機(jī)啟動(dòng)為例
# 一行的形式:
service: name=nginx enabled=true state=started
# 多行的形式:
service: name=nginx
enabled=true
state=started
# 多行寫(xiě)成字典的形式:
service:
name: nginx //一定要記得縮進(jìn)衩匣,這是語(yǔ)法
enabled: true
state: started
具有多個(gè)Play 的Playbook
---
- name: manage web servers
hosts: web_servers
remote_user: root
tasks:
- name: install nginx package
yum: name=nginx state=present
- name: copy nginx.conf to remote server
copy: src=nginx.conf dest=/etc/nginx/nginx.conf
- name: start nginx server
service:
name: nginx
enabled: true
state: started
- name: manager db servers
hosts: db_servers
tasks:
- name: update database confg
copy: src=my.cnf dest=/etc/my.cnf
對(duì)Playbook 進(jìn)行語(yǔ)法校驗(yàn)
// 因?yàn)镻layBook 屬于YAML 格式蕾总, 我們同樣可以使用檢查YAML的語(yǔ)法格式的方法進(jìn)行檢查PlayBook的語(yǔ)法正確性。
// 此形式的校驗(yàn)琅捏,只能校驗(yàn)PlayBook是否正確生百,而不能校驗(yàn)YAML文件是否語(yǔ)法正確。
語(yǔ)法:ansible-playbook 文件名.yml --syntax-check
# ansible-playbook myplaybook.yml --syntax-check
運(yùn)行PlayBook
# ansible-playbook myplaybook.yml
單步跟從調(diào)試PlayBook
// 執(zhí)行Task中的任務(wù)柄延,需要手動(dòng)確認(rèn)是否往下執(zhí)行蚀浆。
# ansible-playbook myplaybook.yml --step
測(cè)試運(yùn)行PlayBook
// 會(huì)執(zhí)行完整個(gè)PlayBook ,但是所有Task中的行為都不會(huì)在遠(yuǎn)程服務(wù)器上執(zhí)行,所有執(zhí)行都是模擬行為搜吧。
# ansible-playbook myplaybook.yml -C
// -C 為大寫(xiě)的字母 C