一 role 簡介
在ansible中,role是將playbook分割為多個文件的主要機制,大大簡化了復雜的playbook的編寫,同時已與復用
role各個目錄的作用及可用文件
- files:存放由copy或script等模塊調用的文件
- tempaltes:Jinja2模板文件
- tasks:至少應該包含一個名為main.yml的文件,其定義了此角色的任務列表,些文件可以使用include包含其它的位於此目錄中的task文件
- handlers:至少包含一個main.yml文件,用於定義此角色用到的各handler,在handler中使用include包含的其他handler文件也應該位於此目錄
- vars:應當包含一個main.yml文件,用於定義此角色用到的變量,擁有比較高的優先級,僅次於命令行
- meta:應當包含一個main.yml文件,用於定義此角色的特殊設定及依賴關系等
- default:為當前角色設定默認變量時使用些目錄,包含一個main.yml文件,變量的優先級最低
二 創建role步驟
1 創建以role命名的目錄
2 在role下創建一個任務目錄,定義角色
3 分別創建 defaults vars files templates tasks handlers meta tests的目錄,用不到的目錄,可以不創建,也可以創建空目錄
4 在playbook中調用各文件
[root@node1 ansible]# cd roles/
[root@node1 roles]# vim ../ansible.cfg
roles_path = /etc/ansible/roles
[root@node1 roles]# mkdir systeminit
[root@node1 systeminit]# mkdir defaults vars files templates tasks handlers meta tests
[root@node1 systeminit]# touch {defaults,vars,files,templates,tasks,handlers,meta}/main.yml
[root@node1 systeminit]# tree ./
./
├── defaults
│ └── main.yml
├── files
│ └── main.yml
├── handlers
│ └── main.yml
├── meta
│ └── main.yml
├── tasks
│ └── main.yml
├── templates
│ └── main.yml
├── tests
└── vars
└── main.yml
把前面tasks里面的文件,按照roles放到對應的位置,刪掉多余的文件
drwxr-xr-x 2 root root 41 May 2 20:12 files drwxr-xr-x 2 root root 42 May 2 20:13 handlers drwxr-xr-x 2 root root 85 May 2 20:13 tasks drwxr-xr-x 2 root root 22 May 2 19:56 templates [root@node1 systeminit]# tree ./ ./ ├── files │ └── resolv.conf ├── handlers │ ├── handlers.yml │ └── main.yml ├── tasks │ ├── dns.yml │ ├── host.yml │ ├── main.yml │ ├── nginx.yml │ └── ntp.yml └── templates └── main.yml
開始調用個文件配置
[root@node1 systeminit]# vim tasks/main.yml
- include_tasks: file: host.yml - include_tasks: file: dns.yml #- include_tasks: # file: ntp.yml
[root@node1 systeminit]# vim handlers/main.yml
- include_tasks: file: handlers.yml
tasks文件中,默認情況下,src就是指向files下的文件,files可以省略
[root@node1 systeminit]# vim tasks/dns.yml
- name: modify resolv.conf copy: src: resolv.conf dest: /etc/resolv.conf - name: /etc/resolvconf/base copy: src: resolv.conf dest: /etc/resolv.conf when: ansible_distribution == "Ubuntu"
創建一個palybook.yml
[root@node1 roles]# vim playbook.yml
- hosts: demo2.example.com
roles:
- systeminit
執行
[root@node1 roles]# ansible-playbook playbook.yml
PLAY [demo2.example.com] ************************************************************************************************************************** TASK [Gathering Facts] **************************************************************************************************************************** ok: [demo2.example.com] TASK [systeminit : include_tasks] ***************************************************************************************************************** included: /etc/ansible/roles/systeminit/tasks/host.yml for demo2.example.com TASK [systeminit : modify num to 0] *************************************************************************************************************** ok: [demo2.example.com] TASK [systeminit : modify hostname] *************************************************************************************************************** ok: [demo2.example.com] TASK [systeminit : include_tasks] ***************************************************************************************************************** included: /etc/ansible/roles/systeminit/tasks/dns.yml for demo2.example.com TASK [systeminit : modify resolv.conf] ************************************************************************************************************ ok: [demo2.example.com] TASK [systeminit : /etc/resolvconf/base] ********************************************************************************************************** skipping: [demo2.example.com] PLAY RECAP **************************************************************************************************************************************** demo2.example.com : ok=6 changed=0 unreachable=0 failed=0 skipped=1 rescued=0 ignored=0
三 role中變量設置
3.1 使用default定義變量
[root@node1 systeminit]# vim defaults/main.yml
testvars:
users:
bob:
name: bob
gender: male
alice:
name: alice
gender: female
[root@node1 systeminit]# vim tasks/host.yml
- name: modify num to 0 set_fact: num: 0 - name: modify hostname hostname: name: test.example.com - name: print testvars debug: msg: "{{ testvars }}"
執行
[root@node1 roles]# ansible-playbook playbook.yml
ok: [demo2.example.com] => { #打印出了testvar的值 "msg": { "users": { "alice": { "gender": "female", "name": "alice" }, "bob": { "gender": "male", "name": "bob" } } } }
3.2 使用命令行的變量
[root@node1 roles]# ansible-playbook -e "{'testvars':'aaa'}" playbook.yml
TASK [systeminit : print testvars] **************************************************************************************************************** ok: [demo2.example.com] => { "msg": "aaa" }
3.3 在palybbok.yml文件直接定義變量
[root@node1 roles]# vim playbook.yml
- hosts: demo2.example.com roles: - role: systeminit vars: testvars: bbbbtest
[root@node1 roles]# ansible-playbook playbook.yml
TASK [systeminit : print testvars] **************************************************************************************************************** ok: [demo2.example.com] => { "msg": "bbbbtest" }
創建第二個role
[root@node1 roles]# mkdir -p nginx/{defaults,handlers,files,tasks}
[root@node1 roles]# vim nginx/tasks/nginx.yml
- name: install nginx yum: name: nginx state: present #- name: mpdify nginx.conf # template: # src: templates/nginx.conf.j2 # dest: /etc/nginx/nginx.conf # notify: # - restart nginx - name: start nginx systemd: name: nginx state: started enabled: yes - name: print testvars debug: msg: "{{ testvars }}"
[root@node1 roles]# vim nginx/tasks/main.yml
- include_tasks: file: nginx.yml
[root@node1 roles]# vim nginx/defaults/main.yml
testvars:
user:
natasha:
name: natasha
gender: female
[root@node1 roles]# vim playbook.yml
- hosts: demo2.example.com roles: - role: systeminit vars: testvars: bbbbtest - role: nginx
[root@node1 roles]# ansible-playbook playbook.yml
PLAY [demo2.example.com] ************************************************************************************************************************** TASK [Gathering Facts] **************************************************************************************************************************** ok: [demo2.example.com] TASK [systeminit : include_tasks] ***************************************************************************************************************** included: /etc/ansible/roles/systeminit/tasks/host.yml for demo2.example.com TASK [systeminit : modify num to 0] *************************************************************************************************************** ok: [demo2.example.com] TASK [systeminit : modify hostname] *************************************************************************************************************** ok: [demo2.example.com] TASK [systeminit : print testvars] **************************************************************************************************************** ok: [demo2.example.com] => { "msg": "bbbbtest" } TASK [systeminit : include_tasks] ***************************************************************************************************************** included: /etc/ansible/roles/systeminit/tasks/dns.yml for demo2.example.com TASK [systeminit : modify resolv.conf] ************************************************************************************************************ ok: [demo2.example.com] TASK [systeminit : /etc/resolvconf/base] ********************************************************************************************************** skipping: [demo2.example.com] TASK [nginx : include_tasks] ********************************************************************************************************************** included: /etc/ansible/roles/nginx/tasks/nginx.yml for demo2.example.com TASK [nginx : install nginx] ********************************************************************************************************************** ok: [demo2.example.com] TASK [nginx : start nginx] ************************************************************************************************************************ ok: [demo2.example.com] TASK [nginx : print testvars] ********************************************************************************************************************* ok: [demo2.example.com] => { "msg": "bbbbtest" } PLAY RECAP **************************************************************************************************************************************** demo2.example.com : ok=11 changed=0 unreachable=0 failed=0 skipped=1 rescued=0 ignored=0
這是因為在playbook.yml定義的變量都是全局的,優先級高於所有角色的default.yml定義的變量
3.4 在var中定義自己的變量
若要使nginx使用自己的變量,就把變量定義在vars的目錄中
[root@node1 roles]# mv nginx/defaults nginx/vars
[root@node1 roles]# ansible-playbook playbook.yml
PLAY [demo2.example.com] ************************************************************************************************************************** TASK [Gathering Facts] **************************************************************************************************************************** ok: [demo2.example.com] TASK [systeminit : include_tasks] ***************************************************************************************************************** included: /etc/ansible/roles/systeminit/tasks/host.yml for demo2.example.com TASK [systeminit : modify num to 0] *************************************************************************************************************** ok: [demo2.example.com] TASK [systeminit : modify hostname] *************************************************************************************************************** ok: [demo2.example.com] TASK [systeminit : print testvars] **************************************************************************************************************** ok: [demo2.example.com] => { "msg": "bbbbtest" } TASK [systeminit : include_tasks] ***************************************************************************************************************** included: /etc/ansible/roles/systeminit/tasks/dns.yml for demo2.example.com TASK [systeminit : modify resolv.conf] ************************************************************************************************************ ok: [demo2.example.com] TASK [systeminit : /etc/resolvconf/base] ********************************************************************************************************** skipping: [demo2.example.com] TASK [nginx : include_tasks] ********************************************************************************************************************** included: /etc/ansible/roles/nginx/tasks/nginx.yml for demo2.example.com TASK [nginx : install nginx] ********************************************************************************************************************** ok: [demo2.example.com] TASK [nginx : start nginx] ************************************************************************************************************************ ok: [demo2.example.com] TASK [nginx : print testvars] ********************************************************************************************************************* ok: [demo2.example.com] => { "msg": { "user": { "natasha": { "gender": "female", "name": "natasha" } } } }
也可以定義到當前role中
[root@node1 roles]# vim playbook.yml
- hosts: demo2.example.com roles: - {role: systeminit,testvars: "bbbtest"} - role: nginx
[root@node1 roles]# mv nginx/vars nginx/defaults
[root@node1 roles]# ansible-playbook playbook.yml
TASK [nginx : include_tasks] ********************************************************************************************************************** included: /etc/ansible/roles/nginx/tasks/nginx.yml for demo2.example.com TASK [nginx : install nginx] ********************************************************************************************************************** ok: [demo2.example.com] TASK [nginx : start nginx] ************************************************************************************************************************ ok: [demo2.example.com] TASK [nginx : print testvars] ********************************************************************************************************************* ok: [demo2.example.com] => { #nginx依然打印出自己的defaut的變量 "msg": { "user": { "natasha": { "gender": "female", "name": "natasha" } } } }
引用role,也可以添加條件
- hosts: webserver roles: - {role: some_role,when: "ansible_os_family == 'Redhat' "}
3.5 pre_tasks和post_tasks操作
在執行一個role之前和之后,可以使用這兩個實現
- name: deplay webserver hosts: webserver vars_files: - secrets.yml pre_tasks: - name: update yum cache yum: update_cache=yes roles: - role: apache database_host: {{ hostvars.db.ansible_eth0.ipv4.address }} domains: - example.com - www.example.com post_tasks: - name: print something shell: echo "The role have been update "
3.6 role的依賴
[root@node1 roles]# vim systeminit/tasks/pkgs.yml
- name: install development tools yum : name: "{{ pkgs.name }}"
引入:
- include_tasks: file: host.yml - include_tasks: file: dns.yml - include_tasks: file: pkgs.yml #- include_tasks: # file: ntp.yml
設置變量
[root@node1 roles]# mkdir systeminit/vars
[root@node1 roles]# vim systeminit/vars/main.yml
pkgs: name: - gcc - make - git
在nginx定義依賴
[root@node1 roles]# mkdir nginx/meta
[root@node1 roles]# vim nginx/meta/main.yml
dependencies:
- role: systeminit
[root@node1 roles]# vim playbook.yml
- hosts: demo2.example.com
roles:
- role: nginx
[root@node1 roles]# ansible-playbook playbook.yml
PLAY [demo2.example.com] ************************************************************************************************************************** TASK [Gathering Facts] **************************************************************************************************************************** ok: [demo2.example.com] TASK [systeminit : include_tasks] ***************************************************************************************************************** included: /etc/ansible/roles/systeminit/tasks/host.yml for demo2.example.com TASK [systeminit : modify num to 0] *************************************************************************************************************** ok: [demo2.example.com] TASK [systeminit : modify hostname] *************************************************************************************************************** ok: [demo2.example.com] TASK [systeminit : print testvars] **************************************************************************************************************** ok: [demo2.example.com] => { "msg": { "users": { "alice": { "gender": "female", "name": "alice" }, "bob": { "gender": "male", "name": "bob" } } } } TASK [systeminit : include_tasks] ***************************************************************************************************************** included: /etc/ansible/roles/systeminit/tasks/dns.yml for demo2.example.com TASK [systeminit : modify resolv.conf] ************************************************************************************************************ ok: [demo2.example.com] TASK [systeminit : /etc/resolvconf/base] ********************************************************************************************************** skipping: [demo2.example.com] TASK [systeminit : include_tasks] ***************************************************************************************************************** included: /etc/ansible/roles/systeminit/tasks/pkgs.yml for demo2.example.com TASK [systeminit : install development tools] ***************************************************************************************************** ok: [demo2.example.com] TASK [nginx : include_tasks] ********************************************************************************************************************** included: /etc/ansible/roles/nginx/tasks/nginx.yml for demo2.example.com TASK [nginx : install nginx] ********************************************************************************************************************** ok: [demo2.example.com] TASK [nginx : start nginx] ************************************************************************************************************************ ok: [demo2.example.com] TASK [nginx : print testvars] ********************************************************************************************************************* ok: [demo2.example.com] => { "msg": { "user": { "natasha": { "gender": "female", "name": "natasha" } } } } PLAY RECAP **************************************************************************************************************************************** demo2.example.com : ok=13 changed=0 unreachable=0 failed=0 skipped=1 rescued=0 ignored=0
先執行systeminit,在執行nginx,是因為nginx依賴於systeminit執行
四 社區版roles
https://galaxy.ansible.com/geerlingguy/nginx
用這里就可以獲取到作者已經寫好的roles
下載
[root@node1 roles]# ansible-galaxy install geerlingguy.nginx
- changing role geerlingguy.nginx from 2.7.0 to unspecified - downloading role 'nginx', owned by geerlingguy - downloading role from https://github.com/geerlingguy/ansible-role-nginx/archive/2.7.0.tar.gz - extracting geerlingguy.nginx to /root/.ansible/roles/geerlingguy.nginx - geerlingguy.nginx (2.7.0) was installed successfully
[root@node1 roles]# ansible-galaxy --help
usage: ansible-galaxy [-h] [--version] [-v] TYPE ... Perform various Role and Collection related operations. positional arguments: TYPE collection Manage an Ansible Galaxy collection. role Manage an Ansible Galaxy role. optional arguments: --version show program's version number, config file location, configured module search path, module location, executable location and exit -h, --help show this help message and exit -v, --verbose verbose mode (-vvv for more, -vvvv to enable connection debugging) [root@node1 roles]#
[root@node1 roles]# cp -r /root/.ansible/roles/geerlingguy.nginx ./
[root@node1 roles]# ls -l
drwxr-xr-x 9 root root 177 May 2 21:55 geerlingguy.nginx drwxr-xr-x 7 root root 76 May 2 21:22 nginx -rw-r--r-- 1 root root 54 May 2 21:37 playbook.yml drwxr-xr-x 8 root root 113 May 2 21:18 systeminit
[root@node1 roles]# ansible-galaxy init apache
[root@node1 roles]# ls -l
drwxr-xr-x 10 root root 154 May 2 21:56 apache drwxr-xr-x 9 root root 177 May 2 21:55 geerlingguy.nginx drwxr-xr-x 7 root root 76 May 2 21:22 nginx -rw-r--r-- 1 root root 54 May 2 21:37 playbook.yml drwxr-xr-x 8 root root 113 May 2 21:18 systeminit
[root@node1 roles]# tree apache/
apache/
├── defaults
│ └── main.yml
├── files
├── handlers
│ └── main.yml
├── meta
│ └── main.yml
├── README.md
├── tasks
│ └── main.yml
├── templates
├── tests
│ ├── inventory
│ └── test.yml
└── vars
└── main.yml
列出安裝別人的role
[root@node1 roles]# ansible-galaxy list
# /root/.ansible/roles - geerlingguy.nginx, 2.7.0 # /usr/share/ansible/roles # /etc/ansible/roles - nginx, (unknown version) - geerlingguy.nginx, 2.7.0 - apache, (unknown version)
查看一個role的完整信息
[root@node1 roles]# ansible-galaxy info geerlingguy.nginx
Role: geerlingguy.nginx/ description: Nginx installation for Linux, FreeBSD and OpenBSD. active: True commit: 87ecb1127f62c5c2f9c901f44594c5445aeb75d4 commit_message: Add probot/stale configuration to repository for stale issues. commit_url: https://api.github.com/repos/geerlingguy/ansible-role-nginx/git/commits/87ecb1127f62c5c2f9c901f44594c5445aeb75d4 company: Midwestern Mac, LLC created: 2014-03-07T14:57:09.348940Z dependencies: [] download_count: 4130883 forks_count: 357 galaxy_info: author: geerlingguy company: Midwestern Mac, LLC galaxy_tags: ['development', 'web', 'nginx', 'reverse', 'proxy', 'load', 'balancer'] license: license (BSD, MIT) min_ansible_version: 2.4 platforms: [{'name': 'EL', 'versions': [6, 7]}, {'name': 'D .......
移除
[root@node1 roles]# ansible-galaxy remove apache
- apache is not installed, skipping.
五 調試ansible
1 運行前檢查
當我們在運行ansible-playbook時,使用--check選項時,將不會對被控端做出任何更改,而是通過模擬的方式 執行所有的tasks,以用於檢查playbook運行的的狀態
ansible-playbook with_items.yml --check
2.再運行palybook時,使用--diff選項配合--check,可以用於檢查本次執行playbook,相較上一次產生了那些改變
[root@node1 ansible]# ansible-playbook --check --diff with_items.yml
[root@node1 ansible]# ansible-playbook --check --diff --limit demo2.example.com with_items.yml
[root@node1 ansible]# ansible-playbook --syntax-check with_items.yml
3 有時候,我們在檢測模式下,運行play時,希望某個play總是運行,可以使用always_run
tasks: - name: this task is run even is check mode command: /something/to/run/ --even-in-check-mode always_run: yes
如果一個tasks包含有always_run和when,當when為false時,如果always_run時true,任務依然會執行
debug調試:
- name: install nginx yum: name: nginx state: present tags: install_nginx register: result ignore_errors: true - debug: msg: "{{ result }}" failed_when: result is failed
assert模塊:
assert會在指定的條件不符合,返回錯誤並退出
#當目標主機沒有eth1網卡足額playbook失敗 tasks: - name: assert ansbile_bond0 is not dfined assert: that: ansible_bond0 is defined
再執行playbook時,插入assert在我們設定的條件不成立;立即失敗,調試很有用
博主聲明:本文的內容來源主要來自譽天教育晏威老師,由本人實驗完成操作驗證,需要的博友請聯系譽天教育(http://www.yutianedu.com/),獲得官方同意或者晏老師(https://www.cnblogs.com/breezey/)本人同意即可轉載,謝謝!