管理大型的playbook任務扩灯、利用角色簡化playbook
當一個playbook中包含了一個大型的服務時,我們可以將其拆分成小的文件霜瘪,便于管理珠插;也可利用模塊化的東西將多個playbook組合為一個playbook,或將單個文件插入到playbook中颖对。這樣就可以在多個項目中重復利用單個文件捻撑。
包含或導入文件
- 包含是一個動態(tài)的操作,在playbook運行運行期間,ansible會在內容到達時處理所包含的內容顾患。
- 導入是一個靜態(tài)的操作番捂,在playbook運行之前,在ansible最初解析playbook時預處理導入的內容江解。就是還沒有運行playbook時就已經將所需要的文件導入到所要執(zhí)行的playbook中了设预。
導入playbook
- import_playbook命令作用是將包含有play列表的外部文件導入到篇playbook。也就是說把一個或多個playbook導入到要執(zhí)行的哪個playbook中去膘流。
規(guī)則:import_playbook命令只能在playbook的頂層使用絮缅,因為我們導入的一般都是一個完整的鲁沥。
示例:
在node2上安裝httpd并且將配置文件里的80端口改為8080
[root@node1 playbook]# cat install.yml
---
- hosts: noe2
tasks:
- name:
yum:
name: httpd
state: present
[root@node1 playbook]# cat config.yml
---
- hosts: node2
vars_files:
- file/test.yml
tasks:
- name: config httpd
template:
src: file/httpd.conf.j2
dest: /etc/httpd/conf/httpd.conf
[root@node1 playbook]# cat main.yml
- name: install
import_playbook: install.yml
- name: config
import_playbook: config.yml
[root@node1 file]# cat test.yml
port: 8080
#Listen 12.34.56.78:80
Listen {{ port }}
#Listen 12.34.56.78:80
Listen 8080
導入本機的playbook
[root@node1 playbook]# cat main.yml
---
- hosts: node2
tasks:
- name: 開啟httpd
service:
name: httpd
state: started
enabled: yes
- name: install
import_playbook: install.yml
- name: config
import_playbook: config.yml
[root@node1 playbook]# ansible-playbook main.yml
PLAY [node2] *******************************************************************
TASK [Gathering Facts] *********************************************************
ok: [node2]
TASK [開啟httpd] *****************************************************************
changed: [node2]
[WARNING]: Could not match supplied host pattern, ignoring: noe2
PLAY [noe2] ********************************************************************
skipping: no hosts matched
[WARNING]: Found variable using reserved name: port
PLAY [node2] *******************************************************************
TASK [Gathering Facts] *********************************************************
ok: [node2]
TASK [config httpd] ************************************************************
ok: [node2]
PLAY RECAP *********************************************************************
node2 : ok=4 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
導入和包含任務
將一些任務文件到導入到play中
在install文件里面只寫任務呼股,將其導入到main文件里面。
[root@node1 playbook]# ansible-playbook main.yml
PLAY [node2] *******************************************************************
TASK [Gathering Facts] *********************************************************
ok: [node2]
TASK [install] *****************************************************************
ok: [node2]
TASK [開啟httpd] *****************************************************************
ok: [node2]
PLAY RECAP *********************************************************************
node2 : ok=3 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
[root@node1 playbook]# cat main.yml
---
- hosts: node2
tasks:
- import_tasks: /opt/playbook/install.yml
- name: 開啟httpd
service:
name: httpd
state: started
enabled: yes
[root@node1 playbook]# cat install.yml
- name: install
yum:
name: httpd
state: present
包含任務文件
[root@node1 playbook]# cat main.yml
---
- hosts: node2
tasks:
- include_tasks: /opt/playbook/install.yml
- name: 開啟httpd
service:
name: httpd
state: started
enabled: yes
導入任務文件時画恰,需要注意的地方
- 當使用import_tasks功能時導入時設置的when條件語句將應用于導入的每個任務
- 無法將循環(huán)用于import_tasks功能
- 若使用變量來指定要導入的文件名稱彭谁,則將無法使用主機或組清單變量就是無法將,主機清單作為變量允扇。
- 當運行ansible-playbook --list-tasks以列出playbook中的任務時缠局,可以看到導入任務文件里面的任務。
包含任務文件時需要注意的地方:
- 使用include_tasks功能時考润,在包含的文件里面有when時就進行判斷狭园。
- 如果運行ansible-playbook --list-tasks以列出playbook中的任務時,不會顯示包含文件里面的任務內容糊治,但是導入時可以看到任務文件里面的任務
- 不能使用ansible-playbook --start-at-task指定包含任務文件中哪個playbook先執(zhí)行唱矛,playbook遵循的是有序性,具有先后順序井辜。
- 不能在包含任務文件的文件里面使用notify語句绎谦,即使使用也不會觸發(fā)處理程序,但是可以在包含了整個任務文件的playbook中去使用粥脚。
為外部play和任務定義變量
使用Ansible的導入和包含功能將外部文件中的play或任務合并到playbook中極大地增強了在Ansible環(huán)境中重用任務和playbook的能力窃肠。為了更大限度的提高任務文件的重可用度,可以設置一些變量刷允。
注意:在包含有多個play的playbook的文件中若要定義變量冤留,只想對某一個play生效,就需要在包含或導入的play文件的下面定義一個變量树灶,若想對所有的playbook都生效就可以在hosts的下面定義變量纤怒。
[root@node1 playbook]# ansible-playbook main.yml
PLAY [node2] *******************************************************************
TASK [Gathering Facts] *********************************************************
ok: [node2]
TASK [install] *****************************************************************
ok: [node2]
TASK [開啟httpd] *****************************************************************
ok: [node2]
PLAY RECAP *********************************************************************
node2 : ok=3 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
[root@node1 playbook]# cat install.yml
- name: install
yum:
name: "{{ package }}"
state: present
[root@node1 playbook]# cat main.yml
---
- hosts: node2
tasks:
- import_tasks: /opt/playbook/install.yml
vars:
- package: httpd
- name: 開啟httpd
service:
name: httpd
state: started
enabled: yes
描述角色結構:
隨著playbook編寫,我們可能會發(fā)現有很多機會重復利用以前縮寫的playbook中的代碼破托。
在實際的生產工作中肪跋,這個playbook可能是冗長復雜的,有許多包含和導入的文件土砂,Ansible角色提供了一種方法州既,讓用戶能以通用的方式更加輕松地重復利用Ansible代碼谜洽。我們可以在標準化目錄結構中打包所有任務、變量吴叶、文件阐虚、模板,以及調配基礎架構或部署應用所需的其他資源蚌卤。
Ansible角色具有下列優(yōu)點:
- 角色可以分組內容实束,從而與他人輕松共享代碼
- 可以編寫角色來定義系統類型的基本要素:Web服務器、數據庫服務器逊彭、Git存儲庫咸灿,或滿足其他用途
- 角色使得較大型項目更容易管理
- 角色可以由不同的管理員并行開發(fā)
ansible的角色子目錄
子目錄 | 作用 |
---|---|
defaults | 此目錄中的main.yml文件包含角色變量的默認值,使用角色時可以覆蓋這些默認值侮叮。這些變量的優(yōu)先級較低避矢,應該在play中更改和自定義。 |
files | 此目錄包含由角色引用的靜態(tài)文件 |
handlers | 此目錄中的main.yml文件包含角色的處理程序定義 |
meta | 此目錄中的main.yml文件包含與角色相關的信息,如作者、許可證啼止、平臺和可選的角色依賴項。 |
tasks | 此目錄中的main.yml文件包含角色的任務定義 |
templates | 此目錄包含由角色任務引用的Jinja2模板砂沛。 |
tests | 此目錄可以包含清單和名為test.yml的playbook,可用于測試角色曙求。 |
vars | 此目錄中的main.yml文件定義角色的變量值碍庵。這些變量通常用于角色內部用途。這些變量的優(yōu)先級較高圆到,在playbook中使用時不應更改 |
控制執(zhí)行的順序
在playbook中的每個play都是按照順序從上到下的順序執(zhí)行
角色要寫至任務列表的開頭怎抛,若有第二個playbook,其任務列表需要添加到第一個角色之后芽淡。
角色處理程序添加到play中的方式與角色任務添加到play中相同马绝,但是要注意的是如果playbook和roles中都有handlers,則優(yōu)先添加roles里面的handlers挣菲,在將playbook中的handlers添加到roles之后富稻。
在有些情況下需要在角色任務之前執(zhí)行一個play任務這時我們就需要
使用pre_tasks這樣就可以在角色任務執(zhí)行之前執(zhí)行想要執(zhí)行的任務。
在pre_tasks中的tasks任務和notify白胀、handlers都是優(yōu)先執(zhí)行的椭赋。在pre_tasks后面就是roles角色任務,角色任務后面跟執(zhí)行角色任務的角色名或杠。
角色任務的tasks和notify都是在pre_tasks的后面執(zhí)行tasks就是寫要正常要執(zhí)行的任務哪怔,同樣的tasks里面的任務要在roles角色任務后面執(zhí)行。
post_tasks在tasks后面執(zhí)行,post_tasks里面的任務同理在tasks的后面執(zhí)行认境。
再執(zhí)行notify胚委、handlers。在handlers規(guī)則中無論notify出現幾次都只執(zhí)行一次叉信,如果pre_tasks亩冬、tasks、post_tasks都有notify最后的handlers就會都執(zhí)行一次
所以優(yōu)先級從大到小就是pre_tasks>roles>tasks>post_tasks>hangdlers硼身。
利用系統角色重用內容
RHEL系統角色
名稱 | 角色作用 |
---|---|
rhel-system-roles.kdump | 配置kdump崩潰恢復服務 |
rhel-system-roles.network | 配置網絡接口 |
rhel-system-roles.selinux | 配置和管理SELinux自定義,包括selinux模式硅急、文件以及端口上下文 |
rhel-system-roles.timesync | 使用網絡時間協議或精確時間協議配置時間同步 |
rhel-system-roles.postfix | 使用Postfix服務將每個主機配置為郵件傳輸代理 |
rhel-system-roles.firewalld | 配置主機的防火墻 |
rhel-systemctl-roles.tuned | 配置tuned服務,以調優(yōu)系統性能 |
安裝系統用戶
[root@node1 playbook]# yum -y install rhel-system-roles
Updating Subscription Management repositories.
Unable to read consumer identity
This system is not registered to Red Hat Subscription Management. You can use subscription-manager to register.
上次元數據過期檢查:0:23:47 前佳遂,執(zhí)行于 2021年08月01日 星期日 19時08分34秒营袜。
依賴關系解決。
==========================================================================
軟件包 架構 版本 倉庫 大小
==========================================================================
安裝:
rhel-system-roles noarch 1.0-10.el8_1 AppStream 175 k
事務概要
==========================================================================
安裝 1 軟件包
總計:175 k
安裝大醒惹ā:1.1 M
下載軟件包:
運行事務檢查
事務檢查成功连茧。
運行事務測試
事務測試成功。
運行事務
準備中 : 1/1
安裝 : rhel-system-roles-1.0-10.el8_1.noarch 1/1
驗證 : rhel-system-roles-1.0-10.el8_1.noarch 1/1
Installed products updated.
已安裝:
rhel-system-roles-1.0-10.el8_1.noarch
完畢巍糯!
系統用戶存在于
[root@node1 roles]# ls /usr/share/ansible/roles/
linux-system-roles.kdump rhel-system-roles.kdump
linux-system-roles.network rhel-system-roles.network
linux-system-roles.postfix rhel-system-roles.postfix
linux-system-roles.selinux rhel-system-roles.selinux
linux-system-roles.storage rhel-system-roles.storage
linux-system-roles.timesync rhel-system-roles.timesync
訪問RHEL系統角色的文檔
RHEL系統角色的文檔位于/usr/share/doc/rhel-system-roles-/目錄中
[root@node1 roles]# ls /usr/share/doc/rhel-system-roles/
kdump network postfix selinux storage timesync
時間同步角色
timesync_ntp_servers屬性
屬性 | 用途 |
---|---|
hostname | 要與其同步的NTP服務器的主機名。 |
iburst | 一個布爾值客扎,用于啟用或禁用快速初始同步祟峦。在角色中默認為no,但通常應該將屬性設為yes徙鱼。 |
系統角色的使用
timesync
[root@node1 roles]# cp -a /usr/share/ansible/roles/rhel-system-roles.timesync/ ./timesync
[root@node1 roles]# cat time.yml
---
- hosts: node2
vars:
timesync_ntp_servers: //使用rhel-system-roles.timesync角色在受管主機上面配置NTP時間同步
- hostname: time.aliyun.com //hostname是指定要同步的NTP服務器宅楞,這里我們使用阿里云
iburst: yes //這里的iburst是用于啟用或禁用快速初始同步的。
roles:
- timesync 使用timesync這個角色
SELINUX角色使用
selinux角色可以執(zhí)行的任務包括:
- 設置enforcing或permissive模式
- 對文件系統層次結構的各部分運行restorecon
- 設置SELinux布爾值
- 永久設置SELinux文件上下文
- 設置SELinux用戶映射
示例
將selinu設置為開啟狀態(tài)
[root@node1 roles]# cat selinux.yml
---
- hosts: node2
vars:
selinux_state: enforcing
tasks:
- name:
block:
- include_role:
name: selinux
rescue:
- name: reboot
fail:
when: not selinux_reboot_required
- name: reboot
reboot:
- name: config selinux
include_role:
name: selinux
示例:
將httpd改為82端口袱吆,并修改selinux規(guī)則后能成功訪問http
[root@node1 roles]# cat selinux.yml
---
- hosts: node2
vars:
selinux_state: enforcing
selinux_ports:
- ports: '82'
setype: 'httpd_port_t'
proto: 'tcp'
state: 'present'
tasks:
- name: install httpd
yum:
name: httpd
state: present
- name: start httpd
service:
name: httpd
state: started
- name: selinux for httpd
template:
src: roles/httpd.conf.j2
dest: /etc/httpd/conf/httpd.conf
- name:
block:
- include_role:
name: selinux
rescue:
- name: reboot
fail:
when: not selinux_reboot_required
- name: reboot
reboot:
- name: config selinux
include_role:
name: selinux
ansible-galaxy的用法
[root@node1 roles]# ansible-galaxy search 'httpd
可以進行聯網搜索roles
[root@node1 roles]# ansible-galaxy info acandid.httpd
用來查看roles基本信息
[root@node1 roles]# ansible-galaxy install acandid.httpd -p /ansible/roles
下載roles到特定的目錄中
[root@node1 roles]# ansible-galaxy list -p roles/
列出本地有哪些roles
創(chuàng)建角色框架
創(chuàng)建一個目錄用來創(chuàng)建角色
[root@node1 ~]# mkdir -p ~/ansible/roles
使用下面的命令初始化一個roles
[root@node1 roles]# ansible-galaxy init now_role
- Role now_role was created successfully
roles規(guī)范的目錄結構
目錄 | 作用 |
---|---|
defualts/main.yml | 定義變量的缺省值厌衙,優(yōu)先級較低 |
files | 存儲靜態(tài)文件的目錄 |
handlers/main.yml | 定義handlers |
meta/main.yml | 寫作者、版本等描述信息 |
tasks/main.yml | 定義任務的地方 |
templates | 存放動態(tài)數據文件的地方(模板文件) |
vars/main.yml | 定義變量绞绒,優(yōu)先級高 |
在playbook中調用role
有兩中方法:
1. 在與role平級的目錄下創(chuàng)建一個playbook進行調用
2. 在ansible.cfg這個配置文件里面加上roles_path = 告訴你的role路徑在哪
角色的使用方式
示例:
這里我選擇在配置文件里面添加
使用templates目錄來調用模塊事實在var目錄調用變量婶希,并在node2主機上進行輸出。
[defaults]
roles_path = /ansible/roles
[root@node1 now_role]# cat templates/test.j2
this is the system {{ ansible_hostname }}
date is {{ ansible_date_time.date }}
var is {{ admin }}
[root@node1 now_role]# cat vars/main.yml
---
# vars file for now_role
admin: hello roles
[root@node1 roles]# cat all.yml
- hosts: node2
roles:
- now_role
這里的all.yml的文件需要在與now_role目錄平級的地方使用蓬衡。
[root@node1 roles]# ansible-playbook all.yml
PLAY [node2] *******************************************************************
TASK [Gathering Facts] *********************************************************
ok: [node2]
TASK [now_role file] ***********************************************************
changed: [node2]
PLAY RECAP *********************************************************************
node2 : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
[root@node2 ~]# cat /opt/file
this is the system node2
date is 2021-08-02
var is hello roles
通過變量更改角色的行為
通過編寫角色利用默認變量來改變角色行為喻杈,讓其更具靈活性。這有助于角色適應更多的應用場景狰晚,可在不同的上下文中使用筒饰。
通過一下方式定義的變量default目錄中定義的變量將會被覆蓋:
- 在清單文件中定義,作為主機變量或組變量
- 在playbook項目的group壁晒、vars或host瓷们、vars目錄下的YAML文件中定義的變量。
- 作為變量嵌套在play的vars關鍵字中定義
- 在play的roles關鍵字中包含該角色時作為變量定義。