ansible- role-07

1. roles角色

  • Ansible roles让用户更加轻松地重复利用Ansible代码。在标准化目录结构中我们可以打包所有任务、变量、文件、模板,以及调配基础架构或部署应用所需的其他资源,然后只需通过复制相关的目录,将roles从一个项目复制到另一个项目。然后,在play中调用roles就能执行它。
  • 除了自行编写、使用、重用和共享roles外,还可以从其他来源获取角色。红帽系系统中rhel-system-roles软件包便提供了部分角色,此外,用户也可以从Ansible Galaxy网站获取由社区提供支持的许多角色。

1.2 roles目录结构

  • 以下是红帽系统的一个timesync角色的简化目录结构,其子目录各文件按照角色用途来命名。
  • defaults目录包含角色变量的默认值,其优先级最低,可在play中更改并覆盖。
  • files目录包含由角色任务引用的静态文件
  • handles目录包含角色定义的处理程序
  • meta目录包含与角色相关的信息,如作者、许可证、平台和可选的角色依赖项
  • tasks目录包含角色定义的任务
  • templates目录包含由角色任务引用的Jinja2模板文件
  • tests目录包含用于测试角色的清单、playbook
  • vars目录包含角色的变量值,这些变量通常用于角色内部用途这些变量的优先级较高,在playbook中使用时不应更改。
  • README.md文件一般都会介绍该角色的应用方法同时会列举一些参例子
roles 
├──timesync
    ├── COPYING
    ├── defaults
    │   └── main.yml
    ├── examples
    ├── handlers
    │   └── main.yml
    ├── library
    │   └── timesync_provider.sh
    ├── meta
    │   └── main.yml
    ├── README.html
    ├── README.md
    ├── tasks
    │   └── main.yml
    ├── templates
    │   ├── chrony.conf.j2
    │   ├── chronyd.sysconfig.j2
    ├── tests
    │   ├── tests_ntp_provider1.yml
    └── vars
        └── main.yml

1.3 定义变量和默认值

  • 角色变量通过在角色目录层次结构中创建含有键值对的vars/main.yml文件来定义。且不会被清单变量和playbook中定义的变量覆盖。
  • 变量值的引用:{{VAR_NAME}}
  • 默认变量具有最低的优先级。它们很容易被包括清单变量在内的任何其他变量覆盖。
  • 默认变量旨在让用户在编写使用该角色的play时可以准确地自定义或控制它将要执行的操作。它们可用于向角色提供所需的信息,以正确地配置或部署某些对象。
  • 在vars/main.yml或defaults/main.yml中定义具体的变量,但不要在两者中都定义。有意要覆盖变量的值时,应使用默认变量。

1.4 roles的应用

  • 红帽系Linux中,默认roles_path在/usr/share/ansible/roles,因此在playbook引用这些角色时Ansible可以很轻松的找到它们。
  • 如果在当前Ansible配置文件(ansible.cfg)中覆盖了roles_path,设置了环境变量ANSIBLE_ROLES_PATH,或者roles_path中更早列出的目录下存在另一个同名的角色,则Ansible可能无法找到系统角色
---
- hosts: remote.example.com
  roles:
    - role: role_path
      var1: vaule
    - role: role_path
      var1: vaule
    - { role: role_name, var1: vaule, var2: vaule }
  • 导入角色
- name: XXXXX
  include_role: 
    name: role_path
- name: XXXXXXX 
  import_role:
    name: role_path

1.5 控制执行顺序

  • 关键字pre_tasks,tasks,post_tasks,执行完pre_tasks任务后,才能执行tasks,最后执行post__tasks
  • pre_tasks,tasks,post_tasks中使用同名的notify,三个都会执行handles

2. RHEL系统角色

2.1 下载安装RHEL系统角色

  • 下载命令
[root@vm1 ~]# yum -y install rhel-system-roles

  • 角色默认安装路径
[root@vm1 ~]# ls /usr/share/ansible/roles/
linux-system-roles.kdump     rhel-system-roles.kdump
linux-system-roles.network   rhel-system-roles.network
linux-system-roles.postfix   rhel-system-roles.postfix
linux-system-roles.selinux   rhel-system-roles.selinux
linux-system-roles.storage   rhel-system-roles.storage
linux-system-roles.timesync  rhel-system-roles.timesync

2.2 timesync角色使用

  • 角色用途:在服务器上配置NTP时间同步
  • ntp_server的部分变量含义
# List of NTP servers
timesync_ntp_servers:
 - hostname: foo.example.com   # Hostname or address of the server
   minpoll: 4                  # Minimum polling interval (default 6)
   maxpoll: 8                  # Maximum polling interval (default 10)
   iburst: yes                 # Flag enabling fast initial synchronization
                               # (default no)
   pool: no                    # Flag indicating that each resolved address
                               # of the hostname is a separate NTP server
                               # (default no)
  • 关闭受管主机时间同步功能,查看当前时间信息
