ansible--创建角色

李鸿
2023-12-01

创建角色

角色创建流程
在Ansible中创建角色不需要特别的开发工具。创建和使用角色包含三个步骤:

  1. 创建角色目录结构
  2. 定义角色内容
  3. 在playbook中使用角色
1.创建角色目录结构

默认情况下,Ansible在Ansible Playbook所在目录的roles子目录中查找角色。这样,用户可以利用playbook和其他支持文件存储角色。

如果Ansible无法在该位置找到角色,它会按照顺序在Ansible配置设置roles_path所指定的目录中查找。此变量包含要搜索的目录的冒号分隔列表。此变量的默认值为:

~/.ansible/roles:/usr/share/ansible/roles:/etc/ansible/roles
  • 系统自带角色位置
[root@ansible ~]# 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
  • 每个角色具有自己的目录,采用标准化的目录结构。例如,以下目录结构包含了定义motd角色的文件。
[root@localhost ~]# tree roles/
roles/
└── motd
    ├── defaults
    │   └── main.yml
    ├── files
    ├── handlers
    ├── meta
    │   └── main.yml
    ├── tasks
    │   └── main.yml
    └── templates
        └── motd.j2

README.md提供人类可读的基本角色描述、有关如何使用该角色的文档和示例,以及其发挥作用所需要满足的任何非Ansible要求。
meta子目录包含一个main.yml文件,该文件指定有关模块的作者、许可证、兼容性和依赖项的信息。
files子目录包含固定内容的文件,而templates子目录则包含使用时可由角色部署的模板。
其他子目录中可以包含main.yml文件,它们定义默认的变量值、处理程序、任务、角色元数据或变量,具体取决于所处的子目录。

如果某一子目录存在但为空,如本例中的handlers,它将被忽略。如果某一角色不使用功能,则其子目录可以完全省略。例如,本例中的vars子目录已被省略。

2.创建角色框架

ansible-galaxy命令行工具可用于管理Ansible角色,包括新角色的创建。用户可以运行ansible-galaxy init来创建新角色的目录结构。指定角色的名称作为命令的参数,该命令在当前工作目录中为新角色创建子目录。

  • 用ansible-galaxy init命令创建一个名为httpd的角色
[root@ansible roles]# pwd       //当前位置在项目角色目录里
/project/roles
[root@ansible roles]# ansible-galaxy init httpd     //创建httpd角色
- Role httpd was created successfully
[root@ansible roles]# ls
httpd
[root@ansible roles]# tree httpd       //查看httpd的子目录
httpd
├── defaults       //文件包含角色变量的默认值,这些变量的优先级较低
│   └── main.yml
├── files          //包含由角色任务引用的静态文件。
├── handlers       //文件包含角色的处理程序定义。
│   └── main.yml
├── meta           //文件包含与角色相关的信息,如作者、许可证、平台和可选的角色依赖项。
│   └── main.yml
├── README.md
├── tasks          //文件包含角色的任务定义
│   └── main.yml
├── templates      //此目录包含由角色任务引用的Jinja2模板。
├── tests          //此目录可以包含清单和名为test.yml的playbook,可用于测试角色
│   ├── inventory
│   └── test.yml
└── vars           //定义角色的变量值,这些变量通常用于角色内部用途,这些变量的优先级较高
    └── main.yml

8 directories, 8 files
3. 定义角色内容

创建目录结构后,用户必须编写角色的内容。ROLENAME/tasks/main.yml任务文件是一个不错的起点,它是由角色运行的主要任务列表。

用httpd这个角色安装配置启动httpd
  • 先编写tasks任务
[root@ansible tasks]# cat main.yml 
---
# tasks file for httpd
- name: install httpd         //安装httpd
  yum:                      
    name: httpd
    state: present

- name: config httpd          //配置文件
  template:
    src: ../templates/httpd.conf.j2
    dest: /etc/httpd/conf/httpd.conf
  notify:                    //配置发生改变就通知httpd重启
    - restart httpd            没有发生改变就执行下一项

- name: service httpd        //启动服务
  service:
    name: httpd
    state: started
  • 在受控机上传输配置文件到主控机
[root@linux131 ~]# ls /etc/httpd/
conf  conf.d  conf.modules.d  logs  modules  run  state
[root@linux131 ~]# cd /etc/httpd/conf
[root@linux131 conf]# ls
httpd.conf  magic

传输文件到133主控机指定位置
[root@linux131 conf]# scp httpd.conf
192.168.152.133:/project/roles/httpd/templates/httpd.conf.j2
The authenticity of host '192.168.152.133 (192.168.152.133)' can't be established.
ECDSA key fingerprint is SHA256:kmliopfYJmTtxXJVhwqIJL5XizwRyu8iA98oJYoVOjI.
Are you sure you want to continue connecting (yes/no/[fingerprint])? yue^H^H^Hyes
Please type 'yes', 'no' or the fingerprint: yes
Warning: Permanently added '192.168.152.133' (ECDSA) to the list of known hosts.
root@192.168.152.133's password: 
httpd.conf                                    100%   12KB   1.9MB/s   00:00 

查看是否传输成功
[root@ansible httpd]# cd templates/
[root@ansible templates]# ls
httpd.conf.j2
[root@ansible templates]# cat httpd.conf.j2 
#
略...

修改配置文件
[root@ansible templates]# vim httpd.conf.j2 
# ServerName www.example.com:80
Listen 80

[root@ansible templates]# vim httpd.conf.j2 
ServerName {{ domain }}:{{ port }}         //修改后
               域名        端口号
Listen {{ port }}
  • defaults编写变量
[root@ansible defaults]# vim main.yml 
---
# defaults file for httpd
domain: www.example.com
port: 80
  • handlers 编写重启服务
