Chapter 9, ansible manages large projects based on roles

1. Use roles to construct ansible playbook

As you develop more playbooks, you will find many opportunities to reuse code from previously written playbooks. Perhaps, a play that configures a MySQL database for an application can be repurposed. Configure a MySQL database for another application by utilizing a different hostname, password, and user.

但在现实中, the play can be lengthy and complex, 有许多包含或导入的文件, and tasks and handlers for managing various situations. It might not be trivial to copy all this code to another playbook.

Ansible provides a way to more easily reuse Ansible code in a generic way. can be in 标准化目录结构中打包所有的任务、变量、文件、模板, and adjust the infrastructure or other resources needed to deploy the application. Simply copy roles from one project to another by copying the relevant directory . Then, just call the role from a play to execute.

With written roles , variables that adjust their behavior can be passed to the role from the playbook, setting all site-related hostnames, IP addresses, usernames, or other specific details that are required locally. For example, a role that deploys a database server might be written to support variables for setting the hostname, database administrator user and password, and other parameters that need to be customized for the installation. Character authors can also ensure that when they choose not to set variable values ​​in play, they set reasonable default values ​​for these variables.

The ansible role has the following advantages:

  1. Roles can group content , making it easy to share code with others
  2. Roles can be written to define the essential elements of a system type : web server, database server, Git repository, or for other purposes
  3. Roles make larger projects easier to manage
  4. Roles can be developed in parallel by different administrators (multiple people can work together to complete the deployment)

In addition to writing, using, reusing, and sharing roles yourself, 还可以从其他来源获取角色. Some roles are included in the rhel-system-rolses package (there are many system roles after installation). As part of Red Hat Enterprise Linux. ansible Galaxy网站Many roles supported by the community (such as deployment nginx, lvs, etc.) are also available from

Check the ANSIBLE role structure

The role at this time is nonexistent

[student@server ansible]$ ls
a            get-pip.py.1    inventory.py   roles        var.yml
[student@server ansible]$ ls roles/
[student@server ansible]$ 

//手动定义

[student@server roles]$ ansible-galaxy init hh
- Role hh was created successfully
[student@server roles]$ ls hh/
defaults  files  handlers  meta  README.md  tasks  templates  tests  vars

Ansible roles are defined by a standardized structure of letters and files . The top-level directory defines the names of the roles themselves (that is, roles themselves). Files are organized into subdirectories (defined roles), and subdirectories 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.

// View the tree diagram of hh through the tree command

[student@server roles]$ tree hh
hh
├── defaults
│   └── main.yml   ——角色默认定义的变量
├── files           ——指在调用角色时使用的静态文件,只用写相对路径
├── handlers        ——用来存放触发任务(notify)的目录
│   └── main.yml
├── meta            ——对角色的基础描述信息
│   └── main.yml
├── README.md       ——记录角色任何使用的帮助文档
├── tasks           ——需要执行的角色任务存放位置
│   └── main.yml
├── templates       ——存放模板,使用template来复制、一般用来启动服务或提前备份数据
├── tests           ——对角色执行进行测试
│   ├── inventory
│   └── test.yml
└── vars            ——经常使用的变量,比defaults变量优先级要高
    └── main.yml

8 directories, 8 files
  • Defaults : The main.yml file in this directory contains default values ​​for 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 role tasks
  • Handlers : The main.yml file in this directory contains the handler definition for the role, which is the content of the trigger
  • Meta : The main.yml file in this directory contains role-related information such as author, license, platform, and optionally the role's dependencies.
  • Tasks : The main.yml file in this directory contains the role's task definitions.
  • Template : This directory contains jinja2 templates (j2 templates) referenced by role tasks
  • Tests : This directory can contain manifests and test.yml playbooks, which can be used for testing roles
  • Vars : The main.yml file in this directory defines the variable values ​​of the role. These variables are usually used for internal purposes of the role. These variables have a higher priority and should not be changed when used in the playbook.

1. Use the ansible role in the playbook

Using characters in playbooks is very simple.


  • name: test
    hosts: node1
    roles:
    • role1
    • role2