#设置主机的时区
[root@vm3 ~]# timedatectl set-timezone America/Los_Angeles
[root@vm3 ~]# date 
Wed Sep 16 07:42:03 PDT 2020
  • playbook中应用角色
[root@vm1 timesync]# vim timesync_ntp.yml 
---
---
- name: use ntp to synchronize the system clock
  hosts: vm3
  vars:
    timesync_ntp_servers:
      - hostname: ntp1.aliyun.com
        iburst: yes
      - hostname: ntp2.aliyun.com
        iburst: yes
      - hostname: ntp3.aliyun.com
        iburst: yes

  tasks:
    - include_role:
        name: ../roles/timesync
    - name: set timezone
      command: timedatectl set-timezone Asia/shanghai

  • 执行playbook
[root@vm1 timesync]# ansible-playbook timesync_ntp.yml -i ../inventory 

PLAY [use ntp to synchronize the system clock] *********************************

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

TASK [../roles/timesync : Check if only NTP is needed] *************************
ok: [vm3]

TASK [../roles/timesync : Check if single PTP is needed] ***********************
skipping: [vm3]
.....................................
TASK [../roles/timesync : Enable timemaster] ***********************************
skipping: [vm3]

TASK [set timezone] ************************************************************
changed: [vm3]

PLAY RECAP *********************************************************************
vm3                        : ok=17   changed=1    unreachable=0    failed=0    skipped=18   rescued=0    ignored=6 
  • 查看效果
## 同步了PDT时区的时间
[root@vm3 ~]# date
Thu Sep 17 16:32:56 CST 2020

2.3 selinux角色使用

  • 应用selinux角色可以对受管主机配置selinux相关功能

2.3.1 应用selinux角色确保配置生效

  • SELinux角色必须确保重新引导受管主机,以便能够完成并应用其更改。
  • 当selinux的状态配置由disabled to enabled 或者反之,布尔值变量selinux_reboot_required则从false 变为True,则表示需要重新引导;否则,selinux_reboot_required默认为false,不重新引导,但是会修改设置。
  • 其详细代码如下:
[root@vm1 selinux]# vim selinux_apply_role.yml 
- name: apply selinux role
  block:
    - include_role:
        name: ../roles/selinux
  rescue:
    - name: Check for failure and to find other resaons
      fail:
      when: not selinux_reboot_required
    - name: Restart managed host
      reboot:
    - name: Reapply SELinux role to complete changes
      include_role:
        name: ../roles/selinux

[root@vm1 selinux]# vim main.yml 
---
- name: import apply_selinux.yml
  hosts: vm3
  vars:
    selinux_state: enforcing
  tasks:
    - import_tasks: selinux_apply_role.yml
  • 1.查看vm3受管主机selinux状态
[root@vm3 ~]# sestatus 
SELinux status:                 enabled
SELinuxfs mount:                /sys/fs/selinux
SELinux root directory:         /etc/selinux
Loaded policy name:             targeted
Current mode:                   permissive
Mode from config file:          permissive
Policy MLS status:              enabled
Policy deny_unknown status:     allowed
Memory protection checking:     actual (secure)
Max kernel policy version:      31
  • 2.执行playbook
[root@vm1 selinux]# ansible-playbook main.yml -i ../inventory 
...........................
TASK [../roles/selinux : Fail if reboot is required] ***************************
skipping: [vm3]

......................
TASK [../roles/selinux : Reload SELinux policy] ********************************
changed: [vm3]

TASK [../roles/selinux : Set an SELinux label on a port] ***********************

TASK [../roles/selinux : Set linux user to SELinux user mapping] ***************

PLAY RECAP *********************************************************************
vm3                        : ok=7    changed=2    unreachable=0    failed=0    skipped=15   rescued=0    ignored=0   

  • 3.查看vm3 selinux状态
[root@vm3 ~]# sestatus 
SELinux status:                 enabled
SELinuxfs mount:                /sys/fs/selinux
SELinux root directory:         /etc/selinux
Loaded policy name:             targeted
Current mode:                   enforcing
Mode from config file:          enforcing
Policy MLS status:              enabled
Policy deny_unknown status:     allowed
Memory protection checking:     actual (secure)
Max kernel policy version:      31
  • 4.分析执行的过程
##下面代码为selinux角色tasks/main.yml里的一个任务
- name: Fail if reboot is required
  fail:
    msg: "Reboot is required to apply changes. Re-execute the role after boot."
  when: selinux_reboot_required
