系统角色的使用和角色构建创建方式
1. 控制执行顺序
对于playbook中的每个play,任务按照任务列表中的顺序来执行。执行完所有任务后,将执行任务通知的处理程序。
在角色添加到play中后,角色任务将添加到任务列表的开头。如果play中包含第二个角色,其任务列表添加到第一个角色之后。
角色处理程序添加到play中的方式与角色任务添加到play中相同。每个play定义一个处理程序列表。角色处理程序先添加到处理程序列表,后跟play的handlers部分中定义的任何处理程序。
在某些情形中,可能需要在角色之前执行一些play任务。若要支持这样的情形,可以为play配置pre_tasks部分。列在此部分中的所有任务将在执行任何角色之前执行。如果这些任务中有任何一个通知了处理程序,则这些处理程序任务也在角色或普通任务之前执行。
此外,play也支持post_tasks关键字。这些任务在play的普通任务和它们通知的任何处理程序运行之后执行。
以下play演示了一个带有pre_tasks、roles、tasks、post_tasks和handlers的示例。一个play中通常不会同时包含所有这些部分。
[root@ansible ansible]# vim httpd.tar/main.yml
---
- hosts: 192.168.200.154
vars:
timesync_ntp_servers:
- hostname: time1.aliyun.com
iburst: yes
pre_tasks:
- debug:
msg: 'pre-tasks'
notify: my handler
roles:
- timesync
tasks:
- debug:
msg: 'first task'
notify: my handler
post_tasks:
- debug:
msg: 'post-task'
notify: my handler
handlers:
- name: my handler
debug:
msg: running my handler
//执行成功
[root@ansible ansible]# ansible-playbook httpd.tar/main.yml
PLAY [192.168.200.154] *********************************************************
TASK [Gathering Facts] *********************************************************
ok: [192.168.200.154]
TASK [debug] *******************************************************************
ok: [192.168.200.154] => {
"msg": "pre-tasks"
}
TASK [timesync : Set version specific variables] *******************************
ok: [192.168.200.154]
TASK [timesync : Populate service facts] ***************************************
ok: [192.168.200.154]
TASK [Set variable `timesync_services` with filtered uniq service names] *******
ok: [192.168.200.154]
TASK [Check that variable 'timesync_services' is defined] **********************
ok: [192.168.200.154] => {
"changed": false,
"msg": "All assertions passed"
}
TASK [timesync : Check if only NTP is needed] **********************************
ok: [192.168.200.154]
TASK [timesync : Check if single PTP is needed] ********************************
skipping: [192.168.200.154]
TASK [timesync : Check if both NTP and PTP are needed] *************************
skipping: [192.168.200.154]
TASK [timesync : Determine current NTP provider] *******************************
ok: [192.168.200.154]
TASK [timesync : Select NTP provider] ******************************************
ok: [192.168.200.154]
TASK [timesync : Install chrony] ***********************************************
ok: [192.168.200.154]
TASK [timesync : Install ntp] **************************************************
skipping: [192.168.200.154]
TASK [timesync : Install linuxptp] *********************************************
skipping: [192.168.200.154]
TASK [timesync : Gather package facts] *****************************************
ok: [192.168.200.154]
TASK [timesync : Run phc_ctl on PTP interface] *********************************
skipping: [192.168.200.154]
TASK [timesync : Check if PTP interface supports HW timestamping] **************
skipping: [192.168.200.154]
TASK [timesync : Generate chrony.conf file] ************************************
ok: [192.168.200.154]
TASK [timesync : Generate chronyd sysconfig file] ******************************
ok: [192.168.200.154]
TASK [timesync : Generate ntp.conf file] ***************************************
skipping: [192.168.200.154]
TASK [timesync : Generate ntpd sysconfig file] *********************************
skipping: [192.168.200.154]
TASK [timesync : Generate ptp4l.conf file] *************************************
skipping: [192.168.200.154]
TASK [timesync : Generate ptp4l sysconfig file] ********************************
skipping: [192.168.200.154]
TASK [timesync : Generate phc2sys sysconfig file] ******************************
skipping: [192.168.200.154]
TASK [timesync : Generate timemaster.conf file] ********************************
skipping: [192.168.200.154]
TASK [timesync : Update network sysconfig file] ********************************
ok: [192.168.200.154]
TASK [timesync : Disable chronyd] **********************************************
skipping: [192.168.200.154]
TASK [timesync : Disable ntpd] *************************************************
skipping: [192.168.200.154]
TASK [timesync : Disable ntpdate] **********************************************
skipping: [192.168.200.154]
TASK [timesync : Disable sntp] *************************************************
skipping: [192.168.200.154]
TASK [timesync : Disable ptp4l] ************************************************
skipping: [192.168.200.154]
TASK [timesync : Disable phc2sys] **********************************************
skipping: [192.168.200.154]
TASK [timesync : Disable timemaster] *******************************************
skipping: [192.168.200.154]
TASK [timesync : Enable chronyd] ***********************************************
ok: [192.168.200.154]
TASK [timesync : Enable ntpd] **************************************************
skipping: [192.168.200.154]
TASK [timesync : Enable ptp4l] *************************************************
skipping: [192.168.200.154]
TASK [timesync : Enable phc2sys] ***********************************************
skipping: [192.168.200.154]
TASK [timesync : Enable timemaster] ********************************************
skipping: [192.168.200.154]
TASK [debug] *******************************************************************
ok: [192.168.200.154] => {
"msg": "first task"
}
TASK [debug] *******************************************************************
ok: [192.168.200.154] => {
"msg": "post-task"
}
PLAY RECAP *********************************************************************
192.168.200.154 : ok=17 changed=0 unreachable=0 failed=0 skipped=23 rescued=0 ignored=0
在上例中,每个部分中都执行debug任务来通知my handler处理程序。my handler任务执行了三次:
在执行了所有pre_tasks任务后
在执行了所有角色任务和tasks部分中的任务后
在执行了所有post_tasks后
除了将角色包含在play的roles部分中外,也可以使用普通任务将角色添加到play中。使用include_role模块可以动态包含角色,使用import_role模块则可静态导入角色。
以下playbook演示了如何通过include_role模块来利用任务包含角色。
[root@ansible ansible]# vim httpd.tar/main.yml
---
- hosts: 192.168.200.154
vars:
timesync_ntp_servers:
- hostname: time1.aliyun.com
iburst: yes
power: true
tasks:
- name:
debug:
msg: 'first task'
- name: timesync
include_role:
name: timesync
handlers:
- name: my handler
debug:
msg: running my handler
oot@ansible ansible]# ansible-playbook httpd.tar/main.yml
PLAY [192.168.200.154] *********************************************************
TASK [Gathering Facts] *********************************************************
ok: [192.168.200.154]
TASK [debug] *******************************************************************
ok: [192.168.200.154] => {
"msg": "first task"
}
TASK [timesync] ****************************************************************
TASK [timesync : Set version specific variables] *******************************
ok: [192.168.200.154]
TASK [timesync : Populate service facts] ***************************************
ok: [192.168.200.154]
TASK [Set variable `timesync_services` with filtered uniq service names] *******
ok: [192.168.200.154]
TASK [Check that variable 'timesync_services' is defined] **********************
ok: [192.168.200.154] => {
"changed": false,
"msg": "All assertions passed"
}
TASK [timesync : Check if only NTP is needed] **********************************
ok: [192.168.200.154]
TASK [timesync : Check if single PTP is needed] ********************************
skipping: [192.168.200.154]
TASK [timesync : Check if both NTP and PTP are needed] *************************
skipping: [192.168.200.154]
TASK [timesync : Determine current NTP provider] *******************************
ok: [192.168.200.154]
TASK [timesync : Select NTP provider] ******************************************
ok: [192.168.200.154]
TASK [timesync : Install chrony] ***********************************************
ok: [192.168.200.154]
TASK [timesync : Install ntp] **************************************************
skipping: [192.168.200.154]
TASK [timesync : Install linuxptp] *********************************************
skipping: [192.168.200.154]
TASK [timesync : Gather package facts] *****************************************
ok: [192.168.200.154]
TASK [timesync : Run phc_ctl on PTP interface] *********************************
skipping: [192.168.200.154]
TASK [timesync : Check if PTP interface supports HW timestamping] **************
skipping: [192.168.200.154]
TASK [timesync : Generate chrony.conf file] ************************************
ok: [192.168.200.154]
TASK [timesync : Generate chronyd sysconfig file] ******************************
ok: [192.168.200.154]
TASK [timesync : Generate ntp.conf file] ***************************************
skipping: [192.168.200.154]
TASK [timesync : Generate ntpd sysconfig file] *********************************
skipping: [192.168.200.154]
TASK [timesync : Generate ptp4l.conf file] *************************************
skipping: [192.168.200.154]
TASK [timesync : Generate ptp4l sysconfig file] ********************************
skipping: [192.168.200.154]
TASK [timesync : Generate phc2sys sysconfig file] ******************************
skipping: [192.168.200.154]
TASK [timesync : Generate timemaster.conf file] ********************************
skipping: [192.168.200.154]
TASK [timesync : Update network sysconfig file] ********************************
ok: [192.168.200.154]
TASK [timesync : Disable chronyd] **********************************************
skipping: [192.168.200.154]
TASK [timesync : Disable ntpd] *************************************************
skipping: [192.168.200.154]
TASK [timesync : Disable ntpdate] **********************************************
skipping: [192.168.200.154]
TASK [timesync : Disable sntp] *************************************************
skipping: [192.168.200.154]
TASK [timesync : Disable ptp4l] ************************************************
skipping: [192.168.200.154]
TASK [timesync : Disable phc2sys] **********************************************
skipping: [192.168.200.154]
TASK [timesync : Disable timemaster] *******************************************
skipping: [192.168.200.154]
TASK [timesync : Enable chronyd] ***********************************************
ok: [192.168.200.154]
TASK [timesync : Enable ntpd] **************************************************
skipping: [192.168.200.154]
TASK [timesync : Enable ptp4l] *************************************************
skipping: [192.168.200.154]
TASK [timesync : Enable phc2sys] ***********************************************
skipping: [192.168.200.154]
TASK [timesync : Enable timemaster] ********************************************
skipping: [192.168.200.154]
PLAY RECAP *********************************************************************
192.168.200.154 : ok=15 changed=0 unreachable=0 failed=0 skipped=23 rescued=0 ignored=0
注意:
include_role模块是在Ansible 2.3中新增的,而import_role模块则是在Ansible 2.4中新增的
2. timesync角色示例
---
- hosts: mysql
vars:
timesync_ntp_servers:
- hostname: time1.aliyun.com
iburst: yes
power: true
pre_tasks:
- debug:
msg: 'k1'
changed_when: power
notify:
- h1
roles:
- timesync
tasks:
- debug:
msg: 'k2'
changed_when: power
notify:
- h1
post_tasks:
- debug:
msg: 'k3'
changed_when: power
notify:
- h1
handlers:
- name: h1
debug:
msg: h2
3. SELINUX角色示例
rhel-system-roles.selinux角色可以简化SELinux配置设置的管理。它通过利用SELinux相关的Ansible模块来实施。与自行编写任务相比,使用此角色的优势是它能让用户摆脱编写这些任务的职责。取而代之,用户将为角色提供变量以对其进行配置,且角色中维护的代码将确保应用用户需要的SELinux配置。
此角色可以执行的任务包括:
设置enforcing或permissive模式
对文件系统层次结构的各部分运行restorecon
设置SELinux布尔值
永久设置SELinux文件上下文
设置SELinux用户映射
---
- hosts: 192.168.200.154
vars:
selinux_state: disabled
tasks:
- name: Apply SELinux role
block:
- name: role use
include_role:
name: selinux
rescue:
- name:
fail:
when: not selinux_reboot_required
- name: Restart managed host
reboot:
- name: Reapply SELinux role to complete changes
include_role:
name: selinux
---
- hosts: 192.168.200.154
vars:
PORT: 82
selinux_state: enforcing
selinux_ports:
- ports: '82'
setype: 'http_port_t'
proto: 'tcp'
state: 'present'
tasks:
- name:
yum:
name: httpd
state: present
- name:
include_role:
name: selinux
- name:
service:
name: httpd
state: started
4. 角色创建流程
在Ansible中创建角色不需要特别的开发工具。创建和使用角色包含三个步骤:
创建角色目录结构
定义角色内容
在playbook中使用角色
5. 创建角色目录结构
默认情况下,Ansible在Ansible Playbook所在目录的roles子目录中查找角色。这样,用户可以利用playbook和其他支持文件存储角色。
如果Ansible无法在该位置找到角色,它会按照顺序在Ansible配置设置roles_path所指定的目录中查找。此变量包含要搜索的目录的冒号分隔列表。此变量的默认值为:
~/.ansible/roles:/usr/share/ansible/roles:/etc/ansible/roles
这允许用户将角色安装到由多个项目共享的系统上。例如,用户可能将自己的角色安装在自己的主目录下的~/.ansible/roles子目录中,而系统可能将所有用户的角色安装在/usr/share/ansible/roles目录中。
每个角色具有自己的目录,采用标准化的目录结构。例如,以下目录结构包含了定义motd角色的文件。
[root@ansible syb]# mkdir defaults handlers files tasks vars meta templetes
[root@ansible syb]# cd ..
[root@ansible roles]# tree
.
└── syb
├── defaults
├── files
├── handlers
├── meta
├── tasks
├── templetes
└── vars
8 directories, 0 files
使用ansible命令
[root@ansible roles]# ansible-galaxy init myroles
- Role myroles was created successfully
[root@ansible roles]# cd myroles/
[root@ansible myroles]# tree
.
├── 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
README.md提供人类可读的基本角色描述、有关如何使用该角色的文档和示例,以及其发挥作用所需要满足的任何非Ansible要求。
meta子目录包含一个main.yml文件,该文件指定有关模块的作者、许可证、兼容性和依赖项的信息。
files子目录包含固定内容的文件,而templates子目录则包含使用时可由角色部署的模板。
其他子目录中可以包含main.yml文件,它们定义默认的变量值、处理程序、任务、角色元数据或变量,具体取决于所处的子目录。
如果某一子目录存在但为空,如本例中的handlers,它将被忽略。如果某一角色不使用功能,则其子目录可以完全省略。例如,本例中的vars子目录已被省略。