How to use and build system roles

How to use and build system roles
1. Control execution sequence
For each play in the playbook, tasks are executed in the order in the task list. After all tasks are executed, the handler of the task notification will be executed

After the role is added to the play, the role task will be added to the beginning of the task list. If the play contains a second role, its task list is added after the first role.

Role handlers are added to play in the same way that role tasks are added to play. Each play defines a list of handlers. The role handler is first added to the handler list, followed by any handler defined in the handlers section of play.

In some cases, you may need to perform some play tasks before the role. To support this scenario, you can configure pre for play_ Tasks section. All tasks listed in this section will be performed before performing any roles. If any of these tasks notifies the handler, these handler tasks are also executed before the role or normal task.

In addition, play also supports post_tasks keyword. These tasks are executed after the normal tasks of play and any handlers they notify run.

The following play demonstrates a with pre_tasks,roles,tasks,post_ Examples of tasks and handlers. A play usually does not contain all of these parts at the same time.
 

[root@master ansible]# cat httpd.tar/main.yml 
--- 
- hosts: 192.168.72.137
  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@master ansible]# 




[root@master ansible]# ansible-playbook httpd.tar/main.yml / / execution succeeds

PLAY [192.168.72.137] *********************************************************

TASK [Gathering Facts] *********************************************************
ok: [192.168.72.137]

TASK [debug] *******************************************************************
ok: [192.168.72.137] => {
    "msg": "pre-tasks"
}

TASK [timesync : Set version specific variables] *******************************
ok: [192.168.72.137]

TASK [timesync : Populate service facts] ***************************************
ok: [192.168.72.137]

TASK [Set variable `timesync_services` with filtered uniq service names] *******
ok: [192.168.72.137]

TASK [Check that variable 'timesync_services' is defined] **********************
ok: [192.168.72.137] => {
    "changed": false,
    "msg": "All assertions passed"
}

TASK [timesync : Check if only NTP is needed] **********************************
ok: [192.168.72.137]

TASK [timesync : Check if single PTP is needed] ********************************
skipping: [192.168.72.137]

TASK [timesync : Check if both NTP and PTP are needed] *************************
skipping: [192.168.72.137]

TASK [timesync : Determine current NTP provider] *******************************
ok: [192.168.72.137]

TASK [timesync : Select NTP provider] ******************************************
ok: [192.168.72.137]

TASK [timesync : Install chrony] ***********************************************
ok: [192.168.72.137]

TASK [timesync : Install ntp] **************************************************
skipping: [192.168.72.137]

TASK [timesync : Install linuxptp] *********************************************
skipping: [192.168.72.137]

TASK [timesync : Gather package facts] *****************************************
ok: [192.168.72.137]

TASK [timesync : Run phc_ctl on PTP interface] *********************************
skipping: [192.168.72.137]

TASK [timesync : Check if PTP interface supports HW timestamping] **************
skipping: [192.168.72.137]

TASK [timesync : Generate chrony.conf file] ************************************
ok: [192.168.72.137]

TASK [timesync : Generate chronyd sysconfig file] ******************************
ok: [192.168.72.137]

TASK [timesync : Generate ntp.conf file] ***************************************
skipping: [192.168.72.137]

TASK [timesync : Generate ntpd sysconfig file] *********************************
skipping: [192.168.72.137]

TASK [timesync : Generate ptp4l.conf file] *************************************
skipping: [192.168.72.137]

TASK [timesync : Generate ptp4l sysconfig file] ********************************
skipping: [192.168.72.137]

TASK [timesync : Generate phc2sys sysconfig file] ******************************
skipping: [192.168.72.137]

TASK [timesync : Generate timemaster.conf file] ********************************
skipping: [192.168.72.137]

TASK [timesync : Update network sysconfig file] ********************************
ok: [192.168.72.137]

TASK [timesync : Disable chronyd] **********************************************
skipping: [192.168.72.137]

TASK [timesync : Disable ntpd] *************************************************
skipping: [192.168.72.137]

TASK [timesync : Disable ntpdate] **********************************************
skipping: [192.168.72.137]

TASK [timesync : Disable sntp] *************************************************
skipping: [192.168.72.137]

TASK [timesync : Disable ptp4l] ************************************************
skipping: [192.168.72.137]

TASK [timesync : Disable phc2sys] **********************************************
skipping: [192.168.72.137]

TASK [timesync : Disable timemaster] *******************************************
skipping: [192.168.72.137]

TASK [timesync : Enable chronyd] ***********************************************
ok: [192.168.72.137]

TASK [timesync : Enable ntpd] **************************************************
skipping: [192.168.72.137]

TASK [timesync : Enable ptp4l] *************************************************
skipping: [192.168.72.137]

TASK [timesync : Enable phc2sys] ***********************************************
skipping: [192.168.72.137]

TASK [timesync : Enable timemaster] ********************************************
skipping: [192.168.72.137]

TASK [debug] *******************************************************************
ok: [192.168.72.137] => {
    "msg": "first task"
}

TASK [debug] *******************************************************************
ok: [192.168.72.137] => {
    "msg": "post-task"
}

