ansible基础roles(角色)

roles介绍

角色(roles)是ansible自1.2版本开始引入的新特性,用于层次性,结构化地组织playbook。roles能够根据层次型结构自动装载变量文件、tasks以及handlers等。要使用roles只需要在playbook中使用include指令即可。简单的说,roles就是通过分别将变量、文件、任务、模块及处理器放置于单独的目录中、并可以便捷地include他们的一种机制。角色一般用于基于主机构建服务的场景中,但也可以是用于构建守护进程等场景中。

创建角色框架

可以使用标准Linux命令创建新角色所需的所有子目录和文件。此外,也可以通过命令行实用程序来自动执行新角色创建过程。

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

[root@ansible roles]# ansible-galaxy  init test
- Role test was created successfully
[root@ansible roles]# tree 
.
└── test
    ├── defaults
    │   └── main.yml
    ├── files
    ├── handlers
    │   └── main.yml
    ├── meta
    │   └── main.yml
    ├── README.md
    ├── tasks
    │   └── main.yml
    ├── templates
    ├── tests
    │   ├── inventory
    │   └── test.yml
    └── vars
        └── main.yml

Ansible角色子目录

子目录功能
defaults 此目录中的main.yml文件包含角色变量的默认值,使用角色时可以覆盖这些默认值。
这些变量的优先级较低,应该在play中更改和自定义。
files 此目录包含由角色任务引用的静态文件。
handlers 此目录中的main.yml文件包含角色的处理程序定义。
meta 此目录中的main.yml文件包含与角色相关的信息,如作者、许可证、平台和可选的角色依赖项。
tasks 此目录中的main.yml文件包含角色的任务定义。
templates 此目录包含由角色任务引用的Jinja2模板。
tests 此目录可以包含清单和名为test.yml的playbook,可用于测试角色。
vars 此目录中的main.yml文件定义角色的变量值。这些变量通常用于角色内部用途。
这些变量的优先级较高,在playbook中使用时不应更改。

当然,上述目录并不全是必须的,也就是说,如果你的角色并没有相关的模板文件,那么角色目录中并不用包含templates目录,同理,其他目录也一样,一般情况下,都至少会有一个tasks目录

在playbook中使用角色

---
- hosts: xxxxxxx
  roles:
    - role1
    - role2

创建一个简单的角色test1,在test1目录中创建tasks子目录,在子目录tasks创建main.yml的文件

[root@ansible roles]# mkdir -p test1/tasks

通过debug模块可以输出信息
[root@ansible roles]# cat  test1/tasks/main.yml 
- debug:
    msg: "test1 roles!"

 调用角色的剧本文件名为test.yml,它与test1目录处于同级目录中

[root@ansible roles]# ls
ansible.cfg  inventory  test1  test.yml

[root@ansible roles]# vim test.yml 
---
- hosts: test123
  roles:
    - test1

[root@ansible roles]# ansible-playbook  test.yml 

PLAY [test123] *************************************************************************************************

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

TASK [test1 : debug] *****************************************************************************************
ok: [test123] => {
    "msg": "test1 roles!"
}

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

通过变量更改角色行为

编写良好的角色利用默认变量来改变角色行为,使之与相关的配置场景相符。这有助于让角色变得更为通用,可在各种不同的上下文中重复利用。

如果通过以下方式定义了相同的变量,则角色的defaults目录中定义的变量的值将被覆盖:

  • 在清单文件中定义,作为主机变量或组变量
  • 在playbook项目的group_vars或host_vars目录下的YAML文件中定义
  • 作为变量嵌套在play的vars关键字中定义
  • 在play的roles关键字中包含该角色时作为变量定义

创建test角色模板文件,引用Ansible事实和test_variable

#创建test模板
[root@ansible roles]# vim  test/templates/test.j2 
This is the system {{ ansible_facts['hostname'] }}.

Today's date is: {{ ansible_facts['date_time']['date'] }}.

test   {{ test_variable }}

#定义变量
[root@ansible roles]# vim test/defaults/main.yml 
---
# defaults file for test
test_variable: 1234567

#tasks
[root@ansible roles]# vim test/tasks/main.yml 
---
# tasks file for test
- template:
    src: test.j2
    dest: /tmp/test

