
ansible自1.2版本引入的新特性,用于層次性、結構化地組織playbook。roles能夠根據層次型結構自動裝載變量檔案、tasks以及handlers等。要使用roles隻需在playbook中使用include指定即可。簡單來講,roles就是通過分别将變量、檔案、任務、模闆以及處理器放置于單獨目錄中,并可以便捷的使用include指令将他們組織在一塊的一種機制。角色一般用于基于主機建構服務的場景中,但也可以用于建構守護程序等場景中。複雜場景建議使用角色,代碼複用度高。
一、roles簡介
ansible自1.2版本引入的新特性,用于層次性、結構化地組織playbook。roles能夠根據層次型結構自動裝載變量檔案、tasks以及handlers等。要使用roles隻需在playbook中使用include指定即可。簡單來講,roles就是通過分别将變量、檔案、任務、模闆以及處理器放置于單獨目錄中,并可以便捷的使用include指令将他們組織在一塊的一種機制。角色一般用于基于主機建構服務的場景中,但也可以用于建構守護程序等場景中。複雜場景建議使用角色,代碼複用度高。
二、roles目錄結構
roles目錄結構如上所示,每個角色以特定的層次目錄結構進行組織。其中roles/目錄下是每個角色的目錄,比如上圖有git和user兩個角色,每個角色下分别有tasks、files、vars等等目錄,files/目錄主要存放copy或scripts子產品等調用的檔案;templates/目錄主要存放template子產品查找所需要的模闆檔案;tasks/定義task,role的基本元素,至少應該包含一個名為main.yml的檔案(這個檔案就是tasks目錄的入口檔案),其他的檔案需要在此檔案中通過include進行包含;handlers/目錄主要存放觸發器任務的yml檔案,同樣它裡面至少需要有一個main.yml的入口檔案,其檔案内容通過include指令引用其下檔案;vars/目錄主要存放定義的變量檔案,同樣也需要有main.yml檔案;meta/目錄定義目前角色的特殊設定以及依賴關系,同樣這個目錄也需要有一個main.yml的入口檔案;default/設定預設變量時使用此目錄中的main.yml檔案;
通過上面的介紹,不難發現roles是依賴目錄的命名和擺放,預設tasks/main.yml是所有任務的入口,是以使用roles的過程可以了解為目錄規範化命名的過程。每個目錄下均由main.yml定義該功能的任務集,tasks/main.yml預設執行所有指定的任務。roles的調用檔案playbook_roles.yml的内容如下
---
- hosts: websers
remote_user: root
roles:
- roles_name
說明:定義好角色我們還需要寫一個調用角色的playbook.yml 用于調用角色,其中我們要寫明這個角色用于那些主機(在那些主機上執行),在遠端主機上以那個使用者來執行角色以及執行那些角色。
角色的執行方法同執行playbook一樣,我們隻需要執行定義調用角色的playbook即可;roles目錄可以擺放在/etc/ansible/ansible.cfg中"roles_path"定義路徑,也可以和入口playbook檔案存放在同級目錄,ansible沒有強制的要求,但還是建議将代碼存放在代碼集預先規劃的目錄,以便管理。
三、建立角色
通常建立role的步驟有如下4步
1)建立以roles命名的目錄
2)在roles目錄中分别建立以各自角色名稱命名的目錄,如nginx等
3)在每個角色命名的目錄中分别建立files、handlers、meta、tasks、templates、和vars目錄;若角色用不到的目錄可以是空目錄,也可以不建立
4)在playbook檔案中,調用各角色
示例:将我們之前寫的playbook修改成角色
playbook代碼以及目錄結構如下:
[root@test ~]#tree
.
├── install_nginx.yml
└── templates
├── centos6_nginx.conf.j2
└── centos7_nginx.conf.j2
1 directory, 3 files
[root@test ~]#cat install_nginx.yml
---
- hosts: websers
remote_user: root
tasks:
- name: install nginx
yum: name=nginx
- name: templates config file centos6
template: src=centos6_nginx.conf.j2 dest=/etc/nginx/nginx.conf
notify: restart nginx
when: ansible_distribution_major_version == "6"
- name: templates config file centos 7
template: src=centos7_nginx.conf.j2 dest=/etc/nginx/nginx.conf
notify: restart nginx
when: ansible_distribution_major_version == "7"
- name: start service
service: name=nginx state=started
handlers:
- name: restart nginx
service: name=nginx state=restarted
[root@test ~]#
改編成角色目錄結構以及各目錄檔案内容如下
[root@test ~]#tree
.
├── install_nginx.yml
├── nginx_role.yml
├── roles
│ └── nginx
│ ├── handlers
│ │ ├── main.yml
│ │ └── restart_nginx.yml
│ ├── tasks
│ │ ├── install_nginx.yml
│ │ ├── main.yml
│ │ ├── nginx_service.yml
│ │ └── template_config_file.yml
│ └── templates
│ ├── centos6_nginx.conf.j2
│ └── centos7_nginx.conf.j2
└── templates
├── centos6_nginx.conf.j2
└── centos7_nginx.conf.j2
6 directories, 12 files
[root@test ~]#cat roles/nginx/tasks/install_nginx.yml
- name: install nginx
yum: name=nginx
[root@test ~]#cat roles/nginx/tasks/template_config_file.yml
- name: templates config file centos6
template: src=centos6_nginx.conf.j2 dest=/etc/nginx/nginx.conf
notify: restart nginx
when: ansible_distribution_major_version == "6"
- name: tmeplates config file centos7
template: src=centos7_nginx.conf.j2 dest=/etc/nginx/nginx.conf
notify: restart nginx
when: ansible_distribution_major_version == "7"
[root@test ~]#cat roles/nginx/tasks/nginx_service.yml
- name: start service
service: name=nginx state=started
[root@test ~]#cat roles/nginx/tasks/main.yml
- include: install_nginx.yml
- include: template_config_file.yml
- include: nginx_service.yml
[root@test ~]#cat roles/nginx/handlers/restart_nginx.yml
- name: restart nginx
service: name=nginx state=restarted
[root@test ~]#cat roles/nginx/handlers/main.yml
- include: restart_nginx.yml
[root@test ~]#
說明:以上目錄編排就實作了一個簡單角色,我們把playbook内容分别用一個檔案存放,然後按照每個目錄的main.yml檔案定義的順序依次執行,這裡隻是定義好了一個角色,我們還需要寫一個playbook來調用該角色即可。
[root@test ~]#cat nginx_role.yml
---
- hosts: websers
remote_user: root
roles:
- nginx
[root@test ~]#
說明:以上就是一個調用我們剛才編排好的nginx角色的playbook。用ansilble-playbook 指令去執行以上調用角色的playbook,就相當于我們之前寫的playbook功能完全一樣。
[root@test ~]#ansible-playbook nginx_role.yml
PLAY [websers] ******************************************************************************************************
TASK [Gathering Facts] **********************************************************************************************
ok: [192.168.0.128]
ok: [192.168.0.218]
TASK [nginx : install nginx] ****************************************************************************************
changed: [192.168.0.128]
changed: [192.168.0.218]
TASK [nginx : templates config file centos6] ************************************************************************
changed: [192.168.0.128]
changed: [192.168.0.218]
TASK [nginx : tmeplates config file centos7] ************************************************************************
skipping: [192.168.0.128]
skipping: [192.168.0.218]
TASK [nginx : start service] ****************************************************************************************
changed: [192.168.0.128]
changed: [192.168.0.218]
RUNNING HANDLER [nginx : restart nginx] *****************************************************************************
changed: [192.168.0.128]
changed: [192.168.0.218]
PLAY RECAP **********************************************************************************************************
192.168.0.128 : ok=5 changed=4 unreachable=0 failed=0
192.168.0.218 : ok=5 changed=4 unreachable=0 failed=0
[root@test ~]#ansible websers -m shell -a 'ss -ntl'
192.168.0.128 | SUCCESS | rc=0 >>
State Recv-Q Send-Q Local Address:Port Peer Address:Port
LISTEN 0 128 :::80 :::*
LISTEN 0 128 *:80 *:*
LISTEN 0 128 :::22 :::*
LISTEN 0 128 *:22 *:*
192.168.0.218 | SUCCESS | rc=0 >>
State Recv-Q Send-Q Local Address:Port Peer Address:Port
LISTEN 0 128 *:35725 *:*
LISTEN 0 128 :::111 :::*
LISTEN 0 128 *:111 *:*
LISTEN 0 128 :::80 :::*
LISTEN 0 128 *:80 *:*
LISTEN 0 128 :::22 :::*
LISTEN 0 128 *:22 *:*
LISTEN 0 128 127.0.0.1:631 *:*
LISTEN 0 128 ::1:631 :::*
LISTEN 0 100 ::1:25 :::*
LISTEN 0 100 127.0.0.1:25 *:*
LISTEN 0 128 :::47546 :::*
[root@test ~]#
說明:可看到我們把playbook改編成角色同我們寫的playbook執行後的結果是一樣的,都實作了同樣的功能。
四、角色調用
方法一:寫好要調用的角色清單
---
- hosts: websers
remote_user: root
roles:
- mysql
- nginx
- memcached
說明:此方法同上面示例一樣,我們需要調用那些角色,隻需要把角色名寫在角色清單裡即可
方法二:調用角色的同時給角色傳遞變量
---
- hosts: websers
remote_user: root
roles:
- mysql
- {role: nginx,username: nginx}
- memcached
說明:此方法在調用nginx角色的同時,還給nginx角色傳遞了一個變量和值,role鍵用于指定角色名,後續可以多個k/v,用于給角色傳遞變量。
方法三:基于條件測試實作角色調用
---
- hosts: websers
remote_user: root
roles:
- mysql
- {role: nginx,username: nginx}
- {role: memcached,when: ansible_distribution_major_version == "7",username: memcached}
說明:此方法實作了當系統版本為7 的時候才調用memcached角色,換句話說隻有在目标系統版本為7 的系統才能調用memchched角色,同時它也可以向腳本傳遞變量。
五、roles playbook tags 的使用
上面角色調用的時候我們介紹了三種方式,事實上我們不僅能給角色傳遞變量,我們還可以給角色打标簽,通過執行playbook 指定标簽 就可以實作隻執行具有指定标簽的角色,如下所示
---
- hosts: websers
remote_user: root
roles:
- {role: mysql,tags: ["mysql","db"]}
- {role: marridb,tags: ["mysql","db"]}
- {role: nginx,tags: ["nginx","web"],username: nginx}
- {role: memcached,when: ansible_distribution_major_version == "7",username: memcached}
- {role: httpd,tags: ["httpd","web"]}
- {role: php,tags: php}
說明:我們在調用角色的時候,我們可以給角色打上多個标簽,其作用在于,這樣把同類角色打上相同的标簽,我們在執行其playbook的時候就可以選擇性的執行某些指定标簽的角色,比如以上我們執行标簽為“web”的角色,我們可以在執行playbook的時候用-t選項指定“web”,這樣我們就可以實作隻在目标主機上執行httpd和nginx這兩個角色的目的。如果我們給一個角色打上多個标簽需要寫成清單的形式,用中括号把多個标簽名給括起來,每個标簽之間用逗号隔開,同時需要注意的是,标簽上一個字元串,需要用引号将其引起來。
作者:Linux-1874
出處:https://www.cnblogs.com/qiuhom-1874/
本文版權歸作者和部落格園共有,歡迎轉載,但未經作者同意必須保留此段聲明,且在文章頁面明顯位置給出原文連接配接,否則保留追究法律責任的權利.