目錄
- 簡單介紹
- 舉例說明
roles可以了解為ansible的一種規範,使用這種規範編寫playbook,可以讓我們條例更加清晰,合理拆分将變量、檔案、任務、ansible其它工作等分别存儲在不同的目錄中,友善快速定位。
- 官方文檔給出的角色目錄拆解過于分散,我以“個人習慣”稍稍精簡,拿redis舉例:
roles/ # 總的角色目錄 ├── redis # redis角色目錄,目錄名代表角色名。 │ ├── defaults/main.yaml # 存放指定角色所用到的預設變量,以便在沒有設定變量值時有預設值可以使用,此檔案中定義的變量優先級是最低的。 │ ├── files # 存放執行角色所需要檔案。 │ ├── handlers/main.yaml # 當角色調用handlers時,預設會在此目錄中的main.yml檔案中查找對應的handler。 │ ├── meta/main.yaml # 存放一些中繼資料,比如作者資訊、本角色作用等等。 │ ├── tasks/main.yaml # 角色執行的任務的主要清單。 │ ├── templates # 存放角色相關的模闆檔案。 │ └── vars/main.yaml # 存放需要修改的變量,優先級較高。 └── redis.yaml # 調用角色的playbook。
- 上述規範可以不用遵守,你自己看得懂也可以;使用上面規範也不是全部目錄都必須使用,按需即可,一般情況至少會有一個tasks目錄。
- 上面目錄結構可以看出,角色調用檔案(redis.yaml)和角色目錄(redis)是同級的,這是因為角色調用檔案會從下面位置查找角色目錄:
- 同級目錄。
- 同級目錄的roles目錄。
- 目前使用者的~/.ansible/roles目錄。
- 也可以編輯/etc/ansible/ansible.cfg的“roles_path”配置項來查找角色目錄。
- 上面情況都不符合的情況也可使用絕對路徑調用角色。如: - role: "/server/ansible/roles/"
- 變量調用說明:
- 角色中定義的預設變量是全局生效的。
- 調用角色的劇本(就是上面的redis.yaml,以下内容中稱角色調用劇本)中定義的變量也是預設全局生效的,但是可以通過修改ansible.cfg配置檔案将全局屬性修改為private,見下方例1。
- 變量定義優先級:ansible-playbppk -e > 角色本身的vars/main.yaml > 角色調用劇本 > 角色本身的defaults/main.yaml > 同一個角色調用劇本中上一個調用角色的defaults/main.yaml(見例2)。
- 例1:rolrs的公/私有變量。
0 16:59:38 root@ck-ansible,172.16.2.9:/server/ops_ansible/roles # cat tr1/tasks/main.yaml - debug: msg: "hello {{ var1 }}!" 0 16:59:45 root@ck-ansible,172.16.2.9:/server/ops_ansible/roles # cat tr1/defaults/main.yaml var1: "natasha" 0 16:59:51 root@ck-ansible,172.16.2.9:/server/ops_ansible/roles # cat tr2/tasks/main.yaml - debug: msg: "hello {{ var1 }}!" 0 16:59:56 root@ck-ansible,172.16.2.9:/server/ops_ansible/roles # cat tr2/defaults/main.yaml var1: "maria" 0 16:59:59 root@ck-ansible,172.16.2.9:/server/ops_ansible/roles # cat tr.yaml - hosts: ck-node1 roles: - role: tr1 vars: var1: "selina" - role: tr2 0 17:01:59 root@ck-ansible,172.16.2.9:/server/ops_ansible/roles # ansible-playbook tr.yaml ... TASK [tr1 : debug] *********************************************************************************************************************** ok: [ck-node1] => { "msg": "hello selina!" } TASK [tr2 : debug] *********************************************************************************************************************** ok: [ck-node1] => { "msg": "hello selina!" } ... # 正常情況下,vars下的變量應該隻對tr1角色生效,但從結果上看var1變量對tr1和tr2角色都生效了,這是因為預設情況下,角色中的變量是全局生效的。想要解決這個問題,需要修改ansible配置檔案。 0 17:10:11 root@ck-ansible,172.16.2.9:/server/ops_ansible/roles # vim /etc/ansible/ansible.cfg private_role_vars = yes # 取消此行的注釋。 # 再執行就達到預想的效果了。 0 17:10:54 root@ck-ansible,172.16.2.9:/server/ops_ansible/roles # ansible-playbook tr.yaml
- 例2:變量調用優先級,五種情況對比,以tr3角色為例。
# 各角色内的tasks/main.yaml檔案保持不變。 0 18:17:00 root@ck-ansible,172.16.2.9:/server/ops_ansible/roles # cat tr1/defaults/main.yaml var1: "tr1-defaults-var1" 0 18:17:02 root@ck-ansible,172.16.2.9:/server/ops_ansible/roles # cat tr2/defaults/main.yaml var1: "tr2-defaults-var2" 0 18:17:04 root@ck-ansible,172.16.2.9:/server/ops_ansible/roles # cat tr3/defaults/main.yaml var1: "tr3-defaults-var3"
- 第一種:所有的位置都定義了v1變量,執行時使用-e參數,-e參數優先級最高。
0 18:25:08 root@ck-ansible,172.16.2.9:/server/ops_ansible/roles # cat tr3/vars/main.yaml var1: "tr3-vars-var1" 0 18:29:14 root@ck-ansible,172.16.2.9:/server/ops_ansible/roles # cat tr.yaml - hosts: ck-node1 roles: - role: tr1 - role: tr2 - role: tr3 vars: var1: "tr-var1" 0 18:30:57 root@ck-ansible,172.16.2.9:/server/ops_ansible/roles # ansible-playbook -e var1="command-e-var1" tr.yaml
- 第二種:所有的位置都定義了v1變量時,執行時不是用-e,tr3/vars/main.yaml優先級高。
0 18:31:49 root@ck-ansible,172.16.2.9:/server/ops_ansible/roles # ansible-playbook tr.yaml
- 第三種:取消定義tr3/vars/main.yaml後,角色調用劇本優先級高。
0 18:32:07 root@ck-ansible,172.16.2.9:/server/ops_ansible/roles # \rm -r tr3/vars 0 18:35:48 root@ck-ansible,172.16.2.9:/server/ops_ansible/roles # ansible-playbook tr.yaml
- 第四種:取消定義tr3/vars/main.yaml和角色調用劇本後,角色本身的defaults/main.yaml的優先級高。
0 18:38:27 root@ck-ansible,172.16.2.9:/server/ops_ansible/roles # cat tr.yaml - hosts: ck-node1 roles: - role: tr1 - role: tr2 - role: tr3 0 18:38:28 root@ck-ansible,172.16.2.9:/server/ops_ansible/roles # ansible-playbook tr.yaml
- 第五種:取消定義tr3/vars/main.yaml、角色調用劇本、tr3/defaultss/main.yaml後,同一個角色調用劇本中上一個調用角色的defaults/main.yaml優先級高。
0 18:38:31 root@ck-ansible,172.16.2.9:/server/ops_ansible/roles # \rm -r tr3/defaults 0 18:40:10 root@ck-ansible,172.16.2.9:/server/ops_ansible/roles # cat tr.yaml - hosts: ck-node1 roles: - role: tr2 - role: tr1 # 特意把tr1和tr2的調用位置換換,友善檢視效果。 - role: tr3 0 18:40:11 root@ck-ansible,172.16.2.9:/server/ops_ansible/roles # ansible-playbook tr.yaml
- 例3:預設情況下,在同一個角色調用劇本中,無法重複調用一個角色,想要解決這個問題,有兩種方式:
- 第一種方法:為角色添加allow_duplicates屬性。
# 依然使用上面的測試檔案,隻修改tr.yaml。 0 18:41:45 root@ck-ansible,172.16.2.9:/server/ops_ansible/roles # cat tr.yaml - hosts: ck-node1 roles: - role: tr1 - role: tr2 - role: tr2 # 此次調用不會顯示内容。 0 18:41:47 root@ck-ansible,172.16.2.9:/server/ops_ansible/roles # ansible-playbook tr.yaml # 為角色添加allow_duplicates屬性。 0 18:43:41 root@ck-ansible,172.16.2.9:/server/ops_ansible/roles # cat tr2/meta/main.yaml allow_duplicates: true 0 18:43:49 root@ck-ansible,172.16.2.9:/server/ops_ansible/roles # ansible-playbook tr.yaml
- 第二種方法:此種方法隻針對需要傳參的角色。
# 依然使用上面的測試檔案,删除meta。 0 18:44:02 root@ck-ansible,172.16.2.9:/server/ops_ansible/roles # \rm -r tr2/meta 0 18:44:53 root@ck-ansible,172.16.2.9:/server/ops_ansible/roles # cat tr.yaml - hosts: ck-node1 roles: - role: tr1 - role: tr2 vars: var1: peiqian - role: tr2 vars: var1: zhujiu 0 18:44:54 root@ck-ansible,172.16.2.9:/server/ops_ansible/roles # ansible-playbook tr.yaml
- 例4,部署redis。
# 這裡把調用檔案放在roles目錄同級,友善區分。 0 15:18:45 root@ck-ansible,172.16.2.9:/server/ops_ansible # tree ./ ./ ├── redis.yaml └── roles └── redis ├── defaults │ └── main.yaml ├── files │ ├── bin │ │ ├── redis-benchmark │ │ ├── redis-check-aof -> redis-server │ │ ├── redis-check-rdb -> redis-server │ │ ├── redis-cli │ │ ├── redis-sentinel -> redis-server │ │ ├── redis-server │ │ └── redis-shutdown │ ├── redis.service │ └── redis.sh ├── tasks │ ├── main.yaml │ ├── redis_common.yaml │ └── start_redis.yaml └── templates └── redis.conf.j2 # 變量定義 0 15:20:02 root@ck-ansible,172.16.2.9:/server/ops_ansible # cat roles/redis/defaults/main.yaml redis_dirs: - "/usr/local/redis/conf" - "/server/logs/redis" - "/server/data/redis" redis_files: - { src: 'files/bin',dest: '/usr/local/redis/',mode: '0755' } - { src: 'files/redis.sh',dest: '/etc/profile.d/' } - { src: 'files/redis.service',dest: '/etc/systemd/system/' } # redis依賴檔案(事先編譯好的redis相關二進制檔案)。 0 15:20:29 root@ck-ansible,172.16.2.9:/server/ops_ansible # ll roles/redis/files/bin/ 總用量 18848 -rwxr-xr-x 1 root root 4833392 5月 7 12:07 redis-benchmark lrwxrwxrwx 1 root root 12 5月 7 12:07 redis-check-aof -> redis-server lrwxrwxrwx 1 root root 12 5月 7 12:07 redis-check-rdb -> redis-server -rwxr-xr-x 1 root root 5003408 5月 7 12:07 redis-cli lrwxrwxrwx 1 root root 12 5月 7 12:07 redis-sentinel -> redis-server -rwxr-xr-x 1 root root 9450240 5月 7 12:07 redis-server -rwxr-xr-x 1 root root 1118 10月 4 20:24 redis-shutdown # redis的systemd檔案和環境變量檔案 0 15:20:32 root@ck-ansible,172.16.2.9:/server/ops_ansible # cat roles/redis/files/redis.service [Unit] Description=Redis persistent key-value database After=network.target After=network-online.target Wants=network-online.target [Service] Type=forking ExecStart=/usr/local/redis/bin/redis-server /usr/local/redis/conf/redis.conf ExecStop=/usr/local/redis/bin/redis-shutdown [Install] WantedBy=multi-user.target 0 15:22:08 root@ck-ansible,172.16.2.9:/server/ops_ansible # cat roles/redis/files/redis.sh #set redis environment export REDIS_HOME=/usr/local/redis export PATH=${REDIS_HOME}/bin:${PATH} # 配置檔案模闆 0 15:22:43 root@ck-ansible,172.16.2.9:/server/ops_ansible # cat roles/redis/templates/redis.conf.j2 daemonize yes port 6379 bind {{ ansible_host }} pidfile /usr/local/redis/redis.pid logfile /server/logs/redis/redis.log dir /server/data/redis requirepass '123456' # 任務執行。 0 15:23:26 root@ck-ansible,172.16.2.9:/server/ops_ansible # cat roles/redis/tasks/main.yaml --- - include: redis_common.yaml - include: start_redis.yaml 0 15:25:07 root@ck-ansible,172.16.2.9:/server/ops_ansible # cat roles/redis/tasks/redis_common.yaml --- - name: create services user user: name: sn_pub uid: 8888 createhome: no shell: /sbin/nologin - name: create redis dir file: path: "{{ item }}" state: directory recurse: yes owner: sn_pub group: sn_pub loop: "{{ redis_dirs }}" - name: copy redis conf.j2 template: src: templates/redis.conf.j2 dest: /usr/local/redis/conf/redis.conf - name: copy redis depend files copy: src: "{{ item.src }}" dest: "{{ item.dest }}" mode: "{{ item.mode | default(omit) }}" owner: sn_pub group: sn_pub loop: "{{ redis_files }}" - name: load redis.sh shell: source /etc/profile.d/redis.sh 0 15:25:11 root@ck-ansible,172.16.2.9:/server/ops_ansible # cat roles/redis/tasks/start_redis.yaml --- - name: start redis systemd: daemon_reload: yes name: redis state: started enabled: yes # 調用redis角色執行部署redis 0 15:25:15 root@ck-ansible,172.16.2.9:/server/ops_ansible # cat redis.yaml - hosts: ck-node1 roles: - role: redis 0 15:26:00 root@ck-ansible,172.16.2.9:/server/ops_ansible # ansible-playbook redis.yaml