#调用角色执行剧本
[root@ansible roles]# cat test.yml 
---
- hosts: test123
  roles:
    - test
[root@ansible roles]# ansible-playbook   test.yml 

PLAY [test123] *************************************************************************************************

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

TASK [test : template] ***************************************************************************************
changed: [test123]

PLAY RECAP ***************************************************************************************************
test123                      : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

#查看test文件
[root@ansible roles]# ansible test123  -a "cat /tmp/test"
test123 | CHANGED | rc=0 >>
This is the system test123.

Today's date is: 2021-02-23.

test   1234567

在清单文件中定义变量

在清单文件中定义
[root@ansible roles]# vim inventory 
test123 test_variable=inventory

[root@ansible roles]# ansible-playbook   test.yml 

PLAY [test123] *************************************************************************************************

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

TASK [test : template] ***************************************************************************************
changed: [test123]

PLAY RECAP ***************************************************************************************************
test123                      : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

角色的defaults目录中定义的变量的值将被覆盖
[root@ansible roles]# ansible test123  -a "cat /tmp/test"
httpd | CHANGED | rc=0 >>
This is the system test123.

Today's date is: 2021-02-23.

test   inventory

 在group_vars或host_vars目录yaml文件中定义

[root@ansible roles]# vim inventory 
test123

#创建host_vars目录
[root@ansible roles]# mkdir host_vars

#创建yaml文件定义变量
[root@ansible roles]# cat host_vars/test123.yml 
test_variable: host_vars

#执行剧本
[root@ansible roles]# ansible-playbook   test.yml 

PLAY [test123] *************************************************************************************************

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

TASK [test : template] ***************************************************************************************
changed: [test123]

PLAY RECAP ***************************************************************************************************
test123                      : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

#角色的defaults目录中定义的变量的值将被覆盖
[root@ansible roles]# ansible test123 -a "cat /tmp/test"
test123 | CHANGED | rc=0 >>
This is the system test123.

Today's date is: 2021-02-23.

test   host_vars

作为变量嵌套在play的vars关键字中定义

[root@ansible roles]# cat  test.yml 
---
- hosts: test123
  vars:
    test_variable: play      
  roles:
    - test

[root@ansible roles]# ansible-playbook   test.yml 

PLAY [test123] *************************************************************************************************

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

TASK [test : template] ***************************************************************************************
changed: [test123]

PLAY RECAP ***************************************************************************************************
test123                     : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

#defaults中定义的被覆盖
[root@ansible roles]# ansible test123  -a "cat /tmp/test"
test123 | CHANGED | rc=0 >>
This is the system test123.

Today's date is: 2021-02-23.

test   play

在play的roles关键字中包含该角色时作为变量定义

[root@ansible roles]# vim test.yml
---
- hosts: test123
  roles:
    - role: test
      vars:
        test_variable: role

[root@ansible roles]# ansible-playbook   test.yml 

PLAY [test123] *************************************************************************************************

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

TASK [test : template] ***************************************************************************************
changed: [test123]

PLAY RECAP ***************************************************************************************************
test123                      : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

#被覆盖
[root@ansible roles]# ansible test123  -a "cat /tmp/test"
test123 | CHANGED | rc=0 >>
This is the system test123.

Today's date is: 2021-02-23.

test   role

在play中使用角色变量时,变量的优先顺序可能会让人困惑。
- 几乎任何其他变量都会覆盖角色的默认变量,如清单变量、playvars变量,以及内嵌的角色参数等。
- 较少的变量可以覆盖角色的vars目录中定义的变量。事实、通过include_vars加载的变量、注册的变量和角色参数是其中一些具备这种能力的变量。清单变量和playvars无此能力。这非常重要,因为它有助于避免用户的play意外改变角色的内部功能。
- 不过,正如上述示例中最后一个所示,作为角色参数内嵌声明的变量具有非常高的优先级。它们可以覆盖角色的vars目录中定义的变量。如果某一角色参数的名称与playvars或角色vars中设置的变量或者清单变量或playbook变量的名称相同,该角色参数将覆盖另一个变量。

红帽企业Linux系统角色