PLAY RECAP *********************************************************************
192.168.72.137            : ok=17   changed=0    unreachable=0    failed=0    skipped=23   rescued=0    ignored=0   

[root@master ansible]# 


In the above example, the debug task is executed in each section to notify the my handler handler. The my handler task was executed three times

  1. After executing all pre_ After tasks
  2. After performing all the role tasks and tasks in the tasks section
  3. After all posts are executed_ After tasks

In addition to including roles in the roles section of the play, you can also add roles to the play using normal tasks. Use include_ The role module can dynamically include roles, using import_role module can statically import roles.

The following playbook demonstrates how to use include_role module to use tasks to include roles.

[root@master ansible]# cat httpd.tar/main.yml 
--- 
- hosts: 192.168.72.137
  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 
     
[root@master ansible]#


[root@master ansible]# ansible-playbook httpd.tar/main.yml 

PLAY [192.168.72.137] *********************************************************

TASK [Gathering Facts] *********************************************************
ok: [192.168.72.137]

TASK [debug] *******************************************************************
ok: [192.168.72.137] => {
    "msg": "first task"
}

TASK [timesync] ****************************************************************

TASK [timesync : Set version specific variables] *******************************
ok: [192.168.72.137]

TASK [timesync : Populate service facts] ***************************************
ok: [192.168.72.137]

TASK [Set variable `timesync_services` with filtered uniq service names] *******
ok: [192.168.72.137]

TASK [Check that variable 'timesync_services' is defined] **********************
ok: [192.168.72.137] => {
    "changed": false,
    "msg": "All assertions passed"
}

TASK [timesync : Check if only NTP is needed] **********************************
ok: [192.168.72.137]

TASK [timesync : Check if single PTP is needed] ********************************
skipping: [192.168.72.137]

TASK [timesync : Check if both NTP and PTP are needed] *************************
skipping: [192.168.72.137]

TASK [timesync : Determine current NTP provider] *******************************
ok: [192.168.72.137]

TASK [timesync : Select NTP provider] ******************************************
ok: [192.168.72.137]

TASK [timesync : Install chrony] ***********************************************
ok: [192.168.72.137]

TASK [timesync : Install ntp] **************************************************
skipping: [192.168.72.137]

TASK [timesync : Install linuxptp] *********************************************
skipping: [192.168.72.137]

TASK [timesync : Gather package facts] *****************************************
ok: [192.168.72.137]

TASK [timesync : Run phc_ctl on PTP interface] *********************************
skipping: [192.168.72.137]

TASK [timesync : Check if PTP interface supports HW timestamping] **************
skipping: [192.168.72.137]

TASK [timesync : Generate chrony.conf file] ************************************
ok: [192.168.100.147]

TASK [timesync : Generate chronyd sysconfig file] ******************************
ok: [192.168.100.147]

TASK [timesync : Generate ntp.conf file] ***************************************
skipping: [192.168.72.137]

TASK [timesync : Generate ntpd sysconfig file] *********************************
skipping: [192.168.72.137]

TASK [timesync : Generate ptp4l.conf file] *************************************
skipping: [192.168.72.137]

TASK [timesync : Generate ptp4l sysconfig file] ********************************
skipping: [192.168.72.137]

TASK [timesync : Generate phc2sys sysconfig file] ******************************
skipping: [192.168.72.137]

TASK [timesync : Generate timemaster.conf file] ********************************
skipping: [192.168.72.137]

TASK [timesync : Update network sysconfig file] ********************************
ok: [192.168.72.137]

TASK [timesync : Disable chronyd] **********************************************
skipping: [192.168.72.137]

TASK [timesync : Disable ntpd] *************************************************
skipping: [192.168.72.137]

TASK [timesync : Disable ntpdate] **********************************************
skipping: [192.168.72.137]

TASK [timesync : Disable sntp] *************************************************
skipping: [192.168.72.137]

TASK [timesync : Disable ptp4l] ************************************************
skipping: [192.168.72.137]

TASK [timesync : Disable phc2sys] **********************************************
skipping: [192.168.72.137]

TASK [timesync : Disable timemaster] *******************************************
skipping: [192.168.72.137]

TASK [timesync : Enable chronyd] ***********************************************
ok: [192.168.72.137]

TASK [timesync : Enable ntpd] **************************************************
skipping: [192.168.72.137]

TASK [timesync : Enable ptp4l] *************************************************
skipping: [192.168.72.137]

TASK [timesync : Enable phc2sys] ***********************************************
skipping: [192.168.72.137]

TASK [timesync : Enable timemaster] ********************************************
skipping: [192.168.72.137]

PLAY RECAP *********************************************************************
192.168.72.137            : ok=15   changed=0    unreachable=0    failed=0    skipped=23   rescued=0    ignored=0   

[root@master ansible]# 

2.selinux role instance
rhel-system-roles.selinux role can simplify the management of SELinux configuration settings. It is implemented by using the Ansible module related to SELinux. The advantage of using this role over writing tasks yourself is that it frees users from the responsibility of writing these tasks. Instead, the user will provide variables to the role to configure it, and the code maintained in the role will ensure that the SELinux configuration required by the user is applied.

