1. 程式人生 > 其它 >Ansible之playbook劇本

Ansible之playbook劇本

Ansible之playbook劇本

1. playbook的組成

playbooks 本身由以下各部分組成
(1)Tasks:任務,即通過 task 呼叫 ansible 的模板將多個操作組織在一個 playbook 中執行
(2)Variables:變數
(3)Templates:模板
(4)Handlers:處理器,當changed狀態條件滿足時,(notify)觸發執行的操作
(5)Roles:角色

2. 劇本示例test1

2.1 劇本製作

[root@ansible ~] vim test1.yml

---

yaml檔案以---開頭,以表明這是一個yaml檔案,可省略

- name: first test

定義一個play的名稱,可省略

gather_facts: false

設定不進行facts資訊收集,這可以加快執行速度,可省略

hosts: webservers

指定要執行任務的被管理主機組,如多個主機組用冒號分隔

remote_user: root

指定被管理主機上執行任務的使用者

tasks:

定義任務列表,任務列表中的各任務按次序逐個在hosts中指定的主機上執行

- name: test connection

自定義任務名稱

ping:

使用 module: [options] 格式來定義一個任務

- name: disable selinux

command: '/sbin/setenforce 0'

command模組和shell模組無需使用key=value格式

ignore_errors: True

如執行命令的返回值不為0,就會報錯,tasks停止,可使用ignore_errors忽略失敗的任務

- name: disable firewalld

service: name=firewalld state=stopped

使用 module: options 格式來定義任務,option使用key=value格式

- name: install httpd

yum: name=httpd state=latest

- name: install configuration file for httpd

copy: src=/etc/ansible/httpd.conf dest=/etc/httpd/conf/httpd.conf

這裡需要一個事先準備好的/opt/httpd.conf檔案

notify: "restart httpd"

如以上操作後為changed的狀態時,會通過notify指定的名稱觸發對應名稱的handlers操作

- name: start httpd service

service: enabled=true name=httpd state=started

handlers:

handlers中定義的就是任務,此處handlers中的任務使用的是service模組

- name: restart httpd

notify和handlers中任務的名稱必須一致

service: name=httpd state=restarted

Ansible在執行完某個任務之後並不會立即去執行對應的handler,而是在當前play中所有普通任務都執行完後再去執行handler,這樣的好處是可以多次觸發notify,但最後只執行一次對應的handler,從而避免多次重啟。

2.2 準備http.conf

[root@ansible ansible] vim /etc/ansible/httpd.conf

42行,指定埠

Listen 8080

95行,指定域名

ServerName node1:8080

2.3 執行劇本

ansible-playbook test1.yml

2.4 檢視web伺服器

ansible web -m shell -a 'netstat -natp | grep httpd'

2.5 補充引數

-k(–ask-pass):用來互動輸入ssh密碼

-K(-ask-become-pass):用來互動輸入sudo密碼

-u:指定使用者

ansible-playbook test1.yml --syntax-check

檢查yml檔案的語法是否正確

ansible-playbook test1.yml --list-task

檢查tasks任務

ansible-playbook test1.yml --list-hosts

檢查生效的主機

ansible-playbook test1.yml --start-at-task='install httpd'

指定從某個task開始執行

3. 劇本示例test2--定義、引用變數

3.1 劇本製作

---

- name: second test

hosts: db

remote_user: root

vars:

定義變數

- groupname: mysql

格式為 key: value

- username: nginx

tasks:

- name: create group

group: name={{groupname}} system=yes gid=306

使用 {{key}} 引用變數的值

- name: create user

user: name={{username}} uid=306 group={{groupname}}

- name: copy file

copy: content="{{ansible_default_ipv4}}" dest=/opt/vars.txt

在setup模組中可以獲取facts變數資訊

3.3 檢視db伺服器

ansible db -a 'grep "mysql" /etc/group'

ansible db -a 'grep "nginx" /etc/passwd'

ansible db -a 'cat /opt/vars.txt'

3.4 修改劇本中的變數設定

刪除dbservers中的mysql組和nginx使用者以及/opt/var.txt

ansible db -a 'userdel -r nginx'

ansible db -a 'groupdel mysql'

ansible db -a 'rm -rf /opt/vars.txt'

確認使用者、組以及檔案已刪除

ansible db -a 'grep "mysql" /etc/group'

ansible db -a 'grep "nginx" /etc/passwd'

ansible db -a 'cat /opt/vars.txt'

刪除/註釋"- username: nginx"變數

3.5 在命令列定義變數執行劇本

ansible-playbook test2.yml -e "username=nginx"

3.6 檢視dbservers伺服器

ansible db -a 'grep "mysql" /etc/group'

ansible db -a 'grep "nginx" /etc/passwd'

ansible db -a 'cat /opt/vars.txt'

4. 劇本示例test3--指定遠端主機sudo切換使用者

vim test3.yml

---

- hosts: db

remote_user: wang

become: yes

2.6版本以後的引數,之前是sudo,意思為切換使用者執行

become_user: root

……

指定sudo使用者為root

測試機需要有wang,修改/etc/sudoers檔案

執行playbook時:ansible-playbook test3.yml -K <密碼>

ansible-playbook test3.yml -K

a

驗證

5. 劇本示例test4--when條件判斷

在Ansible中,提供的唯一一個通用的條件判斷是when指令,當when指令的值為true時,則該任務執行,否則不執行該任務。

when一個比較常見的應用場景是實現跳過某個主機不執行任務或者只有滿足條件的主機執行任務

vim test4.yaml

---

- hosts: all

remote_user: root

tasks:

- name: shutdown host

command: /sbin/shutdown -r now

when: ansible_default_ipv4.address == "192.168.10.3"

when指令中的變數名不需要手動加上{{}}

或者使用

when: inventory_hostname == "<主機名>"

ansible-playbook test4.yml

執行後,僅有指定主機重啟,執行ping模組檢視

ansible all -m ping

重啟完畢後,可以ping通

6. 劇本示例test5--迭代

Ansible提供了很多種迴圈結構,一般都命名為with_items,作用等同於loop迴圈。

vim test5.yaml

---

- name: test5

hosts: all

gather_facts: false

tasks:

- name: create directories

file:

path: "{{item}}"

state: directory

with_items:

等同於 loop:

- /test/test1

- /test/test2

- name: add groups

group: name={{item.name}} state=present

with_items:

- name: test1

- name: test2

- name: add users

user: name={{item.name}} state=present groups={{item.groups}}

with_items:

- name: test1

groups: test

- name: test2

groups: root

或使用以下格式

with_items:

- {name:'test1', groups:'test'}

- {name:'test2', groups:'root'}

ansible-playbook test5.yml

檢視驗證

ansible node3 -a "ls -l /test/"

ansible node3 -m shell -a "id test1"

ansible node3 -m shell -a "id test2"

7. Template模組

Jinja是基於Python的模組引擎。Template類是Jinja的一個重要元件,可以看做是一個編譯過的模板檔案,用來產生目標文字,傳遞Python的變數給模板去替換模板中的標記。

7.1 準備template模板檔案

先準備一個以.j2為字尾的template模板檔案,設定引用的變數

模板檔案使用test1曾用的httpd.conf配置檔案

cd /etc/ansible

cp httpd.conf httpd.conf.j2

vim httpd.conf.j2

42行,修改

Listen {{http_port}}

95行,修改

ServerName {{server_name}}

119行,修改

DocumentRoot "{{root_dir}}"

124行,修改

<Directory "{{root_dir}}">

7.2 修改主機清單檔案

修改主機清單檔案,使用主機變數定義一個變數名相同,而值不同的變數

7.3 編寫playbook

vim test6.yml

---

- hosts: all

remote_user: root

vars:

- package: httpd

- service: httpd

tasks:

- name: install httpd package

yum: name={{package}} state=latest

- name: install configure file

template: src=/etc/ansible/httpd.conf.j2 dest=/etc/httpd/conf/httpd.conf

使用template模板

notify:

- restart httpd

- name: create root dir

file: path=/etc/httpd/htdocs state=directory

- name: start httpd server

service: name={{service}} enabled=true state=started

handlers:

- name: restart httpd

service: name={{service}} state=restarted

7.4 執行playbook

ansible-playbook test6.yml

7.5 製作測試網頁

[root@ansible ~]# ansible node1 -m shell -a "echo 'this is test1 template test' > /etc/httpd/htdocs/index.html"

node1 | CHANGED | rc=0 >>

[root@ansible ~]# ansible node2 -m shell -a "echo 'this is test2 template test' > /etc/httpd/htdocs/index.html"

node2 | CHANGED | rc=0 >>

[root@ansible ~]# ansible node3 -m shell -a "echo 'this is test3 template test' > /etc/httpd/htdocs/index.html"

node3 | CHANGED | rc=0 >>

7.6 訪問測試

curl,訪問前要開放httpd服務的埠

8. tags模組

可以在一個playbook中為某個或某些任務定義"標籤",在執行此playbook時通過ansible-playbook命令使用--tags選項能實現僅執行指定的tasks。

playbook還提供了一個特殊的tags為always。作用就是當使用always當tags的task時,無論執行哪一個tags時,定義有always的tags都會執行。

8.1 編寫指令碼

vim test7.yml

---

- hosts: web

remote_user: root

tasks:

- name: mkdir directory

file: path=/opt/test/ state=directory

tags:

- always

- name: touch file

file: path=/opt/test/testhost state=touch

tags:

- test1

- all

- name: copy hosts file

copy: src=/etc/hosts dest=/opt/test/hosts

tags:

- test2

- all

8.2 執行tags="test1"

ansible-playbook test7.yml --tags="test1"

ansible web -a "ls -l /opt/test/"

8.3 執行tags="test2"

刪除資料夾

ansible web -m file -a "path=/opt/test/ state=absent"

ansible web -a "ls -l /opt/test/"

執行tags="test2"

ansible web -a "ls -l /opt/test/"

8.4 執行tags="all"

刪除資料夾

ansible web -m file -a "path=/opt/test/ state=absent"

ansible web -a "ls -l /opt/test/"

執行tags="all"

ansible-playbook test7.yml --tags="all"

ansible web -a "ls -l /opt/test/"