For each specified role, role tasks, role handlers, role variables and role dependencies will be imported into the playbook in order. Any copy, script (run script), template or include_tasks/import_tasks tasks in a role can refer to related files, templates or task files in the role without relative or absolute path names . Ansible will look for them in the role's files, templates or tasks subdirectories respectively.

Notice
If used roles部分将角色导入到play中, these roles run before any tasks defined for the play.

The following example sets the values ​​of cy's role variables a1 and a2.
When customizing variables with the cy role, any defaults and vars variable priorities are overridden.
Example:
1. Create a role

[student@server roles]$ cd  /etc/ansible/roles
[student@server roles]$ ansible-galaxy  init  cy

2. Define variables for roles in vars

[student@server roles]$ Vim  cy/vars/main.yml
---
# vars file for cy
a1: 11
a2: 22

3. Write the task of the role in main.yml in the tasks directory

[student@server roles]$ Vim  cy/tasks/main.yml
---
# tasks file for cy
- name: test
  debug:
    msg: "{
    
    { a1 }}"

4. Create a playbook of test.yml in the /etc/ansible/ directory to use the cy role (this will indicate the execution of the host)

---
- name: test1
  hosts: node1
  roles:              //直接调用/var/main.yml变量
    - cy

At this point, we will find that we can call the variables defined in main.yml in the role vars directory and can be called directly.
5. Customize variables in the playbook of test.yml

---
- name: test1
  hosts: node1
  roles:               
    - role: cy      //添加此参数可直接引用a1变量
      a1: 333

6. Execute test.yml, you will find that the a1 variable defined in test.yml covers the variables defined in the vars directory in the role, because this definition has a higher priority than vars

The output result is: a1=33

2. Control the execution sequence

For each play in the playbook, tasks are executed in the order listed in the task list, and after all tasks are executed, any notified handlers are executed.
After a character is added to play, character quests are added to the beginning of the quest list. If there is a second character in the play , its task list will be added after the first character ( generally, the character is executed first and then ordinary tasks are performed ).

Actor handlers are added to a play in the same way that role tasks are added to a play. Each play defines a list of handlers. Actor handlers are added to the handlers list first, followed by any handlers defined in the play's handlers section.

In some cases,May need to perform some play tasks before the character. Parts can be added to the play configuration pre_tasks, which can be executed first. All tasks listed in this section will be executed before any roles are executed. If any of these tasks notify handlers, those handler tasks are also executed before role or normal tasks.

In addition, play also supports post_taskskeywords. This task is executed after play's normal tasks and execution roles, and any handlers they notify.

by default:

tasks: 
roles:
先执行角色,然后在执行tasks

也就是这样理解:
pre_tasks:  在角色之前执行
post_tasks: 在角色之后执行

Examples
such as:

---
- name: test1
  hosts: node1
  pre_tasks:            //默认会第一个执行
    - name: debug1
      shell:
        cmd: echo aaa
      notify: cc
  roles:             # 第二个执行
    - cy

  post_tasks:
    - name: debug2      # 第三
      debug:
        msg: ooo
        
  handlers:
    - name: cc
      debug:
        msg: iii

Executing the playbook, we found that the pre_tasks task is executed before the role, and the trigger is executed immediately after being triggered.
Post_tasks tasks are executed after triggers and roles are executed.

3. Import role tasks

Variables must be defined in the role role when importing, and can be directly referenced when importing In
addition to including the role in the roles part of the play, you can also use ordinary tasks to add the role to the play, and use the include_rolemodule to dynamically include the role. import_roleRoles can be statically imported using modules.
like:

---
- name: test23
  hosts: node1
  tasks:
    - debug:
        msg: chenyufdsf

    - name: a task to include cy here
      include_role:                         //或者使用import_role
        name: cy

    - name: debug2
      debug:
        msg: 11111

If quoted in this way, it is also executed in order

Three ways to define a list:

reles:
  -cy

roles:
  - role: cy

tasks: 
  - name: aa
       include_role:  
         name: cy

Case:
Example: Create and use roles
According to the following requirements, create a role named http in /etc/ansible/roles