[root@ansible handlers]# cat main.yml 
---
# handlers file for httpd
- name: restart httpd
  service:
    name: httpd
    state: restarted
  • 查看测试任务
[root@ansible tests]# cat inventory 
localhost                  //文件清单有本机

[root@ansible tests]# cat test.yml 
---
- hosts: localhost         //在本机root要用的角色是httpd
  remote_user: root
  roles:
    - httpd[root@ansible tests]# 
  • 编写playbook
[root@ansible project]# ls
playbook.yml  roles

端口用8080,启用角色httpd
[root@ansible project]# cat playbook.yml 
---
- hosts: 192.168.152.131
  vars:
    port: 8080
  roles:
    - role: roles/httpd
  • 查看受控机上没有8080端口,也没有httpd
[root@linux131 ~]# ss -antl
State    Recv-Q    Send-Q        Local Address:Port       Peer Address:Port   
LISTEN   0         128                 0.0.0.0:22              0.0.0.0:*      
LISTEN   0         128                    [::]:22                 [::]:*     
[root@linux131 ~]# rpm -qa|grep httpd
  • 执行playbook
[root@ansible project]# ansible-playbook playbook.yml
[WARNING]: Found variable using reserved name: port

PLAY [192.168.152.131] *********************************************************

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

TASK [roles/httpd : install httpd] *********************************************
ok: [192.168.152.131]

TASK [roles/httpd : config httpd] **********************************************
ok: [192.168.152.131]

TASK [roles/httpd : service httpd] *********************************************
changed: [192.168.152.131]

PLAY RECAP *********************************************************************
192.168.152.131            : ok=4    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
  • 查看受控机上端口多了个8080
[root@linux131 ~]# ss -antl
State    Recv-Q    Send-Q        Local Address:Port       Peer Address:Port   
LISTEN   0         128                 0.0.0.0:22              0.0.0.0:*      
LISTEN   0         128                       *:8080                  *:*      
LISTEN   0         128                    [::]:22                 [::]:*  

[root@linux131 ~]# rpm -qa|grep httpd
httpd-filesystem-2.4.37-21.module_el8.2.0+494+1df74eae.noarch
httpd-2.4.37-21.module_el8.2.0+494+1df74eae.x86_64
httpd-tools-2.4.37-21.module_el8.2.0+494+1df74eae.x86_64
centos-logos-httpd-80.5-2.el8.noarch
4.角色内容开发的推荐做法

角色允许以模块化方式编写playbook。为了最大限度地提高新开发角色的效率,请考虑在角色开发中采用以下推荐做法:

  • 在角色自己的版本控制存储库中维护每个角色。Ansible很适合使用基于git的存储库。
  • 角色存储库中不应存储敏感信息,如密码或SSH密钥。敏感值应以变量的形式进行参数化,其默认值应不敏感。使用角色的playbook负责通过Ansible Vault变量文件、环境变量或其他ansible-playbook选项定义敏感变量。
  • 使用ansible-galaxy init启动角色,然后删除不需要的任何目录和文件。
  • 创建并维护README.md和meta/main.yml文件,以记录用户的角色的用途、作者和用法。
  • 让角色侧重于特定的用途或功能。可以编写多个角色,而不是让一个角色承担许多任务。
  • 经常重用和重构角色。避免为边缘配置创建新的角色。如果现有角色能够完成大部分的所需配置,请重构现有角色以集成新的配置方案。使用集成和回归测试技术来确保角色提供所需的新功能,并且不对现有的playbook造成问题。
5.定义角色依赖项

角色依赖项使得角色可以将其他角色作为依赖项包含在内。例如,一个定义文档服务器的角色可能依赖于另一个安装和配置web服务器的角色。依赖关系在角色目录层次结构中的meta/main.yml文件内定义。

  • 以下是一个示例meta/main.yml文件
dependencies:             //依赖
  - role: apache          //角色
    port: 8080            //端口
  - role: postgres        //角色 
    dbname: serverlist    //数据库
    admin_user: felix     //管理用户

默认情况下,角色仅作为依赖项添加到playbook中一次。若有其他角色也将它作为依赖项列出,它不会再次运行。此行为可以被覆盖,将meta/main.yml文件中的allow_duplicates变量设置为yes即可。

注意 限制角色对其他角色的依赖。依赖项使得维护角色变得更加困难,尤其是当它具有许多复杂的依赖项时。

6.在playbook中使用角色

要访问角色,可在play的roles:部分引用它。下列playbook引用了motd角色。由于没有指定变量,因此将使用默认变量值应用该角色。

  • 修改playbook,没有指定变量
[root@ansible project]# cat playbook.yml 
---
- hosts: 192.168.152.131
  roles:
    - roles/httpd
  • 执行
[root@ansible project]# ansible-playbook playbook.yml 
[WARNING]: Found variable using reserved name: port

PLAY [192.168.152.131] *********************************************************

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

TASK [roles/httpd : install httpd] *********************************************
ok: [192.168.152.131]

TASK [roles/httpd : config httpd] **********************************************
changed: [192.168.152.131]

TASK [roles/httpd : service httpd] *********************************************
changed: [192.168.152.131]

RUNNING HANDLER [roles/httpd : restart httpd] **********************************
changed: [192.168.152.131]

PLAY RECAP *********************************************************************
192.168.152.131            : ok=5    changed=3    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
  • 查看,恢复了默认端口80
[root@linux131 ~]# ss -antl
State    Recv-Q    Send-Q        Local Address:Port       Peer Address:Port   
LISTEN   0         128                 0.0.0.0:22              0.0.0.0:*      
LISTEN   0         128                       *:80                    *:*      
LISTEN   0         128                    [::]:22                 [::]:*   
 类似资料: