利用角色简化playbook

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.创建角色

  • 创建和使用角色包含三个步骤:
  1. 创建角色目录结构
  2. 定义角色内容
  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部署角色

Ansible内容公共资源库

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 管理下载的角色

  1. 查看当前系统有哪些角色
[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)
  1. 移除角色
[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
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

百慕卿君

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值