1. Deploy the yum repository
2. Install the httpd package
3. The template file index.html.j2 already exists, and the user creates the file /var/www/html/index.html with the following output:
Welcome to HOSTNAME on IPADDRESS
when index.html When the content changes, restart the httpd service.
HOSTNAME is the fully qualified domain name of the controlled node, and IPADDRESS is the IP address of the controlled node
. Create a playbook /etc/ansible/newrole.yml that uses this role as described above. The playbook runs on all hosts.


If you don’t want to use the previous role, you can use ansible-galaxy remove cy when creating a role

1. Create an http role

[root@server roles]# ansible-galaxy init http
- Role http was created successfully
[root@server roles]# 

2. Manually create a new index.html.j2 template according to the requirements

[root@server roles]# cd http/templates/
[root@server templates]# ls
//调用事实变量,分别是完全合格域名和本机IP地址
[root@server templates]# vim index.html.j2
Welcome to {
   
   { ansible_fqdn }} on {
   
   { ansible_ens160.ipv4.address }}

3. Write the role task content in /etc/ansible/roles/http/tasks/main.yml

[root@server ansible]# vim /etc/ansible/roles/http/tasks/main.yml
---
# tasks file for http
- name: repo1
  yum_repository:
    file: server
    name: baseos
    description: rhel8
    baseurl: file:///mnt/BaseOS
    enabled: yes
    gpgcheck: no

- name: repo2
  yum_repository:
    file: server
    name: appstream
    description: RHEL8
    baseurl: file:///mnt/AppStream
    enabled: yes
    gpgcheck: no

- name: mount cdrom
  mount:
    src: /dev/cdrom
    path: /mnt
    fstype: iso9660
    state: mounted

- name: install httpd
  yum:
    name: httpd
    state: present

- name: cp file
  template:
    src: index.html.j2                 //这里写相对路径调用访问网页
    dest: /var/www/html/index.html     //保存到受控主机
  notify:                              //触发任务
    - restart httpd
 
- name: firewalld                    //开启防火墙
  firewalld:
    service: http
    state: enabled
    permanent: yes
    immediate: yes
    
- name: firewalld for http         //设置防火墙规则
  firewalld:
    service: http
    state: enabled
    permanent: yes

4. Configure trigger handlers trigger

[root@server ansible]# vim /etc/ansible/roles/http/handlers/main.yml 
---
# handlers file for http
- name: restart httpd
  service:
    name: httpd
    state: restarted
    enabled: yes

5. Write the /etc/ansible/newrole.yml playbook and run the http role

[root@server ansible]# vim newrole.yml
---
- name: web station
  hosts: all
  roles:
     - http

6. Execute the playbook

[root@server ansible]# ansible-playbook newrole.yml
PLAY [web station] *************************************************************

TASK [Gathering Facts] *********************************************************
ok: [node1]
ok: [node2]

TASK [http : repo1] ************************************************************
changed: [node1]
changed: [node2]

TASK [http : repo2] ************************************************************
changed: [node1]
changed: [node2]

TASK [http : mount cdrom] ******************************************************
changed: [node1]
changed: [node2]

TASK [install httpd] ***********************************************************
changed: [node2]
changed: [node1]

TASK [http : cp file] **********************************************************
changed: [node2]
changed: [node1]

TASK [http : firewalld] ********************************************************
changed: [node1]
changed: [node2]

RUNNING HANDLER [restart httpd] ************************************************
changed: [node1]
changed: [node2]

PLAY RECAP *********************************************************************
node1                      : ok=8    changed=7    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
node2                      : ok=8    changed=7    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

7. Verification:

[root@server ansible]# curl http://node1.example.com
Welcome to node1.example.com on 172.16.30.10
[root@server ansible]# curl http://node2.example.com
Welcome to node2.example.com on 172.16.30.20

2. System role

1. Customize the installation system role

[student@server roles]$ sudo yum -y install rhel-system-roles

2. Rhel system roles
Commonly used system roles:

