一、創建角色目錄結構
1、角色創建流程
1️⃣:在Ansible中創建角色不需要特別的開發工具。創建和使用角色包含三個步驟:
- 創建角色目錄結構
- 定義角色內容
- 在playbook中使用角色
2、角色目錄創建說明
1️⃣:默認情況下,Ansible在Ansible Playbook所在目錄的roles子目錄中查找角色。這樣,用戶可以利用playbook和其他支持文件存儲角色
2️⃣:如果Ansible無法在該位置找到角色,它會按照順序在Ansible配置設置roles_path所指定的目錄中查找
- 此變量包含要搜索的目錄的冒號分隔列表。此變量的默認值為:
~/.ansible/roles:/usr/share/ansible/roles:/etc/ansible/roles
- 例如:在/etc/ansible/ansible.cfg文件中添加roles_path(以冒號分隔)
[root@localhost ~]# grep roles_path /etc/ansible/ansible.cfg roles_path = ~/.ansible/roles:/usr/share/ansible/roles:/etc/ansible/roles
3️⃣:這允許用戶將角色安裝到由多個項目共享的系統上。
- 例如,用戶可能將自己的角色安裝在自己的主目錄下的~/.ansible/roles子目錄中,而系統可能將所有用戶的角色安裝在/usr/share/ansible/roles目錄中
3、角色各目錄說明
1️⃣:README.md提供人類可讀的基本角色描述、有關如何使用該角色的文檔和示例,以及其發揮作用所需要滿足的任何非Ansible要求
2️⃣:meta子目錄包含一個main.yml文件,該文件指定有關模塊的作者、許可證、兼容性和依賴項的信息
3️⃣:files子目錄包含固定內容的文件,而templates子目錄則包含使用時可由角色部署的模板
4️⃣:其他子目錄中可以包含main.yml文件,它們定義默認的變量值、處理程序、任務、角色元數據或變量,具體取決於所處的子目錄
5️⃣:注意:
如果某一子目錄存在但為空,如本例中的handlers,它將被忽略。如果某一角色不使用功能,則其子目錄可以完全省略。例如,本例中的vars子目錄已被省略
二、創建角色框架
1、角色框架構建
1️⃣:ansible-galaxy命令行工具可用於管理Ansible角色,包括新角色的創建。用戶可以運行ansible-galaxy init來創建新角色的目錄結構(init:初始化)
2️⃣:指定角色的名稱作為命令的參數,該命令在當前工作目錄中為新角色創建子目錄
- 演示實例:創建一個httpd角色
[root@localhost project]# ls playbook.yaml [root@localhost project]# ansible-galaxy init httpd - Role httpd was created successfully [root@localhost project]# ls httpd playbook.yaml [root@localhost project]# tree httpd/ httpd/ ├── defaults │ └── main.yml ├── files ├── handlers │ └── main.yml ├── meta │ └── main.yml ├── README.md ├── tasks │ └── main.yml ├── templates ├── tests │ ├── inventory │ └── test.yml └── vars └── main.yml 8 directories, 8 files //創建httpd目錄后,會自動創建一些示例的文件
三、定義角色內容
1、創建角色內容
- 演示實例:以上面創建的httpd角色目錄結構
- 1、在file目錄中創建需要copy的文件
[root@localhost project]# ls httpd/files/ dvd.repo
- 2、在templates目錄中創建模板文件
[root@localhost project]# cat httpd/templates/httpd.conf.j2 <VirtualHost {{ anisble_facts['default_ipv4']['address'] }}:{{ port }}> DocumentRoot "/var/www/html/{{ dir_name }}" ErrorLog "/var/log/httpd/{{ dir_name }}-error_log" CustomLog "/var/log/httpd/{{ dir_name }}-access_log" common </VirtualHost>
- 3、在vars目錄下床架變量文件
[root@localhost project]# cat httpd/vars/main.yml --- # vars file for httpd port: 8080 dir_name: sharedir
- 4、在tasks目錄中床架執行文件
[root@localhost project]# cat httpd/tasks/main.yml --- - name: copy dvd.repo copy: src: ../files/dvd.repo dest: /etc/yum.repos.d/dvd.repo - name: sent template template: src: ../templates/httpd.conf.j2 dest: /etc/httpd/conf.d/httpd.conf
- 1、在file目錄中創建需要copy的文件
其他的我就不一一舉例了,說白了就是在每個對應的目錄下,寫入每個YAML文件
四、角色內容開發推薦做法
1、模塊化編寫
1️⃣:角色允許以模塊化方式編寫playbook。為了最大限度地提高新開發角色的效率,請考慮在角色開發中采用以下推薦做法:
- 在角色自己的版本控制存儲庫中維護每個角色。Ansible很適合使用基於git的存儲庫
- 角色存儲庫中不應存儲敏感信息,如密碼或SSH密鑰。敏感值應以變量的形式進行參數化,其默認值應不敏感。
- 使用角色的playbook負責通過Ansible Vault變量文件、環境變量或其他ansible-playbook選項定義敏感變量。
- 使用ansible-galaxy init啟動角色,然后刪除不需要的任何目錄和文件。
- 創建並維護README.md和meta/main.yml文件,以記錄用戶的角色的用途、作者和用法
- 讓角色側重於特定的用途或功能。可以編寫多個角色,而不是讓一個角色承擔許多任務
- 經常重用和重構角色。避免為邊緣配置創建新的角色。如果現有角色能夠完成大部分的所需配置,請重構現有角色以集成新的配置方案
- 使用集成和回歸測試技術來確保角色提供所需的新功能,並且不對現有的playbook造成問題
五、定義角色依賴項
1、角色依賴
1️⃣:角色依賴項使得角色可以將其他角色作為依賴項包含在內
- 演示實例:一個定義文檔服務器的角色可能依賴於另一個安裝和配置web服務器的角色。依賴關系在角色目錄層次結構中的meta/main.yml文件內定義
[root@localhost project]# cat httpd/meta/main.yml --- - name: dependen role dependencies: - role: apache port: 8080 - role: postgres dbname: serverlist admin_user: felix
2️⃣:默認情況下,角色僅作為依賴項添加到playbook中一次。若有其他角色也將它作為依賴項列出,它不會再次運行
- 此行為可以被覆蓋,將meta/main.yml文件中的allow_duplicates變量設置為yes即可
六、在playbook中使用角色
1、在playbook中引用角色
1️⃣:要訪問角色,可在play的roles:部分引用它
[root@localhost project]# cat playbook.yaml --- - hosts: all roles: - httpd
這里可以不用加roles,默認情況下,Ansible會在Playbook所在目錄的roles子目錄中查找角色
七、通過變量更改角色行為
1、角色中變量優先級
1️⃣:如果通過以下方式定義了相同的變量,則角色的defaults目錄中定義的變量的值將被覆蓋
- 在清單文件中定義,作為主機變量或組變量
- 在playbook項目的group_vars或host_vars目錄下的YAML文件中定義
- 作為變量嵌套在play的vars關鍵字中定義
- 在play的roles關鍵字中包含該角色時作為變量定義
總結:在httpd/vars目錄下定義的變量的優先級最高;/httpd/vars目錄下的變量會覆蓋/httpd/defaults目錄下的定義的變量
2️⃣:重要:
- 在play中使用角色變量時,變量的優先順序可能會讓人困惑
- 幾乎任何其他變量都會覆蓋角色的默認變量,如清單變量、playvars變量,以及內嵌的角色參數等。
- 較少的變量可以覆蓋角色的vars目錄中定義的變量。
- 事實、通過include_vars加載的變量、
- 清單變量和playvars無此能力。這非常重要,因為它有助於避免用戶的play意外改變角色的內部功能。注冊的變量和角色參數是其中一些具備這種能力的變量
- 不過,正如上述示例中最后一個所示,作為角色參數內嵌聲明的變量具有非常高的優先級,它們可以覆蓋角色的vars目錄中定義的變量。
- 如果某一角色參數的名稱與playvars或角色vars中設置的變量或者清單變量或playbook變量的名稱相同,該角色參數將覆蓋另一個變量