##根据执行结果,得知selinux_reboot_required值为false,因此这个任务被跳过
## 由于main.yml里设置的selinux_state: enforcing,其状态并没有由关闭到开启,因此selinux_reboot_required值没变还是为false
  • 5.更改selinux配置后
root@vm1 selinux]# vim main.yml 
---
- name: import apply_selinux.yml
  hosts: vm3
  vars:
    selinux_state: disabled
  tasks:
    - import_tasks: selinux_apply_role.yml
  • 6.执行main.yml
[root@vm1 selinux]# ansible-playbook main.yml -i ../inventory 

PLAY [import apply_selinux.yml] ************************************************

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

TASK [include_role : ../roles/selinux] *****************************************
...................................................
TASK [../roles/selinux : Fail if reboot is required] ***************************
fatal: [vm3]: FAILED! => {"changed": false, "msg": "Reboot is required to apply changes. Re-execute the role after boot."}

TASK [Check for failure and to find other resaons] *****************************
skipping: [vm3]

TASK [Restart managed host] ****************************************************
changed: [vm3]
...............................................
PLAY RECAP *********************************************************************
vm3                        : ok=13   changed=2    unreachable=0    failed=0    skipped=18   rescued=1    ignored=0  
##发现vm3执行重启
  • 7.查看执行效国
[root@vm3 ~]# sestatus 
SELinux status:                 disabled

2.3.2 配置boolean类型selinux规则

  • 通过设置selinux_boolean变量 改变mysql_connect_http规则,不允许通过
  • 1.查看vm3的mysql_connect_http规则状态
[root@vm3 ~]# semanage boolean -l | grep mysql
mysql_connect_any              (off  ,  off)  Allow mysql to connect any
mysql_connect_http             (on   ,   on)  Allow mysql to connect http
selinuxuser_mysql_connect_enabled (off  ,  off)  Allow selinuxuser to mysql connect enabled
[root@vm3 ~]# getsebool -a | grep mysql
mysql_connect_any --> off
mysql_connect_http --> on
selinuxuser_mysql_connect_enabled --> off
  • 2.编写playbook,应用selinux角色
[root@vm1 selinux]# vim selinux_bool.yml 
---
- name: set mysql_connect_http on
  hosts: vm3
  vars:
    selinux_booleans:
      - name: 'mysql_connect_http'
        state: 'off'
        persistent: 'yes'   ## 设置为永久生效
  roles:
    - role: ../roles/selinux
  • 3.执行play
[root@vm1 selinux]# ansible-playbook selinux_bool.yml -i ../inventory 

PLAY [set mysql_connect_http on] ***********************************************

TASK [Gathering Facts] *********************************************************
ok: [vm3]
........................................
TASK [../roles/selinux : Reload SELinux policy] ********************************
changed: [vm3]

TASK [../roles/selinux : Set SELinux booleans] *********************************
changed: [vm3] => (item={'name': 'mysql_connect_http', 'state': 'off', 'persistent': 'yes'})
PLAY RECAP *********************************************************************
vm3                        : ok=7    changed=2    unreachable=0    failed=0    skipped=15   rescued=0    ignored=0   
  • 4.验证结果
[root@vm3 ~]# semanage boolean -l | grep mysql
mysql_connect_any              (off  ,  off)  Allow mysql to connect any
mysql_connect_http             (off  ,  off)  Allow mysql to connect http
selinuxuser_mysql_connect_enabled (off  ,  off)  Allow selinuxuser to mysql connect enabled

2.3.3 配置默认selinux上下文

  • 通过应用selinux角色,设置selinux_fcontexts变量可以配置文件或目录的默认安全上下文
  • 1.查看vm3 /root/wisan目录的默认安全上下文
[root@vm3 ~]# semanage fcontext -l | grep /root/wisan
/root/wisan                                        all files          system_u:object_r:admin_home_t:s0 
[root@vm3 ~]# semanage fcontext -l | grep '/root/wisan(/.*)?'
[root@vm3 ~]# 
  • 2.查看当前上文
[root@vm3 ~]# ls -Z 
    system_u:object_r:admin_home_t:s0 anaconda-ks.cfg
unconfined_u:object_r:admin_home_t:s0 wisan
[root@vm3 ~]# cd wisan 
[root@vm3 wisan]# ls -Z
unconfined_u:object_r:admin_home_t:s0 abc
  • 3.编写playbook
[root@vm1 selinux]# vim selinux_fcontext.yml 
---
- name: set selinux file context
  hosts: vm3
  vars:
    selinux_fcontexts:
      - target: '/root/wisan(/.*)?'
        setype: 'httpd_sys_content_t'
        state: 'present'
  roles:
    - role: ../roles/selinux
  • 4.执行
