ansible包含和导入文件、利用角色简化playbook
1. 管理大型的playbook任务、利用角色简化playbook
当一个playbook中包含了一个大型的服务时,我们可以将其拆分成小的文件,便于管理;也可利用模块化的东西将多个playbook组合为一个playbook,或将单个文件插入到playbook中。这样就可以在多个项目中重复利用单个文件。
2包含或导入文件
- 包含是一个动态的操作,在playbook运行运行期间,ansible会在内容到达时处理所包含的内容。
- 导入是一个静态的操作,在playbook运行之前,在ansible最初解析playbook时预处理导入的内容。就是还没有运行playbook时就已经将所需要的文件导入到所要执行的playbook中了。
2.1导入playbook
- import_playbook命令作用是将包含有play列表的外部文件导入到篇playbook。也就是说把一个或多个playbook导入到要执行的哪个playbook中去。
规则:import_playbook命令只能在playbook的顶层使用,因为我们导入的一般都是一个完整的。
示例:
// 在node2上安装httpd并且将配置文件里的80端口改为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 导入本机的playbook
[root@node1 playbook]# cat main.yml
---
- hosts: node2
tasks:
- name: 开启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 [开启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. 导入和包含任务
// 将一些任务文件到导入到play中
在install文件里面只写任务,将其导入到main文件里面。
[root@node1 playbook]# ansible-playbook main.yml
PLAY [node2] *******************************************************************
TASK [Gathering Facts] *********************************************************
ok: [node2]
TASK [install] *****************************************************************
ok: [node2]
TASK [开启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: 开启httpd
service:
name: httpd
state: started
enabled: yes
[root@node1 playbook]# cat install.yml
- name: install
yum:
name: httpd
state: present
3.1 包含任务文件
[root@node1 playbook]# cat main.yml
---
- hosts: node2
tasks:
- include_tasks: /opt/playbook/install.yml
- name: 开启httpd
service:
name: httpd
state: started
enabled: yes
3.1.1 导入任务文件时,需要注意的地方
- 当使用import_tasks功能时导入时设置的when条件语句将应用于导入的每个任务
- 无法将循环用于import_tasks功能
- 若使用变量来指定要导入的文件名称,则将无法使用主机或组清单变量就是无法将,主机清单作为变量。
- 当运行ansible-playbook --list-tasks以列出playbook中的任务时,可以看到导入任务文件里面的任务。
3.1.2 包含任务文件时需要注意的地方:
- 使用include_tasks功能时,在包含的文件里面有when时就进行判断。
- 如果运行ansible-playbook --list-tasks以列出playbook中的任务时,不会显示包含文件里面的任务内容,但是导入时可以看到任务文件里面的任务
- 不能使用ansible-playbook --start-at-task指定包含任务文件中哪个playbook先执行,playbook遵循的是有序性,具有先后顺序。
- 不能在包含任务文件的文件里面使用notify语句,即使使用也不会触发处理程序,但是可以在包含了整个任务文件的playbook中去使用。
3.2 为外部play和任务定义变量
使用Ansible的导入和包含功能将外部文件中的play或任务合并到playbook中极大地增强了在Ansible环境中重用任务和playbook的能力。为了更大限度的提高任务文件的重可用度,可以设置一些变量。
注意:在包含有多个play的playbook的文件中若要定义变量,只想对某一个play生效,就需要在包含或导入的play文件的下面定义一个变量,若想对所有的playbook都生效就可以在hosts的下面定义变量。
[root@node1 playbook]# ansible-playbook main.yml
PLAY [node2] *******************************************************************
TASK [Gathering Facts] *********************************************************
ok: [node2]
TASK [install] *****************************************************************
ok: [node2]
TASK [开启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: 开启httpd
service:
name: httpd
state: started
enabled: yes
4. 描述角色结构
随着playbook编写,我们可能会发现有很多机会重复利用以前缩写的playbook中的代码。
在实际的生产工作中,这个playbook可能是冗长复杂的,有许多包含和导入的文件,Ansible角色提供了一种方法,让用户能以通用的方式更加轻松地重复利用Ansible代码。我们可以在标准化目录结构中打包所有任务、变量、文件、模板,以及调配基础架构或部署应用所需的其他资源。
4.1 Ansible角色具有下列优点:
- 角色可以分组内容,从而与他人轻松共享代码
- 可以编写角色来定义系统类型的基本要素:Web服务器、数据库服务器、Git存储库,或满足其他用途
- 角色使得较大型项目更容易管理
- 角色可以由不同的管理员并行开发
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中使用时不应更改 |
5. 控制执行的顺序
-
在playbook中的每个play都是按照顺序从上到下的顺序执行
-
角色要写至任务列表的开头,若有第二个playbook,其任务列表需要添加到第一个角色之后。
-
角色处理程序添加到play中的方式与角色任务添加到play中相同,但是要注意的是如果playbook和roles中都有handlers,则优先添加roles里面的handlers,在将playbook中的handlers添加到roles之后。
-
在有些情况下需要在角色任务之前执行一个play任务这时我们就需要
使用pre_tasks这样就可以在角色任务执行之前执行想要执行的任务。
在pre_tasks中的tasks任务和notify、handlers都是优先执行的。 -
在pre_tasks后面就是roles角色任务,角色任务后面跟执行角色任务的角色名。
角色任务的tasks和notify都是在pre_tasks的后面执行 -
tasks就是写要正常要执行的任务,同样的tasks里面的任务要在roles角色任务后面执行。
-
post_tasks在tasks后面执行,post_tasks里面的任务同理在tasks的后面执行。
再执行notify、handlers。 -
在handlers规则中无论notify出现几次都只执行一次,如果pre_tasks、tasks、post_tasks都有notify最后的handlers就会都执行一次
-
所以优先级从大到小就是pre_tasks>roles>tasks>post_tasks>hangdlers。
##利用系统角色重用内容
RHEL系统角色
名称 | 角色作用 |
---|---|
rhel-system-roles.kdump | 配置kdump崩溃恢复服务 |
rhel-system-roles.network | 配置网络接口 |
rhel-system-roles.selinux | 配置和管理SELinux自定义,包括selinux模式、文件以及端口上下文 |
rhel-system-roles.timesync | 使用网络时间协议或精确时间协议配置时间同步 |
rhel-system-roles.postfix | 使用Postfix服务将每个主机配置为邮件传输代理 |
rhel-system-roles.firewalld | 配置主机的防火墙 |
rhel-systemctl-roles.tuned | 配置tuned服务,以调优系统性能 |
6. 安装系统用户
[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.
上次元数据过期检查:0:23:47 前,执行于 2021年08月01日 星期日 19时08分34秒。
依赖关系解决。
==========================================================================
软件包 架构 版本 仓库 大小
==========================================================================
安装:
rhel-system-roles noarch 1.0-10.el8_1 AppStream 175 k
事务概要
==========================================================================
安装 1 软件包
总计:175 k
安装大小:1.1 M
下载软件包:
运行事务检查
事务检查成功。
运行事务测试
事务测试成功。
运行事务
准备中 : 1/1
安装 : rhel-system-roles-1.0-10.el8_1.noarch 1/1
验证 : rhel-system-roles-1.0-10.el8_1.noarch 1/1
Installed products updated.
已安装:
rhel-system-roles-1.0-10.el8_1.noarch
完毕!
6.1系统用户位置
[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 访问RHEL系统角色的文档
RHEL系统角色的文档位于/usr/share/doc/rhel-system-roles-/目录中
[root@node1 roles]# ls /usr/share/doc/rhel-system-roles/
kdump network postfix selinux storage timesync
时间同步角色
timesync_ntp_servers属性
属性 | 用途 |
---|---|
hostname | 要与其同步的NTP服务器的主机名。 |
iburst | 一个布尔值,用于启用或禁用快速初始同步。在角色中默认为no,但通常应该将属性设为yes。 |
7. 系统角色的使用
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: //使用rhel-system-roles.timesync角色在受管主机上面配置NTP时间同步
- hostname: time.aliyun.com //hostname是指定要同步的NTP服务器,这里我们使用阿里云
iburst: yes //这里的iburst是用于启用或禁用快速初始同步的。
roles:
- timesync 使用timesync这个角色
7.1 SELINUX角色使用
selinux角色可以执行的任务包括:
- 设置enforcing或permissive模式
- 对文件系统层次结构的各部分运行restorecon
- 设置SELinux布尔值
- 永久设置SELinux文件上下文
- 设置SELinux用户映射
示例
// 将selinu设置为开启状态
[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
示例:
将httpd改为82端口,并修改selinux规则后能成功访问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. ansible-galaxy的用法
[root@node1 roles]# ansible-galaxy search 'httpd
可以进行联网搜索roles
[root@node1 roles]# ansible-galaxy info acandid.httpd
用来查看roles基本信息
[root@node1 roles]# ansible-galaxy install acandid.httpd -p /ansible/roles
下载roles到特定的目录中
[root@node1 roles]# ansible-galaxy list -p roles/
列出本地有哪些roles
8.1 创建角色框架
创建一个目录用来创建角色
[root@node1 ~]# mkdir -p ~/ansible/roles
使用下面的命令初始化一个roles
[root@node1 roles]# ansible-galaxy init now_role
- Role now_role was created successfully
8.2 roles规范的目录结构
目录 | 作用 |
---|---|
defualts/main.yml | 定义变量的缺省值,优先级较低 |
files | 存储静态文件的目录 |
handlers/main.yml | 定义handlers |
meta/main.yml | 写作者、版本等描述信息 |
tasks/main.yml | 定义任务的地方 |
templates | 存放动态数据文件的地方(模板文件) |
vars/main.yml | 定义变量,优先级高 |
8.3 在playbook中调用role
有两中方法:
- 在与role平级的目录下创建一个playbook进行调用
- 在ansible.cfg这个配置文件里面加上roles_path = 告诉你的role路径在哪
8.4 角色的使用方式
示例:
这里我选择在配置文件里面添加
使用templates目录来调用模块事实在var目录调用变量,并在node2主机上进行输出。
[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
这里的all.yml的文件需要在与now_role目录平级的地方使用。
[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 通过变量更改角色的行为
通过编写角色利用默认变量来改变角色行为,让其更具灵活性。这有助于角色适应更多的应用场景,可在不同的上下文中使用。
通过一下方式定义的变量default目录中定义的变量将会被覆盖:
- 在清单文件中定义,作为主机变量或组变量
- 在playbook项目的group、vars或host、vars目录下的YAML文件中定义的变量。
- 作为变量嵌套在play的vars关键字中定义
- 在play的roles关键字中包含该角色时作为变量定义。