Ansible Roles和最佳實踐

角色(roles):把playbook根據功能,如handler,tasks等分門別類的放在在各自的子目錄下,形成一個集合,就是角色。
Roles目錄可以是ansible.cfg中roles_path定義的路徑,也可以和入口Playbook文件存放在同級目錄。建議使用roles_path,方便統一管理。這篇的示例使用和入口Playbook文件存放在同級目錄。

Roles are ways of automatically loading certain vars_files, tasks, and handlers based on a known file structure. Grouping content by roles also allows easy sharing of roles with other users.

官方文檔的連接:
https://docs.ansible.com/ansible/latest/user_guide/playbooks_reuse_roles.html

github上官方的簡單示例:
https://github.com/ansible/ansible-examples

最佳實踐的官方文檔:
https://docs.ansible.com/ansible/latest/user_guide/playbooks_best_practices.html

Roles 目錄結構

Roles依賴目錄命名規則和目錄擺放。下面是官方的示例,定義了一個Roles的目錄結構:

site.yml
webservers.yml
fooservers.yml
roles/
    common/
        tasks/
        handlers/
        files/
        templates/
        vars/
        defaults/
        meta/
    webservers/
        tasks/
        defaults/
        meta/
  • *.yml文件: 入口Playbook文件
  • site.yml: 這個名字一般就是部署項目的Playbook文件名。如果還有其他任務在創建Playbook,名字隨意。
  • roles目錄: 存放Roles的目錄。下面每一個子目錄就是一個角色,這裏有common和webservers

在每個角色下,根據功能按需創建目錄,目錄名有規範。每個目錄下都要有一個main.yml文件,ansible會調用這個文件。
目錄名稱的含義如下:

  • tasks: 定義角色的任務列表,可以使用include包含其它的位於此目錄的task文件
  • handlers: 定義角色中觸發條件時執行的動作
  • defaults: 設定默認變量,優先級極低,基本就是該變量沒有值的時候纔會用到這個值
  • vars: 定義角色使用的變量,優先級高
  • files: 用來存放由copy模塊或script模塊調用的文件。不需要main.yml文件
  • templates: 用來存放jinjia2模板,template模塊會自動在此目錄中尋找jinjia2模板文件。不需要main.yml文件
  • meta: 定義角色的元數據,主要是用作依賴關係

多平臺支持

官方有一個在tasks裏區分的多平臺支持的示例。
另外還有一個從書上看到的不同平臺定義不同角色名的示例。
最後是一個在官方最佳實踐中的示例。

tasks 多平臺支持

tasks級別,對應tasks目錄。
定義好角色,角色下定義多個task文件。在main.yml中進行條件判斷,導入對應的task文件。
tasks/main.yml是必須有的,作爲tasks的入口文件,但是實際的代碼不用寫在這個文件裏,可以在這個文件裏包含其他yaml文件。官方有一個多平臺支持的示例:

# roles/example/tasks/main.yml
- import_tasks: redhat.yml
  when: ansible_facts['os_family']|lower == 'redhat'
- import_tasks: debian.yml
  when: ansible_facts['os_family']|lower == 'debian'

# roles/example/tasks/redhat.yml
- yum:
    name: "httpd"
    state: present

# roles/example/tasks/debian.yml
- apt:
    name: "apache2"
    state: present

roles 多平臺支持

角色級別,對應roles下的角色子目錄,比如common和webservers目錄。
直接定義好多個角色,有條件地將所有的角色導入。只有滿足要求的角色會被導入執行。
在roles層面來支持多平臺。預先爲不同平臺定義好不用的角色。比如兩個角色名分別爲 httpd_db 和 httpd_rh。那麼Playbook文件可以這麼寫:

# site.yml
- name: install httpd
  hosts: webservers
  roles:
    - { role: httpd_db, when: ansible_os_family == 'Deian' }
    - { role: httpd_rh, when: ansible_os_family == 'RedHat' }

這裏的判斷平臺的方式和上面的應該是一樣的,都是通過Ansible自動獲取的主機信息來進行自動判斷。這裏的寫法比上面的官網的寫法low。我沒有實際測試,就保留原來的寫法了。

group_by 模塊自動對主機分組

