对于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@centos8 ansible]# cat httpd.tar/main.yml --- - hosts: 192.168.197.135 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@centos8 ansible]# ansible-playbook httpd.tar/main.yml PLAY [192.168.197.135] ********************************************************* TASK [Gathering Facts] ********************************************************* ok: [192.168.197.135] TASK [debug] ******************************************************************* ok: [192.168.197.135] => { "msg": "pre-tasks" } TASK [timesync : Set version specific variables] ******************************* ok: [192.168.197.135] TASK [timesync : Populate service facts] *************************************** ok: [192.168.197.135] TASK [Set variable `timesync_services` with filtered uniq service names] ******* ok: [192.168.197.135] TASK [Check that variable 'timesync_services' is defined] ********************** ok: [192.168.197.135] => { "changed": false, "msg": "All assertions passed" } TASK [timesync : Check if only NTP is needed] ********************************** ok: [192.168.197.135]
太长不做过多表示
在上例中,每个部分中都执行debug任务来通知my handler处理程序。my handler任务执行了三次:
在执行了所有pre_tasks任务后
在执行了所有角色任务和tasks部分中的任务后
在执行了所有post_tasks后
除了将角色包含在play的roles部分中外,也可以使用普通任务将角色添加到play中。使用include_role模块可以动态包含角色,使用import_role模块则可静态导入角色。
以下playbook演示了如何通过include_role模块来利用任务包含角色。
[root@centos8 ansible]# cat httpd.tar/main.yml --- - hosts: 192.168.197.135 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@centos8-1 ansible]# ansible-playbook httpd.tar/main.yml PLAY [192.168.197.135] ********************************************************* TASK [Gathering Facts] ********************************************************* ok: [192.168.197.135 ] TASK [debug] ******************************************************************* ok: [192.168.197.135 ] => { "msg": "first task" }
注意:
include_role模块是在Ansible 2.3中新增的,而import_role模块则是在Ansible 2.4中新增的
rhel-system-roles.selinux角色可以简化SELinux配置设置的管理。它通过利用SELinux相关的Ansible模块来实施。与自行编写任务相比,使用此角色的优势是它能让用户摆脱编写这些任务的职责。取而代之,用户将为角色提供变量以对其进行配置,且角色中维护的代码将确保应用用户需要的SELinux配置。
此角色可以执行的任务包括:
设置enforcing或permissive模式
对文件系统层次结构的各部分运行restorecon
设置SELinux布尔值
永久设置SELinux文件上下文
设置SELinux用户映射
有时候,SELinux角色必须确保重新引导受管主机,以便能够完整应用其更改。但是,它本身从不会重新引导主机。如此一来,用户便可以控制重新引导的处理方式。
其工作方式为,该角色将一个布尔值变量selinux_reboot_required设为True,如果需要重新引导,则失败。你可以使用block/rescure结构来从失败中恢复,具体操作为:如果该变量未设为true,则让play失败,如果值是true,则重新引导受管主机并重新运行该角色。Play中的块看起来应该类似于:
[root@centos8 ansible]# cat httpd.tar/main.yml --- - hosts: 192.168.197.135 tasks: - name: Apply SELinux role block: - name: role user include_role: name: selinux rescue: - name: Check for failure for other reasons than required reboot fail: when: not selinux_reboot_required - name: Restart managed host reboot: - name: Reapply SELinux role to complete changes include_role: name: selinux
[root@localhost ~]# getenforce Disabled
用于配置rhel-system-roles.selinux角色的变量的详细记录位于其README.md文件中。以下示例演示了使用此角色的一些方法。
selinux_state变量设置SELinux的运行模式。它可以设为enforcing、permissive或disabled。如果未设置,则不更改模式。
[root@centos8 ansible]# cat /etc/selinux/config # This file controls the state of SELinux on the system. # SELINUX= can take one of these three values: # enforcing - SELinux security policy is enforced. # permissive - SELinux prints warnings instead of enforcing. # disabled - No SELinux policy is loaded. SELINUX=enforcing # SELINUXTYPE= can take one of these three values: # targeted - Targeted processes are protected, # minimum - Modification of targeted policy. Only selected processes are protected. # mls - Multi Level Security protection. SELINUXTYPE=targeted
selinux_booleans变量取一个要调整的SELinux布尔值的列表作为值。列表中的每一项是变量的散列/字典:布尔值的name、state(它应是on还是off),以及该设置是否应在重新引导后persistent。
[root@centos8 ansible]# cat httpd.tar/httpd1.yml --- - hosts: 192.168.197.135 vars: PORT: 82 tasks: - name: install httpd yum: name: httpd state: present - name: config httpd template: src: /etc/ansible/files/httpd.conf.j2 dest: /etc/httpd/conf/httpd.conf - name: serivce httpd service: name: httpd state: started
[root@centos8 ansible]# ansible-playbook httpd.tar/httpd1.yml PLAY [192.168.197.135 ] ********************************************************* TASK [Gathering Facts] ********************************************************* ok: [192.168.197.135 ] TASK [install httpd] *********************************************************** ok: [192.168.197.135 ] TASK [config httpd] ************************************************************ changed: [192.168.197.135 ] TASK [serivce httpd] *********************************************************** changed: [192.168.197.135 ] PLAY RECAP ********************************************************************* 192.168.197.135 : ok=4 changed=2 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
selinux_ports变量取应当具有特定SELinux类型的端口的列表作为值。
selinux_ports: - ports: '82' setype: 'http_port_t' proto: 'tcp' state: 'present'
注意:想要设置上面这些内容,selinux状态必须是enforcing,不然的话设置不了。
角色创建流程
在Ansible中创建角色不需要特别的开发工具。创建和使用角色包含三个步骤:
创建角色目录结构
定义角色内容
在playbook中使用角色
默认情况下,Ansible在Ansible Playbook所在目录的roles子目录中查找角色。这样,用户可以利用playbook和其他支持文件存储角色。
如果Ansible无法在该位置找到角色,它会按照顺序在Ansible配置设置roles_path所指定的目录中查找。此变量包含要搜索的目录的冒号分隔列表。此变量的默认值为:
[root@centos8 ~]# ls /usr/share/ansible/roles/ linux-system-roles.certificate linux-system-roles.crypto_policies linux-system-roles.ha_cluster linux-system-roles.kdump linux-system-roles.kernel_settings
这允许用户将角色安装到由多个项目共享的系统上。例如,用户可能将自己的角色安装在自己的主目录下的~/.ansible/roles子目录中,而系统可能将所有用户的角色安装在/usr/share/ansible/roles目录中。
每个角色具有自己的目录,采用标准化的目录结构。例如,以下目录结构包含了定义motd角色的文件。
[root@centos8 ansible]# tree roles/ roles/ ├── php.tar │ ├── php-7.2.8.tar.xz │ ├── php.sh │ └── php.yml └── timesync ├── ansible_pytest_extra_requirements.txt ├── COPYING ├── custom_requirements.txt ├── defaults │ └── main.yml ├── handlers │ └── main.yml ├── library │ └── timesync_provider.sh ├── meta │ └── main.yml ├── molecule_extra_requirements.txt ├── pylint_extra_requirements.txt ├── pylintrc ├── pytest_extra_requirements.txt ├── README.html ├── README.md ├── tasks │ └── main.yml ├── templates │ ├── chrony.conf.j2 │ ├── chronyd.sysconfig.j2 │ ├── ntp.conf.j2 │ ├── ntpd.sysconfig.j2 │ ├── phc2sys.sysconfig.j2 │ ├── ptp4l.conf.j2 │ ├── ptp4l.sysconfig.j2 │ └── timemaster.conf.j2 ├── tests │ ├── inventory.yaml.j2 │ ├── provision.fmf │ ├── roles │ ├── tests_chrony.yml │ ├── tests_default_vars.yml │ ├── tests_default_wrapper.yml │ ├── tests_default.yml │ ├── tests_ntp_provider1.yml │ ├── tests_ntp_provider2.yml │ ├── tests_ntp_provider3.yml │ ├── tests_ntp_provider4.yml │ ├── tests_ntp_provider5.yml │ ├── tests_ntp_provider6.yml │ ├── tests_ntp_ptp.yml │ ├── tests_ntp.yml │ ├── tests_ptp_multi.yml │ └── tests_ptp_single.yml ├── tox.ini └── vars ├── CentOS_6.yml ├── CentOS_9.yml ├── default.yml ├── Fedora_33.yml ├── main.yml ├── RedHat_6.yml └── RedHat_9.yml 11 directories, 49 files
README.md提供人类可读的基本角色描述、有关如何使用该角色的文档和示例,以及其发挥作用所需要满足的任何非Ansible要求。
meta子目录包含一个main.yml文件,该文件指定有关模块的作者、许可证、兼容性和依赖项的信息。
files子目录包含固定内容的文件,而templates子目录则包含使用时可由角色部署的模板。
其他子目录中可以包含main.yml文件,它们定义默认的变量值、处理程序、任务、角色元数据或变量,具体取决于所处的子目录。
如果某一子目录存在但为空,如本例中的handlers,它将被忽略。如果某一角色不使用功能,则其子目录可以完全省略。例如,本例中的vars子目录已被省略。
可以使用标准Linux命令创建新角色所需的所有子目录和文件。此外,也可以通过命令行实用程序来自动执行新角色创建过程。
ansible-galaxy命令行工具可用于管理Ansible角色,包括新角色的创建。用户可以运行ansible-galaxy init来创建新角色的目录结构。指定角色的名称作为命令的参数,该命令在当前工作目录中为新角色创建子目录。
[root@centos8 ansible]# ls ansible.cfg hosts httpd.tar roles files hosts_facts mysql.tar [root@centos8 ansible]# cd roles/ [root@centos8 roles]# ansible-galaxy init my_new_role - Role my_new_role was created successfully [root@centos8 roles]# ls my_new_role/ defaults handlers README.md templates vars files meta tasks tests [root@centos8-1 roles]#