一、Ad-Hoc問題
通過對AD-HOC的學習,我們發現AD-HOC每次只能在被管理節點上執行簡單的命令。
而日常的工作中,我們往往面臨的是一系列的復制的操作,例如我們有可能需要安裝軟件、更新配置、啟動服務等等一系列的操作的結合。此時再通過AD-HOC去完成任務就力不從心了。
在這種場景下,Ansible引入了playbook來幫我們解決這個問題。
二、playbook是什么?
PlayBook 也被大家翻譯成劇本。
可以認為它是Ansible自定義的一門語言(可以將playbook比作Linux中的shell,而Ansible中的Module可以比作Linux中的各種命令)。
三、YAML 學習
Playbook遵循YAML語法格式。
因此在學校Playbook前,我們必須弄清楚yaml的語法。
1.YAML特點
YAML 文件以 # 為注釋符
YAML 文件以 .yml 或者.yaml 結尾
YAML 文件以 --- 開始,以 ... 結束 但是開始和結束的標識都是可選的
2.基本語法
- 大小寫敏感
- 使用縮進表示層級關系
- 縮進時使用Tab鍵還是空格要一定要一致,建議使用空格
- 相同層次的元素必須左側對齊即可
YAML 支持的數據結構有三種
- 字符串
- 列表
- 字典
2.1 字符串
---
# YAML 中的字符串可以不使用引號,即使里面存在空格的時候,當然了使用單引號和雙引號也沒有錯
this is a string
'this is a string'
"this is a string"
# YAML 中如果一行寫不下你要表述的內容的時候,可以進行折行。寫法如下:
long_line: |
Example 1
Example 2
Example 3
# 或者
long_line: >
Example 1
Example 2
Example 3
2.2 列表
---
# 若熟悉python的話,可以認為它就是python中的list,若熟悉 C語言的話,可以認為它是 c中的數組
# 如何定義:以短橫線開頭 + 空格 + 具體的值
- red
- green
- blue
# 以上的值假如轉換成python中的list會是這樣:
# ['red','green','blue']
2.3 字典
---
# 若熟悉python的話,可以認為它就是python中的Dict
# 如何定義:key + 冒號(:) + 空格 + 值(value),即 key: value
name: Using Ansible
code: D1234
# 轉換為 python 的 Dict
# {'name': 'Using Ansible', 'code': 'D1234'}
2.4 混合結構
以上,針對 YAML 的所有基礎知識點就介紹完了,但日常生活中,往往需要的數據結構會特別復雜,有可能會是字符串、列表、字典組合形式。
例如:
所有人都上過學,都知道學校是以班級為單位。我們去使用列表和字典的形式去描述一個班的組成。
---
class:
- name: stu1
num: 001
- name: stu2
num: 002
- name: stu3
num: 003
# {'class': [{'name': 'stu1', 'num': 1 }, {'name': 'stu2', 'num':2}, ...]}
2.5 驗證 YAML 語法
# YAML 文件,通過 python 的 YAML 模塊驗證,若不正確則報錯,若正確則會輸出 YAML 里的內容。
# 注意使用時,一定確保安裝了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
練習
# 正確的情況
# cat myyaml.yml
---
- red
- green
- blue
...
[root@ansible-01 ~]# python -c 'import yaml,sys; print yaml.safe_load(sys.stdin)' < myyaml.yml
['red', 'green', 'blue']
# 錯誤的情況下
# cat myyaml.yml
---
- red
- green
-blue
[root@ansible-01 ~]# python -c 'import yaml,sys; print yaml.safe_load(sys.stdin)' < myyaml.yml
Traceback (most recent call last):
File "<string>", line 1, in <module>
File "/usr/lib64/python2.7/site-packages/yaml/__init__.py", line 93, in safe_load
return load(stream, SafeLoader)
File "/usr/lib64/python2.7/site-packages/yaml/__init__.py", line 71, in load
return loader.get_single_data()
File "/usr/lib64/python2.7/site-packages/yaml/constructor.py", line 37, in get_single_data
node = self.get_single_node()
File "/usr/lib64/python2.7/site-packages/yaml/composer.py", line 36, in get_single_node
...
四、playbook的編寫
1. play的定義
由於playbook是由一個或者多個play組成,那么如果我們熟悉play的寫法,就自然掌握了我們這章內容
那么如何定義play呢?
1、每個play都是以短橫杠開始的
2、每一個play都是一個YAML字典格式
根據上面兩條play的規則,一個假象的play應該是下面的樣子
---
- key1: value1
- key2: value2
- key3: value3
....
由於一個playbook是由一個或者多個play構成,那么一個含有多個play的playbook 結構上應該是如下的樣子
---
# 一個含有3個play的偽playbook構成
- key1: value1
key2: value2
key3: value3
- key4: value1
key5: value2
key6: value3
- key1: value1
key2: value2
key3: calue3
...
2. play的屬性
常用屬性
- name 屬性:每個play的名字
- hosts 屬性:每個play涉及的被管理服務器,同ad hoc 中的資產選擇器
- tasks 屬性:每個play中具體要完成的任務,以列表形式表達
- become 屬性:如果需要提權,則加上become屬性
- become_user 屬性:若提權的話,提到哪個用戶
- remote_user 屬性:指定連接到遠程節點的用戶,就是在遠程服務器上執行具體操作的用戶,若不指定,則默認使用當前執行ansible playbook的用戶
3. 一個完整劇本
下面來看一個含有play的playbook應該是下面這樣的
---
- name: the first play example
hosts: all
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/yes
state: started
4. tasks 屬性中任務的多種寫法
# 以啟動 nginx 服務,並加入開機自啟為例
# 一行的形式
service: name=nginx enabled=true statu=started
# 多行形式
service: name=nginx
enalbed=true
state=started
# 多行寫成字典的形式
service:
name: nginx
enabled: true
state: started
5. 具有多個play的playbook
---
- name: manage web servers
hosts: webservers
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=/tmp/nginx/nginx.conf
- name: start nginx server
service:
name: nginx
enabled: yes|true
state: started
- name: manager db servers
hosts: db_servers
tasks:
-name: update database confg
copy: src=my.conf dest=/etc/my.conf
...
6. 如何對playbook進行語法校驗
# ansible-playbook - hosts myplaybook.yml --syntax-check
因為Playbook屬於YAML格式,我們同樣可以檢查YAML語法格式的方法進行檢查playbook的語法的正確性
7. 如何允許playbook
# ansible-playbook -i hosts myyaml.yml
8. 如何單步跟從調試playbook
# 執行task中的任務,需要手動確認是否往下執行
ansible-playbook -i hosts my_nginx.yml --step
9. 如何測試允許playbook
# 執行完整的playbook,但是使用Task上的行為都不會在遠程服務器上執行,所有執行都是模擬行為
ansible-playbook -i hosts my_nginx.yml -C
-C 為大寫字母C