The tasks that this role can perform include:

  1. Set the enforcing or permissive mode
  2. Run restorecon on parts of the file system hierarchy
  3. Set SELinux Boolean
  4. Permanently set SELinux file context
  5. Set SELinux user mapping

Sometimes, the SELinux role must ensure that the managed host is rebooted so that its changes can be fully applied. However, it never reboots the host itself. In this way, the user can control how the reboot is handled.

It works by placing a boolean variable SELinux in the role_ reboot_ Required is set to true and fails if a reboot is required. You can use the block / resume structure to recover from failures. The specific operations are: if the variable is not set to true, let play fail; if the value is true, reboot the managed host and re run the role. The blocks in play should look like:
 

[root@master ansible]# cat httpd.tar/main.yml 
---
- hosts: 192.168.72.137
  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@master ansible]# 


[root@localhost ~]# getenforce    
Disabled
[root@localhost ~]# 

3. Configure selinux role


Used to configure RHEL system roles The detailed record of the variables of the SELinux role is located in its readme MD file. The following example demonstrates some ways to use this role.

selinux_ The state variable sets the running mode of SELinux. It can be set to enforced, permitted, or disabled. If not set, the mode is not changed
 

[root@master 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
[root@master ansible]# 

selinux_ The boolean variable takes a list of SELinux Boolean values to be adjusted as the value. Each item in the list is a hash / dictionary of variables: the name and state of the Boolean value (should it be on or off), and whether the setting should persist after reboot

[root@master ansible]# cat httpd.tar/httpd1.yml 
---
- hosts: 192.168.72.137
  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@master ansible]# 


[root@master ansible]# ansible-playbook httpd.tar/httpd1.yml 

PLAY [192.168.72.137] *********************************************************

TASK [Gathering Facts] *********************************************************
ok: [192.168.72.137]

TASK [install httpd] ***********************************************************
ok: [192.168.72.137]

TASK [config httpd] ************************************************************
changed: [192.168.72.137]

TASK [serivce httpd] ***********************************************************
changed: [192.168.72.137]

PLAY RECAP *********************************************************************
192.168.72.137            : ok=4    changed=2    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

selinux_ The ports variable takes the list of ports that should have a specific SELinux type as its value.

selinux_ports:
  - ports: '82'
    setype: 'http_port_t'
    proto: 'tcp'
    state: 'present'

4. Create roles

Role creation process
Creating roles in Ansible does not require special development tools. Creating and using roles involves three steps:

Create role directory structure
Define role content
Using roles in playbook
By default, Ansible finds roles in the roles subdirectory of the directory where Ansible Playbook is located. In this way, users can use playbook and other supporting files to store roles.
If Ansible cannot find roles in this location, it will set roles in Ansible configuration in order_ Path. This variable contains a colon delimited list of directories to search. The default value of this variable is:

[root@master ~]# 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
linux-system-roles.logging
linux-system-roles.metrics
linux-system-roles.nbde_client
linux-system-roles.nbde_server
linux-system-roles.network
linux-system-roles.postfix
linux-system-roles.selinux
linux-system-roles.ssh
linux-system-roles.sshd
linux-system-roles.storage
linux-system-roles.timesync
linux-system-roles.tlog
linux-system-roles.vpn
rhel-system-roles.certificate
rhel-system-roles.crypto_policies
rhel-system-roles.ha_cluster
rhel-system-roles.kdump
rhel-system-roles.kernel_settings
rhel-system-roles.logging
rhel-system-roles.metrics
rhel-system-roles.nbde_client
rhel-system-roles.nbde_server
rhel-system-roles.network
rhel-system-roles.postfix
rhel-system-roles.selinux
rhel-system-roles.ssh
rhel-system-roles.sshd
rhel-system-roles.storage
rhel-system-roles.timesync
rhel-system-roles.tlog
rhel-system-roles.vpn
[root@master ~]# 

This allows users to install roles on systems shared by multiple projects. For example, users may install their roles in ~ /. In their home directory In the accessible / roles subdirectory, and the system may install the roles of all users in the / usr / share / accessible / roles directory.

Each role has its own directory and adopts a standardized directory structure. For example, the following directory structure contains the files that define the motd role.
 

[root@master 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
[root@master ansible]# 

5. Create role framework

You can use standard Linux commands to create all subdirectories and files required for a new role. In addition, you can automate the new role creation process through the command-line utility.

The Ansible Galaxy command line tool can be used to manage Ansible roles, including the creation of new roles. Users can run Ansible Galaxy init to create a directory structure for new roles. Specify the name of the role as an argument to the command, which creates a subdirectory for the new role in the current working directory.
 

[root@ansible opt]# cd roles/
[root@ansible roles]# ansible-galaxy init my_new_role
- Role my_new_role was created successfully
[root@ansible roles]# ls my_new_role/
defaults  handlers  README.md  templates  vars
files     meta      tasks      tests

Keywords: Linux

Added by beedie on Mon, 03 Jan 2022 17:49:50 +0200