Rhel-system-roles.kdump Configure kdump crash recovery service
Rhel-system-roles.network configure network interface
Rhel-system-roles.selinux configure network interface
Rhel-system-roles.selinux configure and manage selinux (selinux schema files and port contexts, booleans)
Rhel-system-roles.timesync Configure Clock Synchronization
Rhel-system-roles.postfix Configure each host as a mail transfer agent using the postfix service
Rhel-system-roles.firewall Configure the host's firewall
Rhel-system-roles.tuned Configure tuned service to tune system performance

3. The RHEL system role is located in the /usr/share/ansible/roles/ directory

[student@server roles]$ ls | wc -l
36
[student@server roles]$ cp -a rhel-system-roles.selinux /home/student/ansible/roles/selinux
[student@server roles]$ cd /home/student/ansible/roles/
[student@server roles]$ ls
hh  selinux
//可以查看帮助文档
[student@server selinux]$ cat README.md
```yaml
selinux_all_purge: true


#### set SELinux policy type and mode

```yaml
selinux_policy: targeted
selinux_state: enforcing

Example:
Install the RHEL system role package and create a playbook /etc/ansible/timesync.yml that:
Runs on all managed nodes Configure the role
with the timesync role
to use the currently valid NTP provider
, to use the time server classroom.example.com
to configure the role to enable iburst parameter
1, install the system role
dnf -y install rhel-system-roles

2. Copy the clock synchronization system role to the /etc/ansible/roles directory, and rename the role to timesync
cp -r /usr/share/ansible/roles/rhel-system-roles.timesync/ /etc/asnible /roles/timesync
3. Write the playbook and execute it.

[root@workstation ansible]$ vim timesync.yml
---
- name: set time sync
  hosts: all
  vars:  
    timesync_ntp_servers:
      - hostname: ansible.example.com
        iburst: yes
  roles:
    - timesync
[root@workstation ansible]$ ansible-playbook timesync.yml

3. Install roles from ansible-galaxy

The ansible-galaxy install subcommand downloads roles from Ansible Galaxy (download any roles you need from the official website), and stakes it locally on the control node.
By default, roles are installed into the first writable directory under the user's roles_path. According to the default roles_path set by ansible, roles are usually installed to the user's ~/.ansible/roles directory. The default roles_path may be overridden by the current ansible configuration file or the environment variable ANSIBLE_ROLES_PATH which will affect the behavior of ansible-galaxy.
You can use the -p DIRECTORY option to specify a specific directory to install the role.

install role
1. First write a playbook in the roles directory, define the path of the role to be installed in the playbook, and place it in the terminal after downloading

[root@server roles]# vim /etc/ansible/roles/test.yml 
- name: haproxy
  src: file:///home/student/ansible/haproxy.tar.gz       //在本地中传输给受控主机

- name: phpinfo
  src: file:///home/student/ansible/phpinfo.tar.gz

Where src specifies the source of the role, which can be local (file://) or remote (http://)

2. Use the ansible-galaxy command to install the role

[root@server ansible]# ansible-galaxy install -r /etc/ansible/roles/test.yml -p /etc/ansible/roles/
- downloading role from file:///root/haproxy.tar.gz
- extracting haproxy to /etc/ansible/roles/haproxy
- haproxy was installed successfully
- downloading role from file:///root/phpinfo.tar.gz
- extracting phpinfo to /etc/ansible/roles/phpinfo
- phpinfo was installed successfully

3. Check the installed roles in the roles directory
, and then you can call the service according to the modules inside.

[root@server roles]# pwd
/etc/ansible/roles
[root@server roles]# ls
haproxy  phpinfo  test.yml

Manage downloaded roles
The ansible-galaxy command can also manage local roles, such as those located in the roles directory of the playbook project. The ansible-galaxy list subcommand lists locally found roles.

[root@server ansible]# ansible-galaxy list
# /etc/ansible/roles
- haproxy, (unknown version)
- phpinfo, (unknown version)

可以使用ansible-galaxy remove子命令本地删除角色
[root@server ansible]# ansible-galaxy remove haproxy
- successfully removed haproxy
[root@server ansible]# ansible-galaxy list
# /etc/ansible/roles
- phpinfo, (unknown version)

Guess you like

Origin blog.csdn.net/cxyxt/article/details/127673716