playbook級別,對應roles的同級目錄,比如site.yml文件。
先執行一個 group_by 模塊的task,對主機進行動態分組。之後再分別對組進行playbook的設置。
這部分內容和roles無關,用了roles可以套用,沒用roles也可以套用。是官方最佳實踐裏的做法。
group_by 模塊可以根據關鍵字對主機進行分組。關鍵字可以從主機信息中提取,提取到之後,可以先拼接上一段自定義的前綴或後綴。最終獲得的字符串會成爲一個主機組的組名,這樣Playbook中的hosts就可以直接填寫這個組名:

---
- name: talk to all hosts just so we can learn about them
  hosts: all
  tasks:
    - name: Classify hosts depending on their OS distribution
      group_by:
        key: os_{{ ansible_facts['distribution'] }}

# now just on the CentOS hosts...
- hosts: os_CentOS
  gather_facts: False
  tasks:
    - # tasks that only happen on CentOS go here

通過 group_by 模塊動態爲主機添加了分組,還可以事先創建好組變量文件,這些組變量也是會生效的。

Using Roles

官網有各種花式技巧:
https://docs.ansible.com/ansible/latest/user_guide/playbooks_reuse_roles.html#using-roles

各種花式技巧:

  • 把role寫在tasks中,這是一種新的語法格式。可以在引入role的前後執行別的task
  • 使用絕對路徑引入role
  • 引入role的同時,定義變量
  • 有條件的導入role,上面roles的多平臺就是這麼用的
  • 爲角色添加標籤。使用場景我還沒想明白

角色依賴關係

通過角色依賴,可以在使用角色時自動加入其它角色。角色依賴定義在 meta/main.yml 文件中的 dependencies 下,內容包含當前角色的依賴角色和依賴角色的參數列表。
配置文件示例:

---
dependencies:
  - role: common
    vars:
      some_parameter: 3
  - role: apache
    vars:
      apache_port: 80
  - role: postgres
    vars:
      dbname: blarg
      other_parameter: 12

角色的依賴關係,僅僅是meta文件中的一個key,也就是dependencies。別的key還有allow_duplicates,這個是定義角色可以重複執行任務的。其他key暫時在文檔中沒有出現。

角色中嵌入模塊和插件

在目錄結構中,列出了角色使用的基本目錄名稱。這裏的自定義模塊和插件也是放在roles目錄下的角色名子目錄中的。
新的目錄結構:

roles/
    webservers/
        tasks/
        defaults/
        meta/
        library/
            module1
            module2
        filter_plugins
            filter1
            filter2

在webservers角色下添加了自定義模塊,目錄名稱使用library。
ansible的插件有很多種,這裏是在webserver角色下,爲filter插件添加了兩個自定義功能的文件。

項目目錄結構

這裏是 Ansible 官方最佳實踐中推薦的一個工作目錄的結構:

production                # 生產環境的 inventory 文件
stage                     # 試運行環境的 inventory 文件

group_vars/               # 定義組變量
   group1
   group2
host_vars/                # 定義主機變量
   hostname1
   hostname2

library/                  # 如果有自定義的模塊,放在這裏(可選)
module_utils/             # 如果有自定義的模塊中要使用的工具,放在這裏(可選)
filter_plugins/           # 如果有自定義的過濾插件,放在這裏(可選)

site.yml                  # 主 playbook
webservers.yml            # Web 服務器的 playbook
dbservers.yml             # 數據庫服務器的 playbook

roles/                    # role 文件存放目錄
    common/               # common 角色目錄
        tasks/            #
            main.yml      #  task 入口
        handlers/         #
            main.yml      #  handler 入口
        templates/        #  存放模板文件
            ntp.conf.j2   #
        files/            #  存放文件資源
            bar.txt       #
            foo.sh        #
        vars/             #
            main.yml      #  定義角色使用的變量
        defaults/         #
            main.yml      #  定義角色默認變量
        meta/             #
            main.yml      #  定義角色依賴

    webservers/           # webservers 角色目錄,不展開了

這裏的自定義模塊和插件是放在項目目錄下的,不會自動生效。
library的默認值: ~/.ansible/plugins/modules:/usr/share/ansible/plugins/modules
filter_plugins的默認值: ~/.ansible/plugins/filter:/usr/share/ansible/plugins/filter
官方文檔的這篇裏可以查到很多有關Ansible設置相關的信息,包括每個變量在配置文件中的名稱,在環境變量中的名稱,以及變量的默認值。
https://docs.ansible.com/ansible/latest/reference_appendices/config.html

可以去修改 ansible.cfg 配置文件,也可以利用默認的家目錄中的位置,創建軟連接。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章