自RHEL7.4开始,操作系统随附了多个Ansible角色,作为rhel-system-roles软件包的一部分。在RHEL8中,该软件包可以从AppStream中获取。以下是每个角色的简要描述:

RHEL系统角色

名称状态角色描述
rhel-system-roles.kdump 全面支持 配置kdump崩溃恢复服务
rhel-system-roles.network 全面支持 配置网络接口
rhel-system-roles.selinux 全面支持 配置和管理SELinux自定义,
包括SELinux模式、文件和端口上下文、
布尔值设置以及SELinux用户
rhel-system-roles.timesync 全面支持 使用网络时间协议或精确时间协议配置时间同步
rhel-system-roles.postfix 技术预览 使用Postfix服务将每个主机配置为邮件传输代理
rhel-system-roles.firewall 开发中 配置主机的防火墙
rhel-system-roles.tuned 开发中 配置tuned服务,以调优系统性能

系统角色的目的是在多个版本之间标准化红帽企业Linux子系统的配置。使用系统角色来配置版本6.10及以上的任何红帽企业Linux主机。

安装RHEL系统角色

RHEL系统角色由rhel-system-roles软件包提供,该软件包可从AppStream流获取。在Ansible控制节点上安装该软件包。

#安装RHEL系统角色
[root@ansible ~]# yum -y install rhel-system-roles

 安装后,RHEL系统角色位于/usr/share/ansible/roles目录中:

[root@ansible ~]# ls  /usr/share/ansible/roles/
linux-system-roles.certificate      linux-system-roles.nbde_server  linux-system-roles.tlog            rhel-system-roles.nbde_client  rhel-system-roles.timesync
linux-system-roles.kdump            linux-system-roles.network      rhel-system-roles.certificate      rhel-system-roles.nbde_server  rhel-system-roles.tlog
linux-system-roles.kernel_settings  linux-system-roles.postfix      rhel-system-roles.kdump            rhel-system-roles.network
linux-system-roles.logging          linux-system-roles.selinux      rhel-system-roles.kernel_settings  rhel-system-roles.postfix
linux-system-roles.metrics          linux-system-roles.storage      rhel-system-roles.logging          rhel-system-roles.selinux
linux-system-roles.nbde_client      linux-system-roles.timesync     rhel-system-roles.metrics          rhel-system-roles.storage

 安装后,RHEL系统角色的文档位于/usr/share/doc/rhel-system-roles-/目录中。文档按照子系统整理到子目录中:

[root@ansible roles]# ls /usr/share/doc/rhel-system-roles/
certificate  kernel_settings  metrics      nbde_server  postfix  storage   tlog
kdump        logging          nbde_client  network      selinux  timesync

每个角色的文档目录均包含一个README.md文件。README.md文件含有角色的说明,以及角色用法信息。

README.md文件也会说明影响角色行为的角色变量。通常,README.md文件中含有一个playbook代码片段,用于演示常见配置场景的变量设置。

时间同步角色示例

假设需要在服务器上配置NTP时间同步。我们可以自行编写自动化来执行每一个必要的任务。但是,RHEL系统角色中有一个可以执行此操作角色,那就是rhel-system-roles.timesync

该角色的详细记录位于/usr/share/doc/rhel-system-roles/timesync目录下的README.md中。此文件说明了影响角色行为的所有变量,还包含演示了不同时间同步配置的三个playbook代码片段。

为了手动配置NTP服务器,该角色具有一个名为timesync_ntp_servers的变量。此变量取一个要使用的NTP服务器的列表作为值。列表中的每一项均由一个或多个属性构成。两个关键属性如下:

timesync_ntp_servers属性

属性用途
hostname 要与其同步的NTP服务器的主机名。
iburst 一个布尔值,用于启用或禁用快速初始同步。在角色中默认为no,但通常应该将属性设为yes.

修改test123主机时间

[root@ansible roles]# ansible test123 -m command -a   "date -s '1999-1-1 00:11:11'"
test123 | CHANGED | rc=0 >>
Fri Jan  1 00:11:11 CST 1999

[root@ansible roles]# date && ssh test123 'date'
Wed Feb 24 17:47:44 CST 2021
Fri Jan  1 00:14:35 CST 1999

编写时间同步playbook

[root@ansible roles]# cp  /usr/share/ansible/roles/rhel-system-roles.timesync/    ~/roles/timesync

[root@ansible roles]# ls
ansible.cfg  inventory  test  test1  test.yml  timesync

#编写剧本导入角色
[root@ansible roles]# cat test.yml 
---
- hosts: test123
  vars:
    timesync_ntp_servers:      
      - hostname: time1.aliyun.com
        iburst: yes
  roles: 
    - timesync

#执行剧本
[root@ansible roles]# ansible-playbook  test.yml 

#查看时间是否同步
[root@ansible roles]# date && ssh test123 'date'
Wed Feb 24 18:43:22 CST 2021
Wed Feb 24 18:43:21 CST 2021

使用ansible galaxy部署角色

 Ansible Galaxy [https://galaxy.ansible.com]是一个Ansible内容公共资源库,这些内容由许许多多Ansible管理员和用户编写。它包含数千个Ansible角色,具有可搜索的数据库,可帮助Ansible用户确定或许有助于他们完成管理任务的角色。

获取Ansible Galaxy帮助

通过Ansible Galaxy网站主页上的Documenttaion标签,可以进入描述如何使用Ansible Galaxy的页面。其中包含了介绍如何从Ansible Galaxy下载和使用角色的内容。该页面也提供关于如何开发角色并上传到Ansible Galaxy的说明。

浏览Ansible Galaxy中的角色

通过Ansible Galaxy网站主页上左侧的Search标签,用户可以访问关于Ansible Galaxy上发布的角色的信息。用户可以使用标记通过角色的名称或通过其他角色属性来搜索Ansible角色。结果按照Best Match分数降序排列,此分数依据角色质量、角色受欢迎程度和搜索条件计算而得。

Ansible Galaxy命令行工具

ansible-galaxy search子命令在Ansible Galaxy中搜索角色。如果以参数形式指定了字符串,则可用于按照关键字在Ansible Galaxy中搜索角色。用户可以使用--author、--platforms和--galaxy-tags选项来缩小搜索结果的范围。也可以将这些选项用作主要的搜索键。例如,命令ansible-galaxy search --author geerlingguy将显示由用户geerlingguy提交的所有角色。

结果按照字母顺序显示,而不是Best Match分数降序排列。下例显示了包含redis并且适用于企业Linux(EL)平台的角色的名称。

[root@ansible roles]# ansible-galaxy search 'mysql' --platforms EL

Found 629 roles matching your search:

 Name                                                  Description
 ----                                                  -----------
 0utsider.ansible_zabbix_agent                         Installing and maintaining zabbix-agent for RedHat/Deb>
 0x0i.grafana                                          Grafana - an analytics and monitoring observability pl>
 0x0i.prometheus                                       Prometheus - a multi-dimensional time-series data moni>
 4linuxdevops.mysql-server                             Instalacao e Configuracao do servidor MySQL
 5KYDEV0P5.skydevops-mysql                             Install and configure MySQL Database
 AAbouZaid.yourls                                      Manage Yourls, a URL shortener web app.
 abednarik.mysqld-exporter                             Install and configure mysqld_exporter
 abelboldu.openstack-glance                            
 abelboldu.openstack-keystone                          
 abelboldu.openstack-neutron-controller                OpenStack Neutron controller node
 abelboldu.openstack-nova-controller                   OpenStack Nova controller node
 acandid.mysql                                         Install MySQL 8 on RedHat/CentOS 8 and Create user and>
 adelean.solr                                          Apache Solr for Linux.
 AerisCloud.collectd                                   This role takes care of adding collectd to any given s>
 AerisCloud.librato                                    Install and configure the Librato Agent
 AerisCloud.repos                                      Manage CentOS yum and Debian apt repositories
 agmalpartida.cron                                     Handle cron.
 ajesus37.mysql_server                                 Instalacao e Configuracao do servidor MySQL
..............................................................
..............................................

 ansible-galaxy info子命令显示与角色相关的更多详细信息。Ansible Galaxy从多个位置获取这一信息,包括角色的meta/main.yml文件及其GigHub存储库。以下命令显示了Ansible Galaxy提供的geerlingguy.redis角色的相关信息。

[root@ansible roles]# ansible-galaxy  info acandid.mysql

Role: acandid.mysql
        description: Install MySQL 8 on RedHat/CentOS 8 and Create user and database.
        active: True
        commit: 74231a180b2496c7861f899c0640aa711d591bad
        commit_message: Update README.md
        commit_url: https://api.github.com/repos/acandid/mysql/git/commits/74231a180b2496c7861f899c0640aa711d>
        company: Almir Candido
        created: 2020-07-22T13:29:27.238385Z
        download_count: 27
        forks_count: 0
        github_branch: master
        github_repo: mysql
        github_user: acandid
        id: 49821
        imported: 2020-07-22T09:29:27.422608-04:00
        is_valid: True
        issue_tracker_url: https://github.com/acandid/mysql/issues
        license: license (BSD, MIT)
        min_ansible_version: 2.9
        modified: 2020-07-22T13:29:27.435572Z
        open_issues_count: 0
        path: ('/root/.ansible/roles', '/usr/share/ansible/roles', '/etc/ansible/roles')
        role_type: ANS
        stargazers_count: 0
        travis_status_url: 

nsible-galaxy install子命令从Ansible Galaxy下载角色,并将它安装到控制节点本地。

默认情况下,角色安装到用户的roles_path下的第一个可写目录中。根据为Ansible设置的默认roles_path,角色通常将安装到用户的~/.ansible/roles目录。默认的roles_path可能会被用户当前Ansible配置文件或环境变量ANSIBLE_ROLES_PATH覆盖,这将影响ansible-galaxy的行为。

用户可以通过使用-p DIRECTORY选项,指定具体的目录来安装角色。

[root@ansible roles]# ansible-galaxy  install acandid.mysql
- downloading role 'mysql', owned by acandid
- downloading role from https://github.com/acandid/mysql/archive/master.tar.gz
- extracting acandid.mysql to /root/.ansible/roles/acandid.mysql
- acandid.mysql (master) was installed successfully

[root@ansible roles]# ls ~/.ansible/roles/
acandid.mysql

[root@ansible roles]# ansible-galaxy  install acandid.mysql -p ~/roles/
- downloading role 'mysql', owned by acandid
- downloading role from https://github.com/acandid/mysql/archive/master.tar.gz
- extracting acandid.mysql to /root/roles/acandid.mysql
- acandid.mysql (master) was installed successfully

[root@ansible roles]# ls
acandid.mysql  ansible.cfg  inventory  test  test1  test.yml  timesync

可以使用ansible-galaxy remove子命令本地删除角色(不用-p指定位置 默认移除 ~/.ansible/roles/ 里的)

[root@ansible roles]# ansible-galaxy remove acandid.mysql
- successfully removed acandid.mysql

[root@ansible roles]# ls ~/.ansible/roles/
[root@ansible roles]# ls .
acandid.mysql  ansible.cfg  inventory  test  test1  test.yml  timesync

 ansible-galaxy list子命令列出本地找到的角色。

[root@ansible roles]# ansible-galaxy list
# /root/.ansible/roles
# /usr/share/ansible/roles
- linux-system-roles.certificate, (unknown version)
- linux-system-roles.kdump, (unknown version)
- linux-system-roles.kernel_settings, (unknown version)
- linux-system-roles.logging, (unknown version)
- linux-system-roles.metrics, (unknown version)
- linux-system-roles.nbde_client, (unknown version)
- linux-system-roles.nbde_server, (unknown version)
- linux-system-roles.network, (unknown version)
- linux-system-roles.postfix, (unknown version)
- linux-system-roles.selinux, (unknown version)
- linux-system-roles.storage, (unknown version)
- linux-system-roles.timesync, (unknown version)
- linux-system-roles.tlog, (unknown version)
- rhel-system-roles.certificate, (unknown version)
- rhel-system-roles.kdump, (unknown version)
- rhel-system-roles.kernel_settings, (unknown version)
- rhel-system-roles.logging, (unknown version)
- rhel-system-roles.metrics, (unknown version)
- rhel-system-roles.nbde_client, (unknown version)
............................................
............................................
原文地址:https://www.cnblogs.com/diqiyao/p/14438761.html