角色
一、利用角色構造ansible playbook
隨著開發更多的playbook,會發現有很多機會重復利用以前編寫的playbook中的代碼。或許,一個用于為某一應用配置MySQL數據庫的play可以改變用途。通過利用不同的主機名、密碼和用戶來為另一個應用配置MySQL數據庫。
但在現實中,這個play可能比較冗長且復雜,有許多包含或導入的文件,以及用于管理各種情況的任務和處理程序。將所有這些代碼復制到另一playbook種可能并不簡單。
ansible提供了一種方法,能以通用的方式更加輕松地重復利用ansible代碼。可以在標準化目錄結構中打包所有的任務、變量、文件、模板,以及調整基礎架構或部署應用所需的其他資源。只需通過復制相關的目錄,將角色從一個項目復制到另外一個項目。然后,只需從一個play調用該角色就能執行。
借助編寫好的角色,可以從playbook中向角色傳遞調整其行為的變量,設置所有站點相關的主機名、IP地址、用戶名,或其他在本地需要的具體詳細信息。例如,部署數據庫服務器的角色可能已編寫為支持多個變量,這些變量用于設置主機名、數據庫管理員用戶和密碼,以及需要為安裝進行自定義的其他參數。角色的作者也可以確保在選擇不在play中設置變量值時,為這些變量設定合理的默認值。
ansible角色具有下列優點:
\1. 角色可以分組內容,從而與他人輕松共享代碼
\2. 可以編寫角色來定義系統類型的基本要素:Web服務器、數據庫服務器、Git存儲庫,或滿足其他用途
\3. 角色使得較大型項目更容易管理
\4. 角色可以由不同的管理員并行開發
除了自行編寫、使用、重用和共享角色以外,還可以從其他來源獲取角色。一些角色以及包含在rhel-system-rolses軟件包中,作為紅帽企業Linux的一部分。可以從ansible Galaxy網站獲取由社區提供支持的許多角色。
檢查ANSIBLE角色結構
? ansible角色由字幕了和文件的標準化結構定義。頂級目錄定義角色本身的名稱。文件整理到子目錄中,子目錄按照各個文件在角色中的用途進行命名,如tasks和handlers。files和templates子目錄中包含其他YAML文件中的任務引用的文件。
Defaults:此目錄中的main.yml文件包含角色變量的默認值,使用角色時可以覆蓋這些默認值。這些變量的優先級較低,應該在play中更改和自定義。
Files:此目錄包含由角色任務引用的靜態文件
Handlers:此目錄中的main.yml文件包含角色的處理程序定義,也就是觸發器的內容。
Meta:此目錄中的main.yml文件包含與角色相關的信息,如作者、許可證、平臺和可選的角色的依賴項。
Tasks: 此目錄中的mian.yml文件包含角色的任務定義。
Template: 此目錄包含由角色任務引用的jinja2模板(j2模板)
Tests:此目錄可以包含清單和test.yml劇本,可用于測試角色
Vars:此目錄的文件定義角色的變量值,這些變量通常用于角色內部用途,這些變量的優先級較高,在中使用時不應更改
在playbook中使用ansible角色
在playbook中使用角色非常簡單。
—
- name: test
hosts: node1
roles:
- role1
- role2
對于每個指定的角色,角色任務、角色處理程序、角色變量和角色依賴項將按照順序導入到playbook中。角色中的任何copy、script、template或include_tasks/import_tasks任務都可引用角色中相關的文件、模板或任務文件,且無需相對或絕對路徑名稱。ansible將分別在角色的files、templates或tasks子目錄中尋找他們。
如果使用roles部分將角色導入到play中,這些角色會為該play定義的任何任務之前運行。
以下示例設置ws的角色變量a1和a2的值,使用ws角色時,任何defaults和vars變量都會被覆蓋。
1、創建角色
[student@master roles]$ ansible-galaxy init ws
- Role ws was created successfully
2、在vars里給角色定義變量
---
# vars file for ws
a1: 11
a2: 22
~
3、在tasks目錄中的main.yml中寫角色的任務
---
# tasks file for ws
- name: test1debug:msg: "{{ a1 }}"
4、在/home/student/ansible/目錄下創建一個test.yml的playbook來使用ws角色
---
- name: test11hosts: node1roles:- ws
此時會發現,我們能夠調用角色vars目錄下main.yml定義的變量可以被調用
[student@master ansible]$ ansible-playbook test.yml PLAY [test11] ******************************************************************************************TASK [Gathering Facts] *********************************************************************************
ok: [node1]TASK [ws : test1] **************************************************************************************
ok: [node1] => {"msg": 11
}PLAY RECAP *********************************************************************************************
node1 : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
5、在test.yml的playbook中來定義變量
---
- name: test111hosts: node1roles:- role: wsa1: 333
6、執行test.yml,就會發現test.yml中定義的a1變量覆蓋了角色中vars目錄中定義的變量。
[student@master ansible]$ ansible-playbook test.yml PLAY [test111] *****************************************************************************************TASK [Gathering Facts] *********************************************************************************
ok: [node1]TASK [ws : test1] **************************************************************************************
ok: [node1] => {"msg": 333
}PLAY RECAP *********************************************************************************************
node1 : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
控制執行順序
對于playbook中的每個play,任務按照任務列表中的順序來執行,執行完所有任務后,將執行任何通知的處理程序。
在角色添加到play后,角色任務將添加到任務列表的開頭。如果play中包含第二個角色,其任務列表添加到第一個角色之后。
角色處理程序添加到play中的方式與角色任務添加到play中相同。每個play定義一個處理程序列表。角色處理程序先添加到處理程序列表,后跟play的handlers部分中定義的任何處理程序。
在某些情形中,可能需要在角色之前執行一些play任務。可以為play配置pre_tasks部分。列在此部分中的所有任務將在執行任何角色之前執行。如果這些任務中有任何一個通知了處理程序,則這些處理程序任務也在角色或普通任務之前執行。
此外,play也支持post_tasks關鍵字。這些任務在play的普通任務和他們通知的任何處理程序之后執行。
如:
---
- name: test111hosts: node1roles:- role: wsa1: 333pre_tasks:- name: test2debug:msg: 00000
[student@master ansible]$ ansible-playbook test.yml PLAY [test111] *****************************************************************************************TASK [Gathering Facts] *********************************************************************************
ok: [node1]TASK [test2] *******************************************************************************************
ok: [node1] => {"msg": 0
}TASK [ws : test1] **************************************************************************************
ok: [node1] => {"msg": 333
}PLAY RECAP *********************************************************************************************
node1 : ok=3 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
執行該playbook,我們發現pre_tasks任務在角色之前執行的
示例:
示例:創建和使用角色
根據下列要求,在/home/student/ansible/roles中創建名為http的角色
1、部署yum倉庫
2、安裝httpd軟件包
3、模板文件index.html.j2已存在,用戶創建具有以下輸出的文件/var/www/html/index.html:
Welcome to HOSTNAME on IPADDRESS
當index.html內容發生改變時,重啟httpd服務
其中HOSTNAME是受控節點的完全合格域名,IPADDRESS則是受控節點的IP地址
按照上方所述,創建一個使用此角色的playbook /home/student/ansible/newrole.yml,該playbook在node1主機上運行。
步驟
1、創建http角色
[student@master roles]$ ansible-galaxy init httpd
- Role httpd was created successfully
2、根據要求新建index.html.j2模板
Welcome to {{ ansible_default_ipv4.address }} on {{ ansible_hostname }}
3、在/etc/ansible/roles/http/tasks/main.yml書寫角色任務內容
---
# tasks file for httpd
- name: baseosyum_repository:name: aadescription: aa1baseurl: http://ansible.example.com/rhel9/BaseOSenabled: yesgpgcheck: no- name: appstreamyum_repository:name: bbdescription: bb1baseurl: http://ansible.example.com/rhel9/AppStreamenabled: yesgpgcheck: no- name: install httpd firewalldyum:name:- httpd- firewalldstate: present- name: cp htmltemplate:src: index.html.j2dest: /var/www/html/index.html- name: restart httpd firewalldservice:name: "{{ item }}"state: restartedenabled: yesloop:- httpd- firewalld
- name: set firewalldfirewalld:service: httpstate: enabledpermanent: yesimmediate: yes
4、書寫/home/student/ansible/newrole.yml
playbook,運行http角色
---
- name: testhosts: node1roles:- httpd
5、執行該playbook
[student@master ansible]$ ansible-playbook newrole.yml PLAY [test] ********************************************************************************************TASK [Gathering Facts] *********************************************************************************
ok: [node1]TASK [httpd : baseos] **********************************************************************************
ok: [node1]TASK [httpd : appstream] *******************************************************************************
ok: [node1]TASK [httpd : install httpd firewalld] *****************************************************************
ok: [node1]TASK [httpd : cp html] *********************************************************************************
changed: [node1]TASK [httpd : restart httpd firewalld] *****************************************************************
changed: [node1] => (item=httpd)
changed: [node1] => (item=firewalld)TASK [httpd : set firewalld] ***************************************************************************
changed: [node1]PLAY RECAP *********************************************************************************************
node1 : ok=7 changed=3 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
6、驗證:
[student@master ansible]$ curl http://node1
Welcome to 192.168.122.10 on node1
二、系統角色
1、安裝系統角色
[student@master ansible]$ sudo yum -y install rhel-system-roles
2、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.firewall 配置主機的防火墻
Rhel-system-roles.tuned 配置tuned服務,以調優系統性能
3、RHEL系統角色位于/usr/share/ansible/roles/目錄下
示例:
安裝 RHEL 系統角色軟件包,并創建符合以下條件的playbook /home/student/ansible/timesync.yml:
在所有受管節點上運行
? 使用 timesync 角色
? 配置該角色,以使用當前有效的 NTP 提供商
? 配置該角色,以使用時間服務器 [ansible.example.com]
配置該角色,以啟用iburst 參數
1、安裝系統角色
sudo yum -y install rhel-system-roles
2、將時鐘同步的系統角色復制到/etc/ansible/roles目錄下,并重名了角色名為timesync
[student@master ansible]$ cp -r rhel-system-roles.timesync -p /home/student/ansible/roles/timesync
3、書寫playbook。
---
- name: testhosts: allvars:timesync_ntp_servers:- hostname: ansibleiburst: yesroles:- timesync
4.改ansible主機chrony配置文件
allow 192.168.122.0/24
# Serve time even if not synchronized to a time source.
local stratum 10
5.執行
[student@master ansible]$ ansible-playbook timesync.yml
[student@master ansible]$ ansible node2 -m shell -a 'chronyc sources'
node2 | CHANGED | rc=0 >>
MS Name/IP address Stratum Poll Reach LastRx Last sample
===============================================================================
^* ansible.example.com 3 6 17 1 -171us[ -488us] +/- 54ms
三、從ansible-galaxy安裝角色
ansible-galaxy install子命令從Ansible Galaxy下載角色,并將它站樁到控制節點本地。
默認情況下,角色安裝到用戶的roles_path下的第一個可寫目錄中。根據ansible設置的默認roles_path,角色通常安裝到用戶的~/.ansible/roles目錄。默認的roles_path可能會被當前的ansible配置文件或環境變量ANSIBLE_ROLES_PATH覆蓋,這將影響ansible-galaxy的行為。
可以使用-p DIRECTORY選項,指定具體的目錄來安裝角色。
安裝角色
1、首先在roles目錄下書寫一個playbook,把需要安裝角色的路徑定義到playbook中
---
- name: haproxysrc: http://ansible.example.com/roles/haproxy.tar- name: myphpsrc: http://ansible.example.com/roles/myphp.tar
2、使用ansible-galaxy命令安裝角色
[student@master ansible]$ ansible-galaxy install -r roles/test.yml -p roles/
Starting galaxy role install process
- downloading role from http://ansible.example.com/roles/haproxy.tar
- extracting haproxy to /home/student/ansible/roles/haproxy
- haproxy was installed successfully
- downloading role from http://ansible.example.com/roles/myphp.tar
- extracting myphp to /home/student/ansible/roles/myphp
- myphp was installed successfully
管理下載的角色
ansible-galaxy命令也可管理本地的角色,如位于playbook項目的roles目錄中的角色。ansible-galaxy list子命令列出本地找到的角色。
[student@master ansible]$ ansible-galaxy list
# /home/student/ansible/roles
- ws, (unknown version)
- httpd, (unknown version)
- timesync, (unknown version)
- haproxy, (unknown version)
- myphp, (unknown version)
可以使用ansible-galaxy
remove子命令本地刪除角色
[student@master ansible]$ ansible-galaxy remove myphp
- successfully removed myphp
[student@master ansible]$ ansible-galaxy list
# /home/student/ansible/roles
- ws, (unknown version)
- httpd, (unknown version)
- timesync, (unknown version)
- haproxy, (unknown version)