The inclusion and import of ansible, the structure of roles and the use of system roles

Posted by lukatchikm on Sat, 01 Jan 2022 04:46:38 +0100

1. Usage included in import

1.1 include or import files

Ansible can use two operations to bring content into the playbook. You can include content or import content

  • Inclusion is a dynamic operation. During playbook operation, Ansible processes the content when it arrives
  • Importing content is a static operation. Before the run starts, Ansible preprocesses the imported content when it initially parses the playbook

1.2 import plyabook

​ import_ The playbook directive allows an external file containing a play list to be imported into playbook. In other words, you can import one or more additional playbook files into the main playbook file

Since the imported content is a complete playbook, import_ The playbook function can only be used at the top level of playbook, not in play. If you import multiple playbooks, they are imported and run sequentially

A simple example of importing a primary playbook with two additional playbooks is shown below

---
- hosts: all
  
- name: install
  import_playbook: install.yml
  
- name: start
  import_playbook: start.yml

1.3 include and import tasks

1.3.1 import task file

You can use import_ The tasks function statically imports the task file into play in the playbook.

When importing a task file, the tasks in the file will be inserted directly when the playbook is parsed.

Import in Playbook_ The location of tasks controls where tasks are inserted and the order in which multiple imports are run

---
- hosts: all
  tasks:
    - name: install
      import_tasks: install.yml
  
    - name: start
      import_tasks: start.yml
  • Note: import_tasks and import_playbook is at different levels; import_playbook is the same level as tasks; import_tasks are subtasks of tasks

When importing a task file, the tasks in the file will be inserted directly when the playbook is parsed. Due to import_tasks statically import tasks when parsing playbook, so it has some impact on its working mode

  • Using import_ When using the tasks function, conditional statements such as when set during import will be applied to each imported task
  • Cannot use loop for import_tasks function
  • If you use variables to specify the name of the file to import, you cannot use host or group manifest variables

1.3.2 documents containing tasks

You can use include_ The tasks function dynamically imports task files into play in the playbook

---
- hosts: all
  tasks:
    - name: install
      imclude_tasks: install.yml

Before the play runs and this part of the play arrives, include_ The tasks feature does not handle the content in the playbook

The order in which Playbook content is processed affects how it works with task features

  • Use include_ When using the tasks function, conditional statements such as when set during inclusion will determine whether the task is included in play
  • If you run ansible playbook -- List tasks to list the tasks in the playbook, the tasks in the included task file will not be displayed
  • In contrast, import_ The tasks function does not list the tasks imported into the task file, but lists the tasks in the imported task file
  • You cannot use ansible playbook -- start at task to start a playbook from a task already contained in a task file
  • You cannot use the notify statement to trigger a handler name in an included task file. The handler can be triggered in the main playbook that contains the entire task file, in which case all tasks in the included file will run

2. Define variables for external play and tasks

Using Ansible's import and include functions to merge play or tasks in external files into playbook greatly enhances the ability to reuse tasks and playbook in Ansible environment

[root@ansible ansible]# cat playbook/install.yml 
- name: install
  yum:
    name: "{{ package }}"
    state: latest
[root@ansible ansible]# cat playbook/test.yml 
---
- hosts: all
  vars:
    package: httpd 
  tasks:
    - import_tasks: install.yml

Use the same technology to make play files more reusable. When the play file is merged into the playbook, variables are passed to execute the play

[root@ansible ansible]# cat playbook/install.yml 
---
- name: install
  hosts: all
  vars:
    package: httpd
  tasks: 
    - name: install
      yum:
        name: "{{ package }}"
        state: latest
[root@ansible ansible]# cat playbook/test.yml 
- name: install
  import_playbook: install.yml

3. Construct an ansible playbook using roles

3.1 what are roles

The Ansible role provides a way for users to more easily reuse Ansible code in a common way.

We can package all tasks, variables, files, templates, and other resources required to provision infrastructure or deploy applications in a standardized directory structure

Simply copy the roles from one project to another by copying the relevant directories. Then, just call the role from a play to execute it

With the help of well written roles, you can pass variables to adjust their behavior from the playbook, and set all site related host names, IP addresses, user names, or other specific details required locally

Ansible has the following advantages:

  1. Roles can group content to easily share code with others
  2. You can write roles to define the basic elements of a system type: a Web server, a database server, a Git repository, or for other purposes
  3. Roles make larger projects easier to manage
  4. Roles can be developed in parallel by different administrators

In addition to writing, using, reusing, and sharing roles yourself, you can also obtain roles from other sources. Some roles have been included in the RHEL system roles package, and users can also obtain many roles supported by the community from the Ansible Galaxy website

  • Using RHEL system roles packages to use roles

    //View local roles on the control node
    [root@ansible ansible]# ls /usr/share/ansible/roles/
    
    //Install RHEL system roles
    [root@ansible ansible]# yum -y install rhel-system-roles
    
    //View local roles again
    [root@ansible ansible]# ls /usr/share/ansible/roles/
    linux-system-roles.certificate      linux-system-roles.ssh             rhel-system-roles.metrics
    linux-system-roles.crypto_policies  linux-system-roles.sshd            rhel-system-roles.nbde_client
    linux-system-roles.ha_cluster       linux-system-roles.storage         rhel-system-roles.nbde_server
    linux-system-roles.kdump            linux-system-roles.timesync        rhel-system-roles.network
    linux-system-roles.kernel_settings  linux-system-roles.tlog            rhel-system-roles.postfix
    linux-system-roles.logging          linux-system-roles.vpn             rhel-system-roles.selinux
    linux-system-roles.metrics          rhel-system-roles.certificate      rhel-system-roles.ssh
    linux-system-roles.nbde_client      rhel-system-roles.crypto_policies  rhel-system-roles.sshd
    linux-system-roles.nbde_server      rhel-system-roles.ha_cluster       rhel-system-roles.storage
    linux-system-roles.network          rhel-system-roles.kdump            rhel-system-roles.timesync
    linux-system-roles.postfix          rhel-system-roles.kernel_settings  rhel-system-roles.tlog
    linux-system-roles.selinux          rhel-system-roles.logging          rhel-system-roles.vpn
    [root@ansible ansible]#
    
  • Get many roles supported by the community from Ansible Galaxy website, please stamp: https://galaxy.ansible.com/

3.2 ansible role structure

The Ansible role is defined by the standardized structure of subdirectories and files

The top-level directory defines the name of the role itself.

The files are sorted into subdirectories, which are named according to the purpose of each file in the role, such as tasks and handlers. The files and templates subdirectories contain files referenced by tasks in other YAML files

example:

head.yml
main.yml
roles/
    common/
        tasks/
        handlers/
        files/
        templates/
        vars/
        defaults/
        meta/
    webservers/
        tasks/
        defaults/
        meta/

Ansible role subdirectory

Subdirectoryfunction
defaultsMain. In this directory The YML file contains default values for role variables that can be overridden when using roles. These variables have low priority and should be changed and customized in play.
filesThis directory contains static files referenced by role tasks.
handlersMain. In this directory The YML file contains the handler definition for the role.
metaMain. In this directory The YML file contains role related information such as author, license, platform, and optional role dependencies.
tasksMain. In this directory The YML file contains the task definition of the role.
templatesThis directory contains Jinja2 templates referenced by role tasks.
testsThis directory can contain the manifest and the name test The playbook of YML can be used to test roles.
varsMain. In this directory The YML file defines variable values for roles. These variables are usually used for internal purposes of roles. These variables have higher priority and should not be changed when used in playbook.
  • Note: not every role has all of these directories.

3.3 defining variables and default values

3.3.1 defining variables

Role variables are created by creating vars / main with key value pairs in the role directory hierarchy YML file (key value pair: key = value)

These role variables are referenced in the role YAML file: * * {{VAR_NAME}}, * * these variables have high priority and cannot be overwritten by the list variables

3.3.2 defining default values

Default variables allow you to set default values for variables that can be used in play to configure roles or customize their behavior

They do this by creating defaults / main with key value pairs in the role directory hierarchy YML file

The default variable has the lowest priority of any available variable. They can easily be overridden by any other variable, including the manifest variable

These variables are designed to allow users to accurately customize or control the actions it will perform when writing a play using the role. They can be used to provide roles with the information they need to properly configure or deploy certain objects

In vars / main YML or defaults / main Specific variables are defined in YML, but not both. When you intend to override the value of a variable, you should use the default variable

be careful:

  1. Roles should not contain site-specific data. They should never contain any secrets, such as passwords or private keys
  2. This is because roles should be generic, reusable and freely shared. Site specific details should not be hard coded into roles
  3. Confidentiality should be provided to the role through other means. This is one reason why users may want to set role variables when calling roles
  4. The role variable set in play can provide a secret or point to an Ansible Vault encrypted file containing the secret.

3.4 using the ansible role in palybook

3.4.1 role call

For each specified role, role tasks, role handlers, role variables, and role dependencies are imported into the playbook in order

Any copy, script, template, or include in the role_ tasks/import_ Tasks tasks can reference related files, templates or task files in roles without relative or absolute path names

Ansible will look for them in the files, templates, or tasks subdirectories of the role, respectively

[root@ansible ansible]# cat playbook/main.yml
---
- hosts: all
  roles:
    - role: roles/role_one
    - role: roles/role_two
[root@ansible ansible]#

Important:

  1. Embedded role variables (role parameters) have very high priority. They will override most other variables
  2. Be careful not to reuse the name of any role variable embedded anywhere else in the play, because the value of the role variable will override the manifest variable and vars in any play

3.5 control execution sequence

3.5.1 sequence control

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.

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

Adding role handlers to play is the same as adding role tasks to play. Each play defines a handler list; The role handler is added to the handler list first, followed by any handler 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 executed before performing any role

  • If any of these tasks notifies the handler, these handler tasks are also executed before the role or normal task

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

- name: Play to illustrate order of execution
  hosts: remote.example.com
  pre_tasks:
    - debug:
      msg: 'pre-task'
      notify: my handler
  roles:
    - role1
  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

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.

    be careful:

    • include_ The role module is added in Ansible 2.3, while import_ The role module is added in Ansible 2.4

3.6 time synchronization role example

The playbook of time synchronization role in RHEL system is RHEL system roles timesync

Time synchronization roles can be used for the first time in RHEL system roles timesync/README. MD view the help documents used; It contains examples of use

Demo example:

//Write playbook
[root@ansible ansible]# cat playbook/time.yml 
---
- name: time
  hosts: all
  vars:
    timesync_ntp_servers:
      - hostname: time1.aliyun.com
        iburst: yes
    timezone: UTC

  roles:
    - rhel-system-roles.timesync
[root@ansible ansible]#
//Viewing managed host time
[root@apache ~]# date
Sun Aug  1 23:53:31 EDT 2021
//Execute play
[root@ansible ansible]# ansible-playbook playbook/time.yml
//View again

3.7 SELINUX role example

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:

  • Set the enforcing or permissive mode
  • Run restorecon on parts of the file system hierarchy
  • Set SELinux Boolean
  • Permanently set SELinux file context
  • Set SELinux user mapping

3.7.1 calling SELinux role

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:

- name: Apply SELinux role
  block:
    - include_role:
      name: rhel-system-roles.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: rhel-system-roles.selinux

3.7.2 configuring SELinux roles

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.

selinux_state: enforcing

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 be persistent after reboot.

This example will httpd_enable_homedirs is permanently set to on:

selinux_booleans:
  - name: 'httpd_enable_homedirs'
    state: 'on'
    persistent: 'yes'

selinux_ The fcontext variable takes a list of file contexts to be permanently set (or deleted) as its value. It works very similar to the selinux fcontent command.

The following example ensures that the policy contains a rule to set the default SELinux type of all files under / srv/www to httpd_sys_content_t.

selinux_fcontexts:
  - target: '/srv/www(/.*)?'
    setype: 'httpd_sys_content_t'
    state: 'present'

selinux_ restore_ The dirs variable specifies the list of directories on which to run restorecon:

selinux_restore_dirs:
  - /srv/www

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'

Topics: Linux