1. 描述角色结构
1.1 利用角色构造ansible playbook
Ansible角色具有下列优点:
- 角色可以分组内容,从而与他人轻松共享代码
- 可以编写角色来定义系统类型的基本要素:Web服务器、数据库服务器、Git存储库,或满足其他用途
- 角色使得较大型项目更容易管理
- 角色可以由不同的管理员并行开发
除了自行编写、使用、重用和共享角色外,还可以从其他来源获取角色。一些角色已包含在rhel-system-roles软件包中,用户也可以从Ansible Galaxy网站获取由社区提供支持的许多角色。
1.2 检查ansible角色结构
Ansible角色由子目录和文件的标准化结构定义。顶级目录定义角色本身的名称。文件整理到子目录中,子目录按照各个文件在角色中的用途进行命名,如tasks和handlers。files和templates子目录中包含由其他YAML文件中的任务引用的文件。
site.yml
webservers.yml
fooservers.yml
roles/
common/
tasks/
handlers/
files/
templates/
vars/
defaults/
meta/
webservers/
tasks/
defaults/
meta/
以下tree命令显示了user.example角色的目录结构:
[root@localhost roles]# tree user.example/
user.example/
├── 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中使用时不应更改。 |
并非每个角色都拥有所有这些目录。
1.3 定义变量和默认值
角色变量通过在角色目录层次结构中创建含有键值对的vars/main.yml文件来定义。与其他变量一样,这些角色变量在角色YAML文件中引用:{{ VAR_NAME }}。这些变量具有较高的优先级,无法被清单变量覆盖。这些变量旨在供角色的内部功能使用。
默认变量允许为可在play中使用的变量设置默认值,以配置角色或自定义其行为。它们通过在角色目录层次结构中创建含有键值对的defaults/main.yml文件来定义。默认变量具有任何可用变量中最低的优先级。它们很容易被包括清单变量在内的任何其他变量覆盖。这些变量旨在让用户在编写使用该角色的play时可以准确地自定义或控制它将要执行的操作。它们可用于向角色提供所需的信息,以正确地配置或部署某些对象。
在vars/main.yml或defaults/main.yml中定义具体的变量,但不要在两者中都定义。有意要覆盖变量的值时,应使用默认变量。
注意:
角色不应该包含特定于站点的数据。它们绝对不应包含任何机密,如密码或私钥。
这是因为角色应该是通用的,可以重复利用并自由共享。特定于站点的详细信息不应硬编码到角色中。
机密应当通过其他途径提供给角色。这是用户可能要在调用角色时设置角色变量的一个原因。play中设置的角色变量可以提供机密,或指向含有该机密的Ansible
1.4 在playbook中使用ansible角色
例子:现需要同步受控机的时间
查看受控机的时间
[root@localhost ~]# date
Tue May 4 01:30:30 CST 1999
主控机创建test目录,编写一个同步时间的playbook
[root@localhost ~]# ls
abc ansible.cfg playbook
anaconda-ks.cfg hosts test
[root@localhost ~]# cd test/
[root@localhost test]# ls
roles timesync.yml
[root@localhost test]# vim timesync.yml
---
- hosts: all
vars:
timesync_ntp_servers:
- hostname: time1.aliyun.com 去哪里同步
iburst: yes 固定写法
minpoll: 3 同步时间:每隔3秒同步一下
roles:
- role: roles/timesync
[root@localhost test]# ansible-playbook timesync.yml
PLAY [all] ***************************************************************************************************************************
TASK [Gathering Facts] ***************************************************************************************************************
ok: [web1]
TASK [roles/timesync : Check if only NTP is needed] **********************************************************************************
ok: [web1]
TASK [roles/timesync : Check if single PTP is needed] ********************************************************************************
skipping: [web1]
TASK [roles/timesync : Check if both NTP and PTP are needed] *************************************************************************
skipping: [web1]
TASK [roles/timesync : Determine current NTP provider] *******************************************************************************
ok: [web1]
TASK [roles/timesync : Select NTP provider] ******************************************************************************************
ok: [web1]
TASK [roles/timesync : Install chrony] ***********************************************************************************************
ok: [web1]
TASK [roles/timesync : Install ntp] **************************************************************************************************
skipping: [web1]
TASK [roles/timesync : Install linuxptp] *********************************************************************************************
skipping: [web1]
TASK [roles/timesync : Run phc_ctl on PTP interface] *********************************************************************************
skipping: [web1]
TASK [roles/timesync : Check if PTP interface supports HW timestamping] **************************************************************
skipping: [web1]
TASK [roles/timesync : Get chrony version] *******************************************************************************************
ok: [web1]
TASK [roles/timesync : Get ntp version] **********************************************************************************************
skipping: [web1]
TASK [roles/timesync : Generate chrony.conf file] ************************************************************************************
changed: [web1]
TASK [roles/timesync : Generate chronyd sysconfig file] ******************************************************************************
ok: [web1]
TASK [roles/timesync : Generate ntp.conf file] ***************************************************************************************
skipping: [web1]
TASK [roles/timesync : Generate ntpd sysconfig file] *********************************************************************************
skipping: [web1]
TASK [roles/timesync : Generate ptp4l.conf file] *************************************************************************************
skipping: [web1]
TASK [roles/timesync : Generate ptp4l sysconfig file] ********************************************************************************
skipping: [web1]
TASK [roles/timesync : Generate phc2sys sysconfig file] ******************************************************************************
skipping: [web1]
TASK [roles/timesync : Generate timemaster.conf file] ********************************************************************************
skipping: [web1]
TASK [roles/timesync : Update network sysconfig file] ********************************************************************************
ok: [web1]
TASK [roles/timesync : Disable chronyd] **********************************************************************************************
skipping: [web1]
TASK [roles/timesync : Disable ntpd] *************************************************************************************************
fatal: [web1]: FAILED! => {"changed": false, "msg": "Could not find the requested service ntpd: host"}
...ignoring
TASK [roles/timesync : Disable ntpdate] **********************************************************************************************
fatal: [web1]: FAILED! => {"changed": false, "msg": "Could not find the requested service ntpdate: host"}
...ignoring
TASK [roles/timesync : Disable sntp] *************************************************************************************************
fatal: [web1]: FAILED! => {"changed": false, "msg": "Could not find the requested service sntp: host"}
...ignoring
TASK [roles/timesync : Disable ptp4l] ************************************************************************************************
fatal: [web1]: FAILED! => {"changed": false, "msg": "Could not find the requested service ptp4l: host"}
...ignoring
TASK [roles/timesync : Disable phc2sys] **********************************************************************************************
fatal: [web1]: FAILED! => {"changed": false, "msg": "Could not find the requested service phc2sys: host"}
...ignoring
TASK [roles/timesync : Disable timemaster] *******************************************************************************************
fatal: [web1]: FAILED! => {"changed": false, "msg": "Could not find the requested service timemaster: host"}
...ignoring
TASK [roles/timesync : Enable chronyd] ***********************************************************************************************
ok: [web1]
TASK [roles/timesync : Enable ntpd] **************************************************************************************************
skipping: [web1]
TASK [roles/timesync : Enable ptp4l] *************************************************************************************************
skipping: [web1]
TASK [roles/timesync : Enable phc2sys] ***********************************************************************************************
skipping: [web1]
TASK [roles/timesync : Enable timemaster] ********************************************************************************************
skipping: [web1]
RUNNING HANDLER [roles/timesync : restart chronyd] ***********************************************************************************
changed: [web1]
PLAY RECAP ***************************************************************************************************************************
web1 : ok=17 changed=2 unreachable=0 failed=0 skipped=18 rescued=0 ignored=6
查看受控机的时间是否同步
[root@localhost ~]# date
Wed Sep 16 21:00:09 CST 2020 时间已被同步
[root@localhost ~]# systemctl status phc2sys 没有发现该服务表示服务没有启动
Unit phc2sys.service could not be found.
注意:
因为内嵌设置的角色变量(角色参数)具有非常高的优先级。它们将覆盖大多数其他变量。所以不要重复使用内嵌设置在play中任何其他位置的任何角色变量的名称,因为角色变量的值将覆盖清单变量和任何play中的vars。
1.5 控制执行顺序
pre_tasks ,列在此部分中的所有任务将在执行任何角色之前执行。如果这些任务中有任何一个通知了处理程序,则这些处理程序任务也在角色或普通任务之前执行。
post_tasks ,这些任务在play的普通任务和它们通知的任何处理程序运行之后执行。
主控机上编写一个角色
[root@localhost test]# vim myplay.yml
---
- hosts: all
gather_facts: no
pre_tasks: 不论排序如何,都先执行pre_tasks任务;再执行tasks任务;后执行post_tasks任务
- name: pre_task
debug:
msg: "hehe"
changed_when: True 只有执行任务结果为chenged时,才会通知notify执行handlers
notify:
- insert data
tasks:
- name: task
command: "echo 'haha'"
notify:
- insert data
post_tasks:
- name: post_task
command: "echo 'post'"
notify:
- insert data
handlers:
- name: insert data
shell: "echo 123 >> /tmp/abc" 在abc里写入123,因执行了3遍handlers,所以受控机的abc里应该有3个123
[root@localhost test]# ansible-playbook myplay.yml
PLAY [all] *********************************************************************
TASK [pre_task] ****************************************************************
changed: [web1] => {
"msg": "hehe"
}
RUNNING HANDLER [insert data] **************************************************
changed: [web1]
TASK [task] ********************************************************************
changed: [web1]
RUNNING HANDLER [insert data] **************************************************
changed: [web1]
TASK [post_task] ***************************************************************
changed: [web1]
RUNNING HANDLER [insert data] **************************************************
changed: [web1]
PLAY RECAP *********************************************************************
web1 : ok=6 changed=6 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
查看受控机
[root@localhost tmp]# ls 原本tmp目录下并没有abc
systemd-private-dc540eab1a59456ea6caf4d4d5b0e784-chronyd.service-GIV4xY
vmware-root_948-2688554130
vmware-root_963-4256545027
vmware-root_967-4248221830
vmware-root_968-2965448017
vmware-root_969-4281777807
[root@localhost tmp]# ls
abc 执行任务之后就有了abc
systemd-private-dc540eab1a59456ea6caf4d4d5b0e784-chronyd.service-GIV4xY
vmware-root_948-2688554130
vmware-root_963-4256545027
vmware-root_967-4248221830
vmware-root_968-2965448017
vmware-root_969-4281777807
[root@localhost tmp]# cat abc abc里有3个123
123
123
123
- 例二:除了将角色包含在play的roles部分中外,也可以使用普通任务将角色添加到play中。使用include_role模块可以动态包含角色,使用import_role模块则可静态导入角色。
注意 :
include_role模块是在Ansible 2.3中新增的,而import_role模块则是在Ansible 2.4中新增的。
[root@localhost test]# ls
myplay.yml
[root@localhost test]# mkdir roles
[root@localhost test]# cd roles/
[root@localhost roles]# cp -a /usr/share/ansible/roles/rhel-system-roles.timesync .
[root@localhost roles]# ls
rhel-system-roles.timesync
[root@localhost roles]# mv rhel-system-roles.timesync timesync
[root@localhost roles]# ls
timesync
[root@localhost roles]# cd timesync/
[root@localhost timesync]# ls
COPYING handlers README.html templates
defaults library README.md tests
examples meta tasks vars
[root@localhost timesync]# less README.md 查看系统文档
......
- hosts: targets
vars:
timesync_ntp_servers: 要用到此模块
- hostname: foo.example.com
iburst: yes
- hostname: bar.example.com
iburst: yes
- hostname: baz.example.com
iburst: yes
roles:
- rhel-system-roles.timesync
......
[root@localhost test]# vim myplay.yml
---
- hosts: all
tasks:
- name: second task
debug:
msg: "second task"
- name: timesync
include_role:
name: roles/timesync
vars:
timesync_ntp_servers:
- hostname: time1.aliyun.com
iburst: yes
[root@localhost test]# ansible-playbook myplay.yml
PLAY [all] *********************************************************************
TASK [Gathering Facts] *********************************************************
ok: [web1]
TASK [second task] *************************************************************
ok: [web1] => {
"msg": "second task"
}
TASK [timesync] ****************************************************************
TASK [roles/timesync : Check if only NTP is needed] ****************************
ok: [web1]
TASK [roles/timesync : Check if single PTP is needed] **************************
skipping: [web1]
TASK [roles/timesync : Check if both NTP and PTP are needed] *******************
skipping: [web1]
TASK [roles/timesync : Determine current NTP provider] *************************
ok: [web1]
TASK [roles/timesync : Select NTP provider] ************************************
ok: [web1]
TASK [roles/timesync : Install chrony] *****************************************
ok: [web1]
TASK [roles/timesync : Install ntp] ********************************************
skipping: [web1]
TASK [roles/timesync : Install linuxptp] ***************************************
skipping: [web1]
TASK [roles/timesync : Run phc_ctl on PTP interface] ***************************
skipping: [web1]
TASK [roles/timesync : Check if PTP interface supports HW timestamping] ********
skipping: [web1]
TASK [roles/timesync : Get chrony version] *************************************
ok: [web1]
TASK [roles/timesync : Get ntp version] ****************************************
skipping: [web1]
TASK [roles/timesync : Generate chrony.conf file] ******************************
changed: [web1]
TASK [roles/timesync : Generate chronyd sysconfig file] ************************
ok: [web1]
TASK [roles/timesync : Generate ntp.conf file] *********************************
skipping: [web1]
TASK [roles/timesync : Generate ntpd sysconfig file] ***************************
skipping: [web1]
TASK [roles/timesync : Generate ptp4l.conf file] *******************************
skipping: [web1]
TASK [roles/timesync : Generate ptp4l sysconfig file] **************************
skipping: [web1]
TASK [roles/timesync : Generate phc2sys sysconfig file] ************************
skipping: [web1]
TASK [roles/timesync : Generate timemaster.conf file] **************************
skipping: [web1]
TASK [roles/timesync : Update network sysconfig file] **************************
ok: [web1]
TASK [roles/timesync : Disable chronyd] ****************************************
skipping: [web1]
TASK [roles/timesync : Disable ntpd] *******************************************
fatal: [web1]: FAILED! => {"changed": false, "msg": "Could not find the requested service ntpd: host"}
...ignoring
TASK [roles/timesync : Disable ntpdate] ****************************************
fatal: [web1]: FAILED! => {"changed": false, "msg": "Could not find the requested service ntpdate: host"}
...ignoring
TASK [roles/timesync : Disable sntp] *******************************************
fatal: [web1]: FAILED! => {"changed": false, "msg": "Could not find the requested service sntp: host"}
...ignoring
TASK [roles/timesync : Disable ptp4l] ******************************************
fatal: [web1]: FAILED! => {"changed": false, "msg": "Could not find the requested service ptp4l: host"}
...ignoring
TASK [roles/timesync : Disable phc2sys] ****************************************
fatal: [web1]: FAILED! => {"changed": false, "msg": "Could not find the requested service phc2sys: host"}
...ignoring
TASK [roles/timesync : Disable timemaster] *************************************
fatal: [web1]: FAILED! => {"changed": false, "msg": "Could not find the requested service timemaster: host"}
...ignoring
TASK [roles/timesync : Enable chronyd] *****************************************
ok: [web1]
TASK [roles/timesync : Enable ntpd] ********************************************
skipping: [web1]
TASK [roles/timesync : Enable ptp4l] *******************************************
skipping: [web1]
TASK [roles/timesync : Enable phc2sys] *****************************************
skipping: [web1]
TASK [roles/timesync : Enable timemaster] **************************************
skipping: [web1]
RUNNING HANDLER [roles/timesync : restart chronyd] *****************************
changed: [web1]
PLAY RECAP *********************************************************************
web1 : ok=18 changed=2 unreachable=0 failed=0 skipped=18 rescued=0 ignored=6
查看版本
[root@localhost test]# ansible --version
ansible 2.9.11
config file = /etc/ansible/ansible.cfg
configured module search path = ['/root/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
ansible python module location = /usr/lib/python3.6/site-packages/ansible
executable location = /usr/bin/ansible
python version = 3.6.8 (default, Dec 5 2019, 15:45:45) [GCC 8.3.1 20191121 (Red Hat 8.3.1-5)]
2. 利用系统角色重用内容
2.1 红帽企业Linux系统角色
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服务,以调优系统性能 |
2.2 安装RHEL系统角色
RHEL系统角色由rhel-system-roles软件包提供,该软件包可从AppStream流获取
[root@localhost test]# 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: 2:42:15 ago on Thu 17 Sep 2020 12:58:19 PM CST.
Package rhel-system-roles-1.0-10.el8_1.noarch is already installed.
Dependencies resolved.
Nothing to do.
Complete!
HEL系统角色位于/usr/share/ansible/roles目录中
[root@localhost ~]# ls /usr/share/ansible/roles/
linux-system-roles.kdump
linux-system-roles.network
linux-system-roles.postfix
linux-system-roles.selinux
linux-system-roles.storage
linux-system-roles.timesync
rhel-system-roles.kdump
rhel-system-roles.network
rhel-system-roles.postfix
rhel-system-roles.selinux
rhel-system-roles.storage
rhel-system-roles.timesync
如果在当前Ansible配置文件中覆盖了roles_path,设置了环境变量ANSIBLE_ROLES_PATH,或者roles_path中更早列出的目录下存在另一个同名的角色,则Ansible可能无法找到系统角色。
2.3 访问RHEL系统角色的文档
[root@localhost ~]# cd /usr/share/doc/rhel-system-roles/
[root@localhost rhel-system-roles]# ls
kdump network postfix selinux storage timesync
[root@localhost rhel-system-roles]# cd timesync/
[root@localhost timesync]# ls
COPYING README.html
example-timesync-playbook.yml README.md
example-timesync-pool-playbook.yml
2.4 时间同步角色
该角色的详细记录位于/usr/share/doc/rhel-system-roles/timesync目录下的README.md中
[root@localhost ~]# cd /usr/share/doc/rhel-system-roles/
[root@localhost rhel-system-roles]# ls
kdump network postfix selinux storage timesync
[root@localhost rhel-system-roles]# cd timesync/
[root@localhost timesync]# ls
COPYING README.html
example-timesync-playbook.yml README.md
example-timesync-pool-playbook.yml
[root@localhost timesync]# less README.md 此文件说明了影响角色行为的所有变量,还包含演示了不同时间同步配置的三个playbook代码片段。
timesync_ntp_servers属性
属性 | 用途 |
---|---|
hostname | 要与其同步的NTP服务器的主机名。 |
iburst | 一个布尔值,用于启用或禁用快速初始同步。在角色中默认为no,但通常应该将属性设为yes |
例:
[root@localhost test]# vim myplay.yml
---
- hosts: localhost
vars:
timesync_ntp_servers:
- hostname: time1.aliyun.com
iburst: yes
timezone: Asia/Shanghai
roles:
- role: roles/timesync
tasks:
- name: set timezone
timezone: 在角色中没有用该模块
name: "{{ timezone }}"
[root@localhost test]# ansible-playbook myplay.yml
PLAY [localhost] ***************************************************************
TASK [Gathering Facts] *********************************************************
ok: [localhost]
TASK [roles/timesync : Check if only NTP is needed] ****************************
ok: [localhost]
TASK [roles/timesync : Check if single PTP is needed] **************************
skipping: [localhost]
TASK [roles/timesync : Check if both NTP and PTP are needed] *******************
skipping: [localhost]
TASK [roles/timesync : Determine current NTP provider] *************************
ok: [localhost]
TASK [roles/timesync : Select NTP provider] ************************************
ok: [localhost]
TASK [roles/timesync : Install chrony] *****************************************
changed: [localhost]
TASK [roles/timesync : Install ntp] ********************************************
skipping: [localhost]
TASK [roles/timesync : Install linuxptp] ***************************************
skipping: [localhost]
TASK [roles/timesync : Run phc_ctl on PTP interface] ***************************
skipping: [localhost]
TASK [roles/timesync : Check if PTP interface supports HW timestamping] ********
skipping: [localhost]
TASK [roles/timesync : Get chrony version] *************************************
ok: [localhost]
TASK [roles/timesync : Get ntp version] ****************************************
skipping: [localhost]
TASK [roles/timesync : Generate chrony.conf file] ******************************
changed: [localhost]
TASK [roles/timesync : Generate chronyd sysconfig file] ************************
changed: [localhost]
TASK [roles/timesync : Generate ntp.conf file] *********************************
skipping: [localhost]
TASK [roles/timesync : Generate ntpd sysconfig file] ***************************
skipping: [localhost]
TASK [roles/timesync : Generate ptp4l.conf file] *******************************
skipping: [localhost]
TASK [roles/timesync : Generate ptp4l sysconfig file] **************************
skipping: [localhost]
TASK [roles/timesync : Generate phc2sys sysconfig file] ************************
skipping: [localhost]
TASK [roles/timesync : Generate timemaster.conf file] **************************
skipping: [localhost]
TASK [roles/timesync : Update network sysconfig file] **************************
changed: [localhost]
TASK [roles/timesync : Disable chronyd] ****************************************
skipping: [localhost]
TASK [roles/timesync : Disable ntpd] *******************************************
fatal: [localhost]: FAILED! => {"changed": false, "msg": "Could not find the requested service ntpd: host"}
...ignoring
TASK [roles/timesync : Disable ntpdate] ****************************************
fatal: [localhost]: FAILED! => {"changed": false, "msg": "Could not find the requested service ntpdate: host"}
...ignoring
TASK [roles/timesync : Disable sntp] *******************************************
fatal: [localhost]: FAILED! => {"changed": false, "msg": "Could not find the requested service sntp: host"}
...ignoring
TASK [roles/timesync : Disable ptp4l] ******************************************
fatal: [localhost]: FAILED! => {"changed": false, "msg": "Could not find the requested service ptp4l: host"}
...ignoring
TASK [roles/timesync : Disable phc2sys] ****************************************
fatal: [localhost]: FAILED! => {"changed": false, "msg": "Could not find the requested service phc2sys: host"}
...ignoring
TASK [roles/timesync : Disable timemaster] *************************************
fatal: [localhost]: FAILED! => {"changed": false, "msg": "Could not find the requested service timemaster: host"}
...ignoring
TASK [roles/timesync : Enable chronyd] *****************************************
changed: [localhost]
TASK [roles/timesync : Enable ntpd] ********************************************
skipping: [localhost]
TASK [roles/timesync : Enable ptp4l] *******************************************
skipping: [localhost]
TASK [roles/timesync : Enable phc2sys] *****************************************
skipping: [localhost]
TASK [roles/timesync : Enable timemaster] **************************************
skipping: [localhost]
TASK [set timezone] ************************************************************
ok: [localhost]
RUNNING HANDLER [roles/timesync : restart chronyd] ***************************** 这一步执行了就表示时间改回来了
changed: [localhost]
PLAY RECAP *********************************************************************
localhost : ok=18 changed=6 unreachable=0 failed=0 skipped=18 rescued=0 ignored=6
[root@localhost test]# date
Thu Sep 17 16:25:44 CST 2020
- 要设置不同的时区,可以使用tzselect命令查询其他有效的值
[root@localhost test]# tzselect
Please identify a location so that time zone rules can be set correctly.
Please select a continent, ocean, "coord", or "TZ".
1) Africa
2) Americas
3) Antarctica
4) Asia
5) Atlantic Ocean
6) Australia
7) Europe
8) Indian Ocean
9) Pacific Ocean
10) coord - I want to use geographical coordinates.
11) TZ - I want to specify the time zone using the Posix TZ format.
#? ^C
- 在play的vars部分中设置角色变量,但更好的做法可能是将它们配置为主机或主机组的清单变量。
[root@localhost test]# mkdir group_vars 创建一个组
[root@localhost test]# mkdir group_vars/all all表示所有的组
[root@localhost test]# vim group_vars/all/timesync.yml 将变量写到该文件里
timesync_ntp_servers:
- hostname: time1.aliyun.com
iburst: yes
timezone: Asia/Shanghai
[root@localhost test]# vim myplay.yml
---
- hosts: all
roles:
- role: roles/timesync
tasks:
- name: set timezone
timezone:
name: "{{ timezone }}"
2.5 调用SELinux角色
查看受控机selinux状态为enforcing
[root@localhost ~]# cat /etc/sysconfig/selinux
# This file controls the state of SELinux on the system.
# SELINUX= can take one of these three values:
# enforcing - SELinux security policy is enforced.
# permissive - SELinux prints warnings instead of enforcing.
# disabled - No SELinux policy is loaded.
SELINUX=enforcing
# SELINUXTYPE= can take one of these three values:
# targeted - Targeted processes are protected,
# minimum - Modification of targeted policy. Only selected processes are protected.
# mls - Multi Level Security protection.
SELINUXTYPE=targeted
[root@localhost ~]# getenforce
Enforcing
[root@localhost test]# vim myplay.yml
---
- hosts: all
vars:
selinux_policy: targeted
selinux_state: disabled
tasks:
- name: apply selinux
block:
- include_role:
name: rhel-system-roles.selinux
rescue:
- name: sdlkjs
fail:
when: not selinux_reboot_required
- name: reboot
reboot:
- include_role:
name: rhel-system-roles.selinux
[root@localhost test]# ansible-playbook myplay.yml
PLAY [all] *********************************************************************
TASK [Gathering Facts] *********************************************************
ok: [web1]
TASK [include_role : rhel-system-roles.selinux] ********************************
TASK [rhel-system-roles.selinux : Install SELinux python2 tools] ***************
skipping: [web1]
TASK [rhel-system-roles.selinux : Install SELinux python3 tools] ***************
ok: [web1]
TASK [rhel-system-roles.selinux : refresh facts] *******************************
ok: [web1]
TASK [rhel-system-roles.selinux : Install SELinux tool semanage on Fedora] *****
ok: [web1]
TASK [rhel-system-roles.selinux : Set permanent SELinux state if enabled] ******
[WARNING]: SELinux state temporarily changed from 'enforcing' to 'permissive'.
State change will take effect next reboot.
changed: [web1]
TASK [rhel-system-roles.selinux : Set permanent SELinux state if disabled] *****
skipping: [web1]
TASK [rhel-system-roles.selinux : Set ansible facts if needed] *****************
ok: [web1]
TASK [rhel-system-roles.selinux : Fail if reboot is required] ******************
fatal: [web1]: FAILED! => {"changed": false, "msg": "Reboot is required to apply changes. Re-execute the role after boot."}
TASK [sdlkjs] ******************************************************************
skipping: [web1]
TASK [reboot] ******************************************************************
changed: [web1]
TASK [include_role : rhel-system-roles.selinux] ********************************
TASK [rhel-system-roles.selinux : Install SELinux python2 tools] ***************
skipping: [web1]
TASK [rhel-system-roles.selinux : Install SELinux python3 tools] ***************
ok: [web1]
TASK [rhel-system-roles.selinux : refresh facts] *******************************
ok: [web1]
TASK [rhel-system-roles.selinux : Install SELinux tool semanage on Fedora] *****
ok: [web1]
TASK [rhel-system-roles.selinux : Set permanent SELinux state if enabled] ******
skipping: [web1]
TASK [rhel-system-roles.selinux : Set permanent SELinux state if disabled] *****
ok: [web1]
TASK [rhel-system-roles.selinux : Set ansible facts if needed] *****************
ok: [web1]
TASK [rhel-system-roles.selinux : Fail if reboot is required] ******************
skipping: [web1]
TASK [rhel-system-roles.selinux : debug] ***************************************
ok: [web1] => {
"msg": "SELinux is disabled on system - some SELinux modules can crash"
}
TASK [rhel-system-roles.selinux : Drop all local modifications] ****************
skipping: [web1]
TASK [rhel-system-roles.selinux : Purge all SELinux boolean local modifications] ***
skipping: [web1]
TASK [rhel-system-roles.selinux : Purge all SELinux file context local modifications] ***
skipping: [web1]
TASK [rhel-system-roles.selinux : Purge all SELinux port local modifications] ***
skipping: [web1]
TASK [rhel-system-roles.selinux : Purge all SELinux login local modifications] ***
skipping: [web1]
TASK [rhel-system-roles.selinux : Reload SELinux policy] ***********************
skipping: [web1]
TASK [rhel-system-roles.selinux : Set SELinux booleans] ************************
TASK [rhel-system-roles.selinux : Set SELinux file contexts] *******************
TASK [rhel-system-roles.selinux : Restore SELinux labels on filesystem tree] ***
TASK [rhel-system-roles.selinux : Restore SELinux labels on filesystem tree in check mode] ***
TASK [rhel-system-roles.selinux : Set an SELinux label on a port] **************
TASK [rhel-system-roles.selinux : Set linux user to SELinux user mapping] ******
PLAY RECAP *********************************************************************
web1 : ok=13 changed=2 unreachable=0 failed=0 skipped=18 rescued=1 ignored=0
受控机selinux状态为disabled
[root@localhost ~]# cat /etc/sysconfig/selinux
# This file controls the state of SELinux on the system.
# SELINUX= can take one of these three values:
# enforcing - SELinux security policy is enforced.
# permissive - SELinux prints warnings instead of enforcing.
# disabled - No SELinux policy is loaded.
SELINUX=disabled
# SELINUXTYPE= can take one of these three values:
# targeted - Targeted processes are protected,
# minimum - Modification of targeted policy. Only selected processes are protected.
# mls - Multi Level Security protection.
SELINUXTYPE=targeted
[root@localhost ~]# getenforce
Disabled
2.6 配置SELinux角色
例一:将httpd_enable_homedirs永久设为on
查看受控机状态为off
[root@localhost ~]# semanage boolean -l|grep -i "httpd_enable_homedirs"
httpd_enable_homedirs (off , off) Allow httpd to enable homedirs
[root@localhost test]# vim myplay.yml
---
- hosts: all
vars:
selinux_booleans:
- name: httpd_enable_homedirs
state: on
persistent: yes
roles:
- role: rhel-system-roles.selinux
[root@localhost test]# ansible-playbook myplay.yml
PLAY [all] *********************************************************************
TASK [Gathering Facts] *********************************************************
ok: [web1]
TASK [rhel-system-roles.selinux : Install SELinux python2 tools] ***************
skipping: [web1]
TASK [rhel-system-roles.selinux : Install SELinux python3 tools] ***************
ok: [web1]
TASK [rhel-system-roles.selinux : refresh facts] *******************************
ok: [web1]
TASK [rhel-system-roles.selinux : Install SELinux tool semanage on Fedora] *****
ok: [web1]
TASK [rhel-system-roles.selinux : Set permanent SELinux state if enabled] ******
skipping: [web1]
TASK [rhel-system-roles.selinux : Set permanent SELinux state if disabled] *****
skipping: [web1]
TASK [rhel-system-roles.selinux : Set ansible facts if needed] *****************
ok: [web1]
TASK [rhel-system-roles.selinux : Fail if reboot is required] ******************
skipping: [web1]
TASK [rhel-system-roles.selinux : debug] ***************************************
skipping: [web1]
TASK [rhel-system-roles.selinux : Drop all local modifications] ****************
skipping: [web1]
TASK [rhel-system-roles.selinux : Purge all SELinux boolean local modifications] ***
skipping: [web1]
TASK [rhel-system-roles.selinux : Purge all SELinux file context local modifications] ***
skipping: [web1]
TASK [rhel-system-roles.selinux : Purge all SELinux port local modifications] ***
skipping: [web1]
TASK [rhel-system-roles.selinux : Purge all SELinux login local modifications] ***
skipping: [web1]
TASK [rhel-system-roles.selinux : Reload SELinux policy] ***********************
changed: [web1]
TASK [rhel-system-roles.selinux : Set SELinux booleans] ************************
changed: [web1] => (item={'name': 'httpd_enable_homedirs', 'state': True, 'persistent': True})
TASK [rhel-system-roles.selinux : Set SELinux file contexts] *******************
TASK [rhel-system-roles.selinux : Restore SELinux labels on filesystem tree] ***
TASK [rhel-system-roles.selinux : Restore SELinux labels on filesystem tree in check mode] ***
TASK [rhel-system-roles.selinux : Set an SELinux label on a port] **************
TASK [rhel-system-roles.selinux : Set linux user to SELinux user mapping] ******
PLAY RECAP *********************************************************************
web1 : ok=7 changed=2 unreachable=0 failed=0 skipped=15 rescued=0 ignored=0
查看受控机状态为on
[root@localhost ~]# semanage boolean -l|grep -i "httpd_enable_homedirs"
httpd_enable_homedirs (on , on) Allow httpd to enable homedirs
- 例二:永久设置的文件的安全上下文
[root@localhost ~]# mkdir /opt/www 受控机创建一个目录
[root@localhost ~]# touch /opt/www/abc 目录下面创一个文件
[root@localhost ~]# ls -Z /opt/
unconfined_u:object_r:usr_t:s0 hosts
unconfined_u:object_r:usr_t:s0 www 此时www没有安全上下文
[root@localhost ~]# ls -Z /opt/www
unconfined_u:object_r:usr_t:s0 abc 此时abc也没有安全上下文
当只给/opt/www设安全上下文时
[root@localhost test]# vim myplay.yml
---
- hosts: all
vars:
selinux_fcontexts:
- target: /opt/www 只给opt下的目录设上下文
setype: httpd_sys_content_t
state: present
selinux_restore_dirs:
- /opt/www
roles:
- role: rhel-system-roles.selinux
[root@localhost test]# ansible-playbook myplay.yml
PLAY [all] *********************************************************************
TASK [Gathering Facts] *********************************************************
ok: [web1]
TASK [rhel-system-roles.selinux : Install SELinux python2 tools] ***************
skipping: [web1]
TASK [rhel-system-roles.selinux : Install SELinux python3 tools] ***************
ok: [web1]
TASK [rhel-system-roles.selinux : refresh facts] *******************************
ok: [web1]
TASK [rhel-system-roles.selinux : Install SELinux tool semanage on Fedora] *****
ok: [web1]
TASK [rhel-system-roles.selinux : Set permanent SELinux state if enabled] ******
skipping: [web1]
TASK [rhel-system-roles.selinux : Set permanent SELinux state if disabled] *****
skipping: [web1]
TASK [rhel-system-roles.selinux : Set ansible facts if needed] *****************
ok: [web1]
TASK [rhel-system-roles.selinux : Fail if reboot is required] ******************
skipping: [web1]
TASK [rhel-system-roles.selinux : debug] ***************************************
skipping: [web1]
TASK [rhel-system-roles.selinux : Drop all local modifications] ****************
skipping: [web1]
TASK [rhel-system-roles.selinux : Purge all SELinux boolean local modifications] ***
skipping: [web1]
TASK [rhel-system-roles.selinux : Purge all SELinux file context local modifications] ***
skipping: [web1]
TASK [rhel-system-roles.selinux : Purge all SELinux port local modifications] ***
skipping: [web1]
TASK [rhel-system-roles.selinux : Purge all SELinux login local modifications] ***
skipping: [web1]
TASK [rhel-system-roles.selinux : Reload SELinux policy] ***********************
changed: [web1]
TASK [rhel-system-roles.selinux : Set SELinux booleans] ************************
TASK [rhel-system-roles.selinux : Set SELinux file contexts] *******************
changed: [web1] => (item={'target': '/opt/www', 'setype': 'httpd_sys_content_t', 'state': 'present'})
TASK [rhel-system-roles.selinux : Restore SELinux labels on filesystem tree] ***
changed: [web1] => (item=/opt/www)
TASK [rhel-system-roles.selinux : Restore SELinux labels on filesystem tree in check mode] ***
skipping: [web1] => (item=/opt/www)
TASK [rhel-system-roles.selinux : Set an SELinux label on a port] **************
TASK [rhel-system-roles.selinux : Set linux user to SELinux user mapping] ******
PLAY RECAP *********************************************************************
web1 : ok=8 changed=3 unreachable=0 failed=0 skipped=14 rescued=0 ignored=0
受控机查看www有安全上下文,abc没有安全上下文
[root@localhost ~]# ls -Z /opt/
unconfined_u:object_r:usr_t:s0 hosts
unconfined_u:object_r:httpd_sys_content_t:s0 www
[root@localhost ~]# ls -Z /opt/www
unconfined_u:object_r:usr_t:s0 abc
当给所有的文件设上下文时
[root@localhost test]# vim myplay.yml
---
- hosts: all
vars:
selinux_fcontexts:
- target: /opt/www(/.*)? 给所有的文件设安全上下文,正则表达式
setype: httpd_sys_content_t
state: present
selinux_restore_dirs:
- /opt/www
roles:
- role: rhel-system-roles.selinux
[root@localhost test]# ansible-playbook myplay.yml
PLAY [all] *********************************************************************
TASK [Gathering Facts] *********************************************************
ok: [web1]
TASK [rhel-system-roles.selinux : Install SELinux python2 tools] ***************
skipping: [web1]
TASK [rhel-system-roles.selinux : Install SELinux python3 tools] ***************
ok: [web1]
TASK [rhel-system-roles.selinux : refresh facts] *******************************
ok: [web1]
TASK [rhel-system-roles.selinux : Install SELinux tool semanage on Fedora] *****
ok: [web1]
TASK [rhel-system-roles.selinux : Set permanent SELinux state if enabled] ******
skipping: [web1]
TASK [rhel-system-roles.selinux : Set permanent SELinux state if disabled] *****
skipping: [web1]
TASK [rhel-system-roles.selinux : Set ansible facts if needed] *****************
ok: [web1]
TASK [rhel-system-roles.selinux : Fail if reboot is required] ******************
skipping: [web1]
TASK [rhel-system-roles.selinux : debug] ***************************************
skipping: [web1]
TASK [rhel-system-roles.selinux : Drop all local modifications] ****************
skipping: [web1]
TASK [rhel-system-roles.selinux : Purge all SELinux boolean local modifications] ***
skipping: [web1]
TASK [rhel-system-roles.selinux : Purge all SELinux file context local modifications] ***
skipping: [web1]
TASK [rhel-system-roles.selinux : Purge all SELinux port local modifications] ***
skipping: [web1]
TASK [rhel-system-roles.selinux : Purge all SELinux login local modifications] ***
skipping: [web1]
TASK [rhel-system-roles.selinux : Reload SELinux policy] ***********************
changed: [web1]
TASK [rhel-system-roles.selinux : Set SELinux booleans] ************************
TASK [rhel-system-roles.selinux : Set SELinux file contexts] *******************
changed: [web1] => (item={'target': '/opt/www(/.*)?', 'setype': 'httpd_sys_content_t', 'state': 'present'})
TASK [rhel-system-roles.selinux : Restore SELinux labels on filesystem tree] ***
changed: [web1] => (item=/opt/www)
TASK [rhel-system-roles.selinux : Restore SELinux labels on filesystem tree in check mode] ***
skipping: [web1] => (item=/opt/www)
TASK [rhel-system-roles.selinux : Set an SELinux label on a port] **************
TASK [rhel-system-roles.selinux : Set linux user to SELinux user mapping] ******
PLAY RECAP *********************************************************************
web1 : ok=8 changed=3 unreachable=0 failed=0 skipped=14 rescued=0 ignored=0
受控机查看www,abc都被设安全上下文
[root@localhost ~]# ls -Z /opt/
unconfined_u:object_r:usr_t:s0 hosts
unconfined_u:object_r:httpd_sys_content_t:s0 www
[root@localhost ~]# ls -Z /opt/www
unconfined_u:object_r:httpd_sys_content_t:s0 abc
- 例三: 添加SELinux类型的端口
受控机查看端口号,没有82,这里我想添加82端口
[root@localhost ~]# semanage port -l|grep http
http_port_t tcp 80, 81, 443, 488, 8008, 8009, 8443, 9000
[root@localhost test]# vim myplay.yml
---
- hosts: all
vars:
selinux_ports:
- setype: http_port_t
ports: 82 添加82端口
state: present
proto: tcp
roles:
- role: rhel-system-roles.selinux
[root@localhost test]# ansible-playbook myplay.yml
PLAY [all] *********************************************************************
TASK [Gathering Facts] *********************************************************
ok: [web1]
TASK [rhel-system-roles.selinux : Install SELinux python2 tools] ***************
skipping: [web1]
TASK [rhel-system-roles.selinux : Install SELinux python3 tools] ***************
ok: [web1]
TASK [rhel-system-roles.selinux : refresh facts] *******************************
ok: [web1]
TASK [rhel-system-roles.selinux : Install SELinux tool semanage on Fedora] *****
ok: [web1]
TASK [rhel-system-roles.selinux : Set permanent SELinux state if enabled] ******
skipping: [web1]
TASK [rhel-system-roles.selinux : Set permanent SELinux state if disabled] *****
skipping: [web1]
TASK [rhel-system-roles.selinux : Set ansible facts if needed] *****************
ok: [web1]
TASK [rhel-system-roles.selinux : Fail if reboot is required] ******************
skipping: [web1]
TASK [rhel-system-roles.selinux : debug] ***************************************
skipping: [web1]
TASK [rhel-system-roles.selinux : Drop all local modifications] ****************
skipping: [web1]
TASK [rhel-system-roles.selinux : Purge all SELinux boolean local modifications] ***
skipping: [web1]
TASK [rhel-system-roles.selinux : Purge all SELinux file context local modifications] ***
skipping: [web1]
TASK [rhel-system-roles.selinux : Purge all SELinux port local modifications] ***
skipping: [web1]
TASK [rhel-system-roles.selinux : Purge all SELinux login local modifications] ***
skipping: [web1]
TASK [rhel-system-roles.selinux : Reload SELinux policy] ***********************
changed: [web1]
TASK [rhel-system-roles.selinux : Set SELinux booleans] ************************
TASK [rhel-system-roles.selinux : Set SELinux file contexts] *******************
TASK [rhel-system-roles.selinux : Restore SELinux labels on filesystem tree] ***
TASK [rhel-system-roles.selinux : Restore SELinux labels on filesystem tree in check mode] ***
TASK [rhel-system-roles.selinux : Set an SELinux label on a port] **************
changed: [web1] => (item={'setype': 'http_port_t', 'ports': 82, 'state': 'present', 'proto': 'tcp'})
TASK [rhel-system-roles.selinux : Set linux user to SELinux user mapping] ******
PLAY RECAP *********************************************************************
web1 : ok=7 changed=2 unreachable=0 failed=0 skipped=15 rescued=0 ignored=0
受控机查看已有82端口
[root@localhost ~]# semanage port -l|grep http
http_port_t tcp 82, 80, 81, 443, 488, 8008, 8009, 8443, 9000
手动添加端口方式(添加82端口)
[root@localhost ~]# semanage port -a -t http_port_t -p tcp 82
3.创建角色
- 创建和使用角色包含三个步骤:
- 创建角色目录结构
- 定义角色内容
- 在playbook中使用角色
3.1 创建角色目录结构
- 查找角色
[root@localhost ~]# vim /etc/ansible/ansible.cfg
......
#roles_path = /etc/ansible/roles
......
- 每个角色具有自己的目录,采用标准化的目录结构
[root@localhost ~]# tree roles/
roles/
└── motd
├── defaults
│ └── main.yml
├── files files子目录包含固定内容的文件
├── handlers
├── meta
│ └── main.yml 该文件指定有关模块的作者、许可证、兼容性和依赖项的信息
├── tasks
│ └── main.yml
└── templates templates子目录则包含使用时可由角色部署的模板
└── motd.j2
其他子目录中可以包含main.yml文件,它们定义默认的变量值、处理程序、任务、角色元数据或变量,具体取决于所处的子目录
3.2 创建角色框架
[root@localhost /]# ls
bin etc lib64 opt root srv usr
boot home media proc run sys var
dev lib mnt project sbin tmp
[root@localhost /]# cd project/
[root@localhost project]# touch playbook.yml
[root@localhost project]# ls
playbook.yml
[root@localhost project]# mkdir roles
[root@localhost project]# ls
playbook.yml roles
[root@localhost project]# cd roles/
[root@localhost roles]# ansible-galaxy init httpd init后面跟创建角色名
- Role httpd was created successfully
[root@localhost roles]# ls
httpd
[root@localhost roles]# tree httpd
httpd
├── defaults
│ └── main.yml
├── files
├── handlers
│ └── main.yml
├── meta
│ └── main.yml
├── README.md
├── tasks
│ └── main.yml
├── templates
├── tests
│ ├── inventory
│ └── test.yml
└── vars
└── main.yml
8 directories, 8 files
3.3 定义角色内容
[root@localhost roles]# ls
httpd
[root@localhost roles]# cd httpd/
[root@localhost httpd]# ls
defaults handlers README.md templates vars
files meta tasks tests
写任务
[root@localhost httpd]# cd tasks/
[root@localhost tasks]# ls
main.yml
[root@localhost tasks]# vim main.yml
---
# tasks file for httpd
- name: install httpd
yum:
name: httpd
state: present
- name: config httpd
template:
src: ../templates/httpd.conf.j2
dest: /etc/httpd/conf/httpd.conf
notify:
- restart httpd
- name: service httpd
service:
name: httpd
state: started
在受控机上把文件传到主控机的文件里
[root@localhost conf]# scp httpd.conf 192.168.50.135:/project/roles/httpd/templates/httpd.conf.j2
root@192.168.50.135's password:
httpd.conf 100% 12KB 13.6MB/s 00:00
主控机上修改配置文件
[root@localhost templates]# vim httpd.conf.j2
......
ServerName {{ domain }}:{{ port }} 写域名,端口改成变量
......
Listen {{ port }} 同时也要监听端口号
......
定义变量
[root@localhost templates]# cd ..
[root@localhost httpd]# ls
defaults handlers README.md templates vars
files meta tasks tests
[root@localhost httpd]# cd defaults/
[root@localhost defaults]# ls
main.yml
[root@localhost defaults]# vim main.yml
---
# defaults file for httpd
domain: www.example.com 定义默认变量
port: 80
写启动服务
[root@localhost defaults]# cd ../handlers/
[root@localhost handlers]# ls
main.yml
[root@localhost handlers]# vim main.yml
---
# handlers file for httpd
- name: restart httpd
service:
name: httpd
state: restarted
测试
[root@localhost httpd]# cd tests/
[root@localhost tests]# ls
inventory test.yml
[root@localhost tests]# cat inventory
localhost
[root@localhost tests]# cat test.yml
---
- hosts: localhost
remote_user: root
roles:
- httpd
写playbook
[root@localhost project]# vim playbook.yml
---
- hosts: all
vars:
port: 8080
roles:
role: roles/httpd
运行playbook
[root@localhost project]# ansible-playbook playbook.yml
[WARNING]: Found variable using reserved name: port
PLAY [all] *********************************************************************
TASK [Gathering Facts] *********************************************************
ok: [web1]
TASK [roles/httpd : install httpd] *********************************************
ok: [web1]
TASK [roles/httpd : config httpd] **********************************************
ok: [web1]
TASK [roles/httpd : service httpd] *********************************************
changed: [web1]
PLAY RECAP *********************************************************************
web1 : ok=4 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
受控机上查看8080端口
[root@localhost ~]# 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 *:81 *:*
LISTEN 0 128 [::]:22 [::]:*
[root@localhost ~]# rpm -qa|grep httpd
centos-logos-httpd-80.5-2.el8.noarch
httpd-tools-2.4.37-21.module_el8.2.0+494+1df74eae.x86_64
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
3.4 角色内容开发的推荐做法
- 在角色自己的版本控制存储库中维护每个角色。Ansible很适合使用基于git的存储库。
- 角色存储库中不应存储敏感信息,如密码或SSH密钥。敏感值应以变量的形式进行参数化,其默认值应不敏感。使用角色的playbook负责通过Ansible Vault变量文件、环境变量或其他ansible-playbook选项定义敏感变量。
- 使用ansible-galaxy init启动角色,然后删除不需要的任何目录和文件。
- 创建并维护README.md和meta/main.yml文件,以记录用户的角色的用途、作者和用法。
- 让角色侧重于特定的用途或功能。可以编写多个角色,而不是让一个角色承担许多任务。
- 经常重用和重构角色。避免为边缘配置创建新的角色。如果现有角色能够完成大部分的所需配置,请重构现有角色以集成新的配置方案。使用集成和回归测试技术来确保角色提供所需的新功能,并且不对现有的playbook造成问题。
3.5 在playbook中使用角色
查看受控机端口号为8080
[root@localhost ~]# 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 *:81 *:*
LISTEN 0 128 [::]:22 [::]:
主控机上编写
[root@localhost project]# vim playbook.yml
---
- hosts: all
roles:
- roles/httpd 这里直接写角色名字
[root@localhost project]# ansible-playbook playbook.yml
[WARNING]: Found variable using reserved name: port
PLAY [all] *********************************************************************
TASK [Gathering Facts] *********************************************************
ok: [web1]
TASK [roles/httpd : install httpd] *********************************************
ok: [web1]
TASK [roles/httpd : config httpd] **********************************************
changed: [web1]
TASK [roles/httpd : service httpd] *********************************************
ok: [web1]
RUNNING HANDLER [roles/httpd : restart httpd] **********************************
changed: [web1]
PLAY RECAP *********************************************************************
web1 : ok=5 changed=2 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
查看受控机端口号变成80
[root@localhost ~]# 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 *:81 *:*
LISTEN 0 128 [::]:22 [::]:*
3.6 通过变量更改角色的行为
如果通过以下方式定义了相同的变量,则角色的defaults目录中定义的变量的值将被覆盖:
- 在清单文件中定义,作为主机变量或组变量
- 在playbook项目的group_vars或host_vars目录下的YAML文件中定义
先在创建一个与playbook.yml平级的目录,在该目录里创建一个all并写入定义变量的端口号8080
[root@localhost project]# mkdir group_vars/all
[root@localhost project]# vim group_vars/all/main.yml
port: 8080
[root@localhost project]# ls
group_vars playbook.yml roles
[root@localhost project]# ansible-playbook playbook.yml
[WARNING]: Found variable using reserved name: port
PLAY [all] *********************************************************************
TASK [Gathering Facts] *********************************************************
ok: [web1]
TASK [roles/httpd : install httpd] *********************************************
ok: [web1]
TASK [roles/httpd : config httpd] **********************************************
changed: [web1]
TASK [roles/httpd : service httpd] *********************************************
ok: [web1]
RUNNING HANDLER [roles/httpd : restart httpd] **********************************
changed: [web1]
PLAY RECAP *********************************************************************
web1 : ok=5 changed=2 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
受控机上查看端口号为8080
[root@localhost ~]# 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 *:81 *:*
LISTEN 0 128 [::]:22 [::]:*
- 作为变量嵌套在play的vars关键字中定义
- 在play的roles关键字中包含该角色时作为变量定义
当在角色里面的vars里写入变量时,defaults里的变量会被覆盖,playbook里面的变量不会覆盖vars里的变量(vars里的变量采用优先级最高)
查看主控机defaults里的默认变量端口为80,vars里的变量为8090,最终会采用vars的变量
[root@localhost httpd]# cat defaults/main.yml
---
# defaults file for httpd
domain: www.example.com
port: 80
[root@localhost vars]# cat main.yml
---
# vars file for httpd
port: 8090
[root@localhost project]# vim playbook.yml
---
- hosts: all
roles:
- role: httpd
[root@localhost project]# ansible-playbook playbook.yml
[WARNING]: Found variable using reserved name: port
PLAY [all] *********************************************************************
TASK [Gathering Facts] *********************************************************
ok: [web1]
TASK [install httpd] ***********************************************************
ok: [web1]
TASK [config httpd] ************************************************************
ok: [web1]
TASK [service httpd] ***********************************************************
changed: [web1]
PLAY RECAP *********************************************************************
web1 : ok=4 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
查看受控机端口为8090
[root@localhost ~]# 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 *:81 *:*
LISTEN 0 128 [::]:22 [::]:*
LISTEN 0 128 *:8090 *:*
当在playbook中写入变量时,该变量并不能替换vars中的变量
[root@localhost project]# vim playbook.yml
---
- hosts: all
vars:
port: 8080
roles:
- role: httpd
[root@localhost project]# ansible-playbook playbook.yml
[WARNING]: Found variable using reserved name: port
PLAY [all] *********************************************************************
TASK [Gathering Facts] *********************************************************
ok: [web1]
TASK [install httpd] ***********************************************************
ok: [web1]
TASK [config httpd] ************************************************************
ok: [web1]
TASK [service httpd] ***********************************************************
ok: [web1]
PLAY RECAP *********************************************************************
web1 : ok=4 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
查看受控机端口依然是8090
[root@localhost ~]# 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 *:81 *:*
LISTEN 0 128 [::]:22 [::]:*
LISTEN 0 128 *:8090 *:*
4 使用ansible galaxy部署角色
4.1 用命令搜索角色
搜索geerlingguy提交的所有角色
[root@localhost ~]# ansible-galaxy search --author geerlingguy
Found 99 roles matching your search:
Name Description
---- -----------
geerlingguy.adminer Installs Adminer f>
geerlingguy.ansible Ansible for RedHat>
geerlingguy.apache Apache 2.x for Lin>
geerlingguy.apache-php-fpm Apache 2.4+ PHP-FP>
......
用角色名字来搜索
[root@localhost ~]# ansible-galaxy search 'redis' --platforms EL 搜索EL平台上的redis角色
Found 221 roles matching your search:
Name Desc>
---- ---->
0x0i.consul Cons>
0x0i.grafana Graf>
0x5a17ed.ansible_role_netbox Inst>
1it.sudo Ansi>
adfinis-sygroup.redis Ansi>
AerisCloud.librato Inst>
AerisCloud.redis
......
显示角色信息
[root@localhost ~]# ansible-galaxy info geerlingguy.redis
Role: geerlingguy.redis
description: Redis for Linux
active: True
commit: 4f6fbdff6b566a596b2eaac168f88be820d4b>
commit_message: Ignore the tyranny of ansible>
commit_url: https://api.github.com/repos/geer>
company: Midwestern Mac, LLC
created: 2014-03-06T16:48:12.451903
......
从Ansible Galaxy安装角色, -p 可以指定安装到哪儿去
[root@localhost ~]# ansible-galaxy install geerlingguy.redis
- downloading role 'redis', owned by geerlingguy
- downloading role from https://github.com/geerlingguy/ansible-role-redis/archive/1.6.0.tar.gz
- extracting geerlingguy.redis to /root/.ansible/roles/geerlingguy.redis
- geerlingguy.redis (1.6.0) was installed successfully
4.2 使用要求文件安装角色
用ansible-galaxy,根据某一文本文件中的定义来安装一个角色列表
[root@localhost roles]# vim requirements.yml 在roles下面写一个文件,里面写入要装的角色
- src: geerlingguy.redis
[root@localhost project]# ansible-galaxy install -r roles/requirements.yml -p roles -r指定角色在哪个位置,-p指定要装到哪去
- downloading role 'redis', owned by geerlingguy
- downloading role from https://github.com/geerlingguy/ansible-role-redis/archive/1.6.0.tar.gz
- extracting geerlingguy.redis to /project/roles/geerlingguy.redis
- geerlingguy.redis (1.6.0) was installed successfully
[root@localhost project]# cd roles/
[root@localhost roles]# ls roles下面就有一个geerlingguy的角色
geerlingguy.redis httpd requirements.yml
4.3 管理下载的角色
- 查看当前系统有哪些角色
[root@localhost project]# ansible-galaxy list
# /root/.ansible/roles
- geerlingguy.redis, 1.6.0
# /usr/share/ansible/roles
- linux-system-roles.kdump, (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)
- rhel-system-roles.kdump, (unknown version)
- rhel-system-roles.network, (unknown version)
- rhel-system-roles.postfix, (unknown version)
- rhel-system-roles.selinux, (unknown version)
- rhel-system-roles.storage, (unknown version)
- rhel-system-roles.timesync, (unknown version)
# /etc/ansible/roles
- geerlingguy.redis, 1.6.0
- httpd, (unknown version)
- 移除角色
[root@localhost project]# ansible-galaxy list
# /root/.ansible/roles
- geerlingguy.redis, 1.6.0
# /usr/share/ansible/roles
[root@localhost project]# ansible-galaxy remove geerlingguy.redis
- successfully removed geerlingguy.redis
[root@localhost project]# ansible-galaxy list
# /root/.ansible/roles
# /usr/share/ansible/roles