Ansible 的指令碼——playbook 劇本
阿新 • • 發佈:2021-10-26
目錄
一、playbooks組成
Tasks:任務,即通過 task 呼叫 ansible 的模板將多個操作組織在一個 playbook 中執行 Variables:變數 Templates:模板 Handlers:處理器,當changed狀態條件滿足時,(notify)觸發執行的操作 Roles:角色
1.1、示例
vim test.yaml --- #yaml檔案以---開頭,以表明這是一個yaml檔案,可省略 - name: first play #定義一個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=/opt/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,從而避免多次重啟。 //執行playbook ansible-playbook test1.yaml //補充引數: -k(–ask-pass):用來互動輸入ssh密碼 -K(-ask-become-pass):用來互動輸入sudo密碼 -u:指定使用者 ansible-playbook test1.yaml --syntax-check #檢查yaml檔案的語法是否正確 ansible-playbook test1.yaml --list-task #檢查tasks任務 ansible-playbook test1.yaml --list-hosts #檢查生效的主機 ansible-playbook test1.yaml --start-at-task='install httpd' #指定從某個task開始執行
1.2、定義、引用變數
- name: second play hosts: dbservers 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變數資訊 ansible-playbook test1.yaml -e "username=nginx" #在命令列裡定義變數 #命令列輸入的變數值優先順序高於yaml檔案中的變數值
1.3、指定遠端主機sudo切換使用者
---
- hosts: dbservers
remote_user: zhangsan
become: yes #2.6版本以後的引數,之前是sudo,意思為切換使用者執行
become_user: root #指定sudo使用者為root
執行playbook時:ansible-playbook test1.yml -K <密碼>
1.4、when條件判斷
在Ansible中,提供的唯一一個通用的條件判斷是when指令,當when指令的值為true時,則該任務執行,否則不執行該任務。
when一個比較常見的應用場景是實現跳過某個主機不執行任務或者只有滿足條件的主機執行任務
vim test3.yaml
---
- hosts: all
remote_user: root
tasks:
- name: shutdown host
command: /sbin/shutdown -r now
when: ansible_default_ipv4.address == "192.168.80.12" #when指令中的變數名不需要手動加上 {{}}
或
when: inventory_hostname == "<主機名>"
1.5、迭代
Ansible提供了很多種迴圈結構,一般都命名為with_items,作用等同於 loop 迴圈。
vim test3.yaml
---
- name: play1
hosts: dbservers
gather_facts: false
tasks:
- name: create directories
file:
path: "{{item}}"
state: directory
with_items: #等同於 loop:
- /opt/test1
- /opt/test2
- name: add users
user: name={{item.name}} state=present groups={{item.groups}}
with_items:
- name: test1
groups: wheel
- name: test2
groups: root
或
with_items:
- {name:'test1', groups:'wheel'}
- {name:'test2', groups:'root'}
1.6、Templates 模組
Jinja是基於Python的模板引擎。Template類是Jinja的一個重要元件,可以看作是一個編譯過的模板檔案,用來產生目標文字,傳遞Python的變數給模板去替換模板中的標記。
1.先準備一個以 .j2 為字尾的 template 模板檔案,設定引用的變數
cp /etc/httpd/conf/httpd.conf /opt/httpd.conf.j2
vim /opt/httpd.conf.j2
Listen {{http_port}} #42行,修改
ServerName {{server_name}} #95行,修改
DocumentRoot "{{root_dir}}" #119行,修改
<Directory "{{root_dir}}"> #124行,修改
2.修改主機清單檔案,使用主機變數定義一個變數名相同,而值不同的變數
vim /etc/ansible/hosts
[webservers]
192.168.80.12 http_port=192.168.80.12:80 server_name=www.aaa.com:80 root_dir=/etc/httpd/htdocs
[dbservers]
192.168.80.13 http_port=192.168.80.13:80 server_name=www.bbb.com:80 root_dir=/etc/httpd/htdocs
3.編寫 playbook
vim apache.yaml
---
- 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=/opt/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
1.7、tags 模組
可以在一個playbook中為某個或某些任務定義“標籤”,在執行此playbook時通過ansible-playbook命令使用--tags選項能實現僅執行指定的tasks。
playbook還提供了一個特殊的tags為always。作用就是當使用always當tags的task時,無論執行哪一個tags時,定義有always的tags都會執行。
vim webhosts.yaml
---
- hosts: webservers
remote_user: root
tasks:
- name: Copy hosts file
copy: src=/etc/hosts dest=/opt/hosts
tags:
- only #可自定義
- name: touch file
file: path=/opt/testhost state=touch
tags:
- always #表示始終要執行的程式碼
ansible-playbook webhosts.yaml --tags="only"
vim dbhosts.yaml
---
- hosts: dbservers
remote_user: root
tasks:
- name: Copy hosts file
copy: src=/etc/hosts dest=/opt/hosts
tags:
- only
- name: touch file
file: path=/opt/testhost state=touch
ansible-playbook dbhosts.yaml --tags="only"
//分別去兩臺被管理主機上去檢視檔案建立情況
1.8、Roles 模組
Ansible為了層次化、結構化地組織Playbook,使用了角色(roles),roles可以根據層次型結構自動裝載變數檔案、task以及handlers等。簡單來講,roles就是通過分別將變數、檔案、任務、模組及處理器放置於單獨的目錄中,並可以便捷地include它們。roles一般用於基於主機構建服務的場景中,但也可以用於構建守護程序等場景中。
1.8.1、roles 的目錄結構
cd /etc/ansible/
tree roles/
roles/
├── web/
│ ├── files/
│ ├── templates/
│ ├── tasks/
│ ├── handlers/
│ ├── vars/
│ ├── defaults/
│ └── meta/
└── db/
├── files/
├── templates/
├── tasks/
├── handlers/
├── vars/
├── defaults/
└── meta/
1.8.2、roles 內各目錄含義解釋
●files
用來存放由 copy 模組或 script 模組呼叫的檔案。
●templates
用來存放 jinjia2 模板,template 模組會自動在此目錄中尋找 jinjia2 模板檔案。
●tasks
此目錄應當包含一個 main.yml 檔案,用於定義此角色的任務列表,此檔案可以使用 include 包含其它的位於此目錄的 task 檔案。
●handlers
此目錄應當包含一個 main.yml 檔案,用於定義此角色中觸發條件時執行的動作。
●vars
此目錄應當包含一個 main.yml 檔案,用於定義此角色用到的變數。
●defaults
此目錄應當包含一個 main.yml 檔案,用於為當前角色設定預設變數。
●meta
此目錄應當包含一個 main.yml 檔案,用於定義此角色的特殊設定及其依賴關係。
1.8.3、示例
(1)建立以 roles 命名的目錄
mkdir /etc/ansible/roles/ -p #yum裝完預設就有
(2)建立全域性變數目錄(可選)
mkdir /etc/ansible/group_vars/ -p
touch /etc/ansible/group_vars/all #檔名自己定義,引用的時候注意
(3)在 roles 目錄中分別建立以各角色名稱命令的目錄,如 httpd、mysql、php
mkdir /etc/ansible/roles/httpd
mkdir /etc/ansible/roles/mysql
mkdir /etc/ansible/roles/php
(4)在每個角色命令的目錄中分別建立7個目錄
mkdir /etc/ansible/roles/httpd/{files,templates,tasks,handlers,vars,defaults,meta}
mkdir /etc/ansible/roles/mysql/{files,templates,tasks,handlers,vars,defaults,meta}
mkdir /etc/ansible/roles/php/{files,templates,tasks,handlers,vars,defaults,meta}
(5)在每個角色的 handlers、tasks、meta、defaults、vars 目錄下建立 main.yml 檔案,千萬不能自定義檔名
touch /etc/ansible/roles/httpd/{defaults,vars,tasks,meta,handlers}/main.yml
touch /etc/ansible/roles/mysql/{defaults,vars,tasks,meta,handlers}/main.yml
touch /etc/ansible/roles/http/{defaults,vars,tasks,meta,handlers}/main.yml
(6)編寫httpd模組
寫一個簡單的tasks/main.yml
vim /etc/ansible/roles/httpd/tasks/main.yml
- name: install apache
yum: name={{pkg}} state=latest
- name: start apache
service: enabled=true name={{svc}} state=started
vim /etc/ansible/roles/mysql/vars/main.yml
pkg:
- mariadb
- mariadb-server
svc: mariadb
(7)編寫mysql模組
vim /etc/ansible/roles/mysql/tasks/main.yml
- name: install mysql
yum: name={{pkg}} state=latest
- name: start mysql
service: enabled=true name={{svc}} state=started
vim /etc/ansible/roles/mysql/vars/main.yml
pkg:
- mariadb
- mariadb-server
svc: mariadb
(8)編寫php模組
vim /etc/ansible/roles/php/tasks/main.yml
- name: install php
yum: name={{pkg}} state=latest
- name: start php-fpm
service: enabled=true name={{svc}} state=started
vim /etc/ansible/roles/php/vars/main.yml
pkg:
- php
- php-fpm
svc: php-fpm
(9)編寫roles示例
vim /etc/ansible/site.yml
---
- hosts: webservers
remote_user: root
roles:
- httpd
- mysql
- php
cd /etc/ansible
ansible-playbook site.yml