1. Manage large-scale playbook tasks and simplify playbook by using roles
When a playbook contains a large service, we can split it into small files for easy management; You can also use modularity to combine multiple playbooks into one playbook, or insert a single file into the playbook. This allows you to reuse a single file in multiple projects.
2 include or import files
- Inclusion is a dynamic operation. During the playbook run, ansible will process the included content when the content arrives.
- Import is a static operation. Before the playbook runs, the imported content is preprocessed when ansible initially parses the playbook. That is, the required files have been imported into the playbook to be executed before the playbook is run.
2.1 importing playbook
- import_ The playbook command is used to import an external file containing a play list into the playbook. That is, import one or more playbooks into which playbook to execute.
Rules: Import_ The playbook command can only be used at the top level of the playbook, because we usually import a complete.
Example:
// Install httpd on node2 and change port 80 in the configuration file to 8080 [root@node1 playbook]# cat install.yml --- - hosts: noe2 tasks: - name: yum: name: httpd state: present [root@node1 playbook]# cat config.yml --- - hosts: node2 vars_files: - file/test.yml tasks: - name: config httpd template: src: file/httpd.conf.j2 dest: /etc/httpd/conf/httpd.conf [root@node1 playbook]# cat main.yml - name: install import_playbook: install.yml - name: config import_playbook: config.yml [root@node1 file]# cat test.yml port: 8080 #Listen 12.34.56.78:80 Listen {{ port }} #Listen 12.34.56.78:80 Listen 8080
2.2 import the playbook of this machine
[root@node1 playbook]# cat main.yml --- - hosts: node2 tasks: - name: open httpd service: name: httpd state: started enabled: yes - name: install import_playbook: install.yml - name: config import_playbook: config.yml [root@node1 playbook]# ansible-playbook main.yml PLAY [node2] ******************************************************************* TASK [Gathering Facts] ********************************************************* ok: [node2] TASK [open httpd] ***************************************************************** changed: [node2] [WARNING]: Could not match supplied host pattern, ignoring: noe2 PLAY [noe2] ******************************************************************** skipping: no hosts matched [WARNING]: Found variable using reserved name: port PLAY [node2] ******************************************************************* TASK [Gathering Facts] ********************************************************* ok: [node2] TASK [config httpd] ************************************************************ ok: [node2] PLAY RECAP ********************************************************************* node2 : ok=4 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
3. Import and include tasks
//Import some task files into play
stay install Only tasks are written in the file and imported into main In the file. [root@node1 playbook]# ansible-playbook main.yml PLAY [node2] ******************************************************************* TASK [Gathering Facts] ********************************************************* ok: [node2] TASK [install] ***************************************************************** ok: [node2] TASK [open httpd] ***************************************************************** ok: [node2] PLAY RECAP ********************************************************************* node2 : ok=3 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 [root@node1 playbook]# cat main.yml --- - hosts: node2 tasks: - import_tasks: /opt/playbook/install.yml - name: open httpd service: name: httpd state: started enabled: yes [root@node1 playbook]# cat install.yml - name: install yum: name: httpd state: present
3.1 include task documents
[root@node1 playbook]# cat main.yml --- - hosts: node2 tasks: - include_tasks: /opt/playbook/install.yml - name: open httpd service: name: httpd state: started enabled: yes
3.1.1 points needing attention when importing task files
- When using import_ The when condition statement set at the time of import will be applied to each imported task
- Cannot use loop for import_tasks function
- If a variable is used to specify the name of the file to be imported, the host or group list variable cannot be used, that is, the host list cannot be used as a variable.
- When you run ansible playbook -- List tasks to list the tasks in the playbook, you can see the tasks in the imported task file.
3.1.2 points needing attention when including task documents:
- Use include_ In the tasks function, you can judge when in the included file.
- If you run ansible playbook -- List tasks to list the tasks in the playbook, the task contents in the included file will not be displayed, but the tasks in the task file can be seen during import
- You cannot specify which playbook in the task file to execute first by using the ansible playbook -- start at task. The playbook follows the order and sequence.
- The notify statement cannot be used in the file containing the task file. Even if it is used, the handler will not be triggered, but it can be used in the playbook containing the whole task file.
3.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. In order to improve the reusability of task files to a greater extent, some variables can be set.
Note: if you want to define variables in a playbook file that contains multiple plays and only want to be effective for one play, you need to define a variable under the included or imported play file. If you want to be effective for all playbooks, you can define variables under hosts.
[root@node1 playbook]# ansible-playbook main.yml PLAY [node2] ******************************************************************* TASK [Gathering Facts] ********************************************************* ok: [node2] TASK [install] ***************************************************************** ok: [node2] TASK [open httpd] ***************************************************************** ok: [node2] PLAY RECAP ********************************************************************* node2 : ok=3 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 [root@node1 playbook]# cat install.yml - name: install yum: name: "{{ package }}" state: present [root@node1 playbook]# cat main.yml --- - hosts: node2 tasks: - import_tasks: /opt/playbook/install.yml vars: - package: httpd - name: open httpd service: name: httpd state: started enabled: yes
4. Describe the role structure
As playbook is written, we may find many opportunities to reuse the code in the previously abbreviated playbook.
In the actual production work, this playbook may be lengthy and complex, with many included and imported files. The Ansible role provides a way for users to 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.
4.1 Ansible has the following advantages:
- Roles can group content to easily share code with others
- 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
- Roles make larger projects easier to manage
- Roles can be developed in parallel by different administrators
Role subdirectory of ansible
Subdirectory | effect |
---|---|
defaults | The main.yml file in this directory contains the default values of role variables, which can be overridden when using roles. These variables have low priority and should be changed and customized in play. |
files | This directory contains static files referenced by roles |
handlers | The main.yml file in this directory contains the handler definition for the role |
meta | The main.yml file in this directory contains role related information such as author, license, platform, and optional role dependencies. |
tasks | The main.yml file in this directory contains the task definition of the role |
templates | This directory contains Jinja2 templates referenced by role tasks. |
tests | This directory can contain a manifest and a playbook named test.yml, which can be used to test roles. |
vars | The main.yml file in this directory defines the variable values for the role. These variables are usually used for internal purposes of roles. These variables have higher priority and should not be changed when used in playbook |
5. Control execution sequence
-
Each play in the playbook is executed from top to bottom
-
The role should be written to the beginning of the task list. If there is a second playbook, its task list needs to be added after the first role.
-
The method of adding role handlers to play is the same as that of adding role tasks to play. However, it should be noted that if there are handlers in both playbook and roles, the handlers in roles will be added first, after the handlers in playbook are added to roles.
-
In some cases, we need to execute a play task before the role task
Using pre_tasks so that you can execute the tasks you want to execute before the role task is executed.
In pre_tasks, notify and handlers in tasks are executed first. -
In pre_tasks is followed by roles role tasks, which are followed by the name of the role executing the role tasks.
The tasks and notify of role tasks are in pre_ Execute after tasks -
Tasks is to write the tasks to be executed normally. The tasks in the same tasks should be executed after the roles role tasks.
-
post_tasks are executed after tasks, post_ Similarly, tasks in tasks are executed behind tasks.
Then execute notify and handlers. -
In the handlers rule, notify is executed only once no matter how many times it appears. If pre_tasks,tasks,post_ All tasks have notify, and the last handlers will be executed once
-
So the priority from big to small is pre_ tasks>roles>tasks>post_ tasks>hangdlers.
##Reuse content with system roles
RHEL system roles
name | Role role |
---|---|
rhel-system-roles.kdump | Configure kdump crash recovery service |
rhel-system-roles.network | Configure network interface |
rhel-system-roles.selinux | Configure and manage SELinux customizations, including SELinux mode, files, and port context |
rhel-system-roles.timesync | Configure time synchronization using network time protocol or precise time protocol |
rhel-system-roles.postfix | Configure each host as a mail transfer agent using the Postfix service |
rhel-system-roles.firewalld | Configure firewall for host |
rhel-systemctl-roles.tuned | Configure tuned services to tune system performance |
6. Install system users
[root@node1 playbook]# yum -y install rhel-system-roles Updating Subscription Management repositories. Unable to read consumer identity This system is not registered to Red Hat Subscription Management. You can use subscription-manager to register. Last metadata expiration check: 0:23:47 Before, it was executed at 19:08:34 on Sunday, August 1, 2021. Dependency resolution. ========================================================================== software package framework edition Warehouse size ========================================================================== install: rhel-system-roles noarch 1.0-10.el8_1 AppStream 175 k Transaction summary ========================================================================== Install 1 package Total: 175 k Installation size: 1.1 M Download package: Run transaction check Transaction check succeeded. Run transaction test Transaction test succeeded. Run transaction In preparation : 1/1 install : rhel-system-roles-1.0-10.el8_1.noarch 1/1 verification : rhel-system-roles-1.0-10.el8_1.noarch 1/1 Installed products updated. already installed: rhel-system-roles-1.0-10.el8_1.noarch complete!
6.1 system user location
[root@node1 roles]# ls /usr/share/ansible/roles/ linux-system-roles.kdump rhel-system-roles.kdump linux-system-roles.network rhel-system-roles.network linux-system-roles.postfix rhel-system-roles.postfix linux-system-roles.selinux rhel-system-roles.selinux linux-system-roles.storage rhel-system-roles.storage linux-system-roles.timesync rhel-system-roles.timesync
6.2 accessing RHEL system role documents
The documentation for RHEL system roles is located in the / usr / share / Doc / RHEL system roles - / directory
[root@node1 roles]# ls /usr/share/doc/rhel-system-roles/ kdump network postfix selinux storage timesync
Time synchronization role
timesync_ntp_servers property
attribute | purpose |
---|---|
hostname | The host name of the NTP server to synchronize with. |
iburst | A Boolean value that enables or disables fast initial synchronization. The default is no in roles, but the attribute should usually be set to yes. |
7. Use of system roles
timesync
[root@node1 roles]# cp -a /usr/share/ansible/roles/rhel-system-roles.timesync/ ./timesync [root@node1 roles]# cat time.yml --- - hosts: node2 vars: timesync_ntp_servers: //Use the rhel-system-roles.timesync role to configure NTP time synchronization on the managed host - hostname: time.aliyun.com //hostname specifies the NTP server to be synchronized. Here we use Alibaba cloud iburst: yes //iburst here is used to enable or disable fast initial synchronization. roles: - timesync use timesync This role
7.1 SELINUX role usage
The tasks that selinux 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
Example
// Set selinu on [root@node1 roles]# cat selinux.yml --- - hosts: node2 vars: selinux_state: enforcing tasks: - name: block: - include_role: name: selinux rescue: - name: reboot fail: when: not selinux_reboot_required - name: reboot reboot: - name: config selinux include_role: name: selinux
Example:
After changing httpd to port 82 and modifying selinux rules, you can successfully access http
[root@node1 roles]# cat selinux.yml --- - hosts: node2 vars: selinux_state: enforcing selinux_ports: - ports: '82' setype: 'httpd_port_t' proto: 'tcp' state: 'present' tasks: - name: install httpd yum: name: httpd state: present - name: start httpd service: name: httpd state: started - name: selinux for httpd template: src: roles/httpd.conf.j2 dest: /etc/httpd/conf/httpd.conf - name: block: - include_role: name: selinux rescue: - name: reboot fail: when: not selinux_reboot_required - name: reboot reboot: - name: config selinux include_role: name: selinux
8. Usage of ansible Galaxy
[root@node1 roles]# ansible-galaxy search 'httpd You can search online roles [root@node1 roles]# ansible-galaxy info acandid.httpd Used to view roles essential information [root@node1 roles]# ansible-galaxy install acandid.httpd -p /ansible/roles download roles To a specific directory [root@node1 roles]# ansible-galaxy list -p roles/ List local roles
8.1 create role framework
Create a directory to create roles [root@node1 ~]# mkdir -p ~/ansible/roles Use the following command to initialize a roles [root@node1 roles]# ansible-galaxy init now_role - Role now_role was created successfully
8.2 directory structure of roles specification
catalogue | effect |
---|---|
defualts/main.yml | Define the default value of the variable with lower priority |
files | Directory where static files are stored |
handlers/main.yml | Define handlers |
meta/main.yml | Write description information such as author, version, etc |
tasks/main.yml | Where tasks are defined |
templates | Where dynamic data files are stored (template files) |
vars/main.yml | Define variables with high priority |
8.3 calling role in playbook
There are two ways:
- Create a playbook in the directory level with the role to call
- Add roles to the configuration file ansible.cfg_ Path = tell you where the role path is
8.4 role usage
Example:
Here I choose to add in the configuration file
use templates Directory to call the module fact var Call the variable in the directory and node2 Output on the host. [defaults] roles_path = /ansible/roles [root@node1 now_role]# cat templates/test.j2 this is the system {{ ansible_hostname }} date is {{ ansible_date_time.date }} var is {{ admin }} [root@node1 now_role]# cat vars/main.yml --- # vars file for now_role admin: hello roles [root@node1 roles]# cat all.yml - hosts: node2 roles: - now_role there all.yml Your files need to be now_role The directory is used at the same level. [root@node1 roles]# ansible-playbook all.yml PLAY [node2] ******************************************************************* TASK [Gathering Facts] ********************************************************* ok: [node2] TASK [now_role file] *********************************************************** changed: [node2] PLAY RECAP ********************************************************************* node2 : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 [root@node2 ~]# cat /opt/file this is the system node2 date is 2021-08-02 var is hello roles
8.5 changing role behavior through variables
By writing a character, use the default variables to change the character behavior and make it more flexible. This helps characters adapt to more application scenarios and can be used in different contexts.
The variables defined in the default directory will be overwritten:
- Defined in the manifest file as a host variable or group variable
- Variables defined in YAML files in the group, vars or host, vars directories of the playbook project.
- Defined as a variable nested in the vars keyword of play
- When the role is included in the roles keyword of play, it is defined as a variable.