[root@vm1 selinux]# ansible-playbook selinux_fcontext.yml -i ../inventory 
.......................................
TASK [../roles/selinux : Reload SELinux policy] **********************************
changed: [vm3]

TASK [../roles/selinux : Set SELinux booleans] ***********************************

TASK [../roles/selinux : Set SELinux file contexts] ******************************
changed: [vm3] => (item={'target': '/root/wisan(/.*)?', 'setype': 'httpd_sys_content_t', 'state': 'present'})
PLAY RECAP ***********************************************************************
vm3                        : ok=7    changed=2    unreachable=0    failed=0    skipped=15   rescued=0    ignored=0  
  • 5.查看效果
##添加了新的/root/wisan(/.*)?的默认上下文
[root@vm3 wisan]# semanage fcontext -l | grep /root/wisan
/root/wisan                                        all files          system_u:object_r:admin_home_t:s0 
/root/wisan(/.*)?                                  all files          system_u:object_r:httpd_sys_content_t:s0 

##发现当前文件安全上下文没有改变,若要改变请接着往下看
[root@vm3 wisan]# ls -Z
unconfined_u:object_r:admin_home_t:s0 abc
[root@vm3 wisan]# cd ..
[root@vm3 ~]# ls -Z
    system_u:object_r:admin_home_t:s0 anaconda-ks.cfg
unconfined_u:object_r:admin_home_t:s0 wisan

2.3.4 restore恢复安全上下文为默认

  • 恢复selinux_restore_dirs变量指定文件的安全上下
  • 1.playbook
[root@vm1 selinux]# vim selinux_restorecon.yml 
---
- name: restore fcontext
  hosts: vm3
  vars:
    selinux_restore_dirs:
      - /root/wisan         ##包含目录本身及目录内所有文件
  roles:
    - role: ../roles/selinux
  • 2.执行
[root@vm1 selinux]# ansible-playbook selinux_restorecon.yml -i ../inventory 
............................................
TASK [../roles/selinux : Set SELinux file contexts] ******************************

TASK [../roles/selinux : Restore SELinux labels on filesystem tree] **************
changed: [vm3] => (item=/root/wisan)

TASK [../roles/selinux : Restore SELinux labels on filesystem tree in check mode] ***
skipping: [vm3] => (item=/root/wisan) 

TASK [../roles/selinux : Set an SELinux label on a port] *************************

TASK [../roles/selinux : Set linux user to SELinux user mapping] *****************

PLAY RECAP ***********************************************************************
vm3                        : ok=7    changed=2    unreachable=0    failed=0    skipped=15   rescued=0    ignored=0 
  • 3.验证效果
[root@vm3 ~]# ls -Z
    system_u:object_r:admin_home_t:s0 anaconda-ks.cfg
unconfined_u:object_r:admin_home_t:s0 wisan
[root@vm3 ~]# cd wisan
[root@vm3 wisan]# ls -Z
unconfined_u:object_r:httpd_sys_content_t:s0 abc

2.3.5 配置selinux端口

  • 设置selinux_ports变量向selinux http_port_t端口列表,添加一个82端口
  • 1.查看vm3当前http_port_t端口列表
[root@vm3 ~]# semanage port -l | grep http_port_t
http_port_t                    tcp      8080, 80, 81, 443, 488, 8008, 8009, 8443, 9000
pegasus_http_port_t            tcp      5988

  • 2.编写playbook
[root@vm1 selinux]# vim selinux_port.yml 
---
- name: set selinux port
  hosts: vm3
  vars:
    selinux_ports:
      - ports: '82'
        proto: 'tcp'
        setype: 'http_port_t'
        state: 'present'
  roles:
    - role: ../roles/selinux
  • 3.执行
[root@vm1 selinux]# ansible-playbook selinux_port.yml -i ../inventory 
............................................
ASK [../roles/selinux : Reload SELinux policy] **********************************
changed: [vm3]
..................................................................
TASK [../roles/selinux : Restore SELinux labels on filesystem tree in check mode] ***

TASK [../roles/selinux : Set an SELinux label on a port] *************************
changed: [vm3] => (item={'ports': '82', 'proto': 'tcp', 'setype': 'http_port_t', 'state': 'present'})

TASK [../roles/selinux : Set linux user to SELinux user mapping] *****************

PLAY RECAP ***********************************************************************
vm3                        : ok=7    changed=2    unreachable=0    failed=0    skipped=15   rescued=0    ignored=0  
  • 4.验证效果
[root@vm3 ~]# semanage port -l | grep http_port_t
http_port_t                    tcp      82, 8080, 80, 81, 443, 488, 8008, 8009, 8443, 9000
pegasus_http_port_t            tcp      5988

posted @ 2020-09-18 14:17  小芃总  阅读(416)  评论(0)    收藏  举报