Ansible的基本使用


1 介绍Ansible

  Ansible是python开发的、开源的批量自动化运维工具

  官方网站:https://www.ansible.com、https://docs.ansible.com/

1.1 Ansible的概念和架构

  通过inventor定义Managed node,并由SSH与python进行连通:

  1.管理机上管理被管机

  2.inventory(清单)分组被管机

  3.基于SSH、PowerShell进行PUSH ad-hoc或基于YML文件Playbook

  4.Python模块、插件、API

1.2 Absible的优势

  简单明了:Ansible playbook,更好的对任务进行排序编写

  功能强大:3000多个模块,配置管理、工作流自动化、网络自动化

  无需代理:通过SSH管理,而puppet、saltstack需要装客户端

  与其他系统轻松集成,如jenkins

  跨平台支持:win、linux、unix、网络设备,虚拟机、物理机、云主机、容器

1.3 Ansible自动化平台2

  1.Ansible自动化平台2-Ansible Core

   包含多个不同的组件,共同提供了一整套集成的自动化工具和资源

   提供用于运行Ansible Playbook的基本功能

   定义了用于在YAML文本文件中编写Ansible Playbook的自动化语言

   提供了自动化代码所需的关键功能,如循环、条件和其他Ansible命令

   提供了驱动自动化所需的框架和基本命令行工具

   在ansible-core RPM软件包及其ee-minimal-rhel8和ee-supported-rhel8自动化执行环境中提供Ansible Core 2.13

  2.Ansible自动化平台2-Ansible内容集合

   在过去,Ansible提供了大量模块作为核心软件包的一部分;这种方法在Ansible社区中被称为“自带电池”

   Ansible中包含的模块数量呈指数级增长。这导致了支持方面的一些挑战,特别是因为用户有时希望使用比Ansible特定版本中附带模块版本更早或更高的模块

   开发人员决定将大多数模块重新整理为单独的Ansible collection(内容集合),这些资源collection相关的模块角色和插件构成,由同一组开发人员提供支持

   Ansible Core本身仅限于由ansible.builtin、Ansible collection(内容集合)提供的一小组模块,该集合始终是Ansible Core的一部分

   订阅红帽Ansible自动化平台2后,可获得红帽提供的120多个认证内容集合的访问权限,另外还可通过AnsibleGalaxy获得很多受社区支持的集合

  3.Ansible自动化平台2概述-自动化内容导航器

   红帽Ansible自动化平台2还可提供新的顶级工具(自动化内容导航(ansble-navigator))来开发和测试Ansible Playbook。该工具可取代并扩展多个命令行实用程序的功能,包括ansible-playbook、ansible-inventory、ansible-config

   通过在容器中运行playbook,将运行Ansible的控制节点与运行它的自动化执行环境分隔开来。这样一来,可以更轻松地为自动化代码提供完整的工作环境,以部署到生产环境中

  4.Ansible自动化平台2-自动化执行环境

   自动化执行环境是一种容器镜像,包含Ansible Core、Ansible内容集合以及运行playbook所需的任何Python库、可执行文件或其他依赖项

   使用ansible-navigator运行playbook时,可选择用于运行该playbook的自动化执行环境

   当代码运行时,可以向自动化控制器提供playbook和自动化执行环境,并且也知道其具有正确运行playbook所需的一切

  5.Ansible自动化平台2-准备控制节点

   要运行Ansible Playbook,需在控制节点安装自动化内容导航器(ansible-navigator),然后下载执行环境

   由Ansible托管的主机无需安装ansible-navigator,该工具只需安装在运行Ansible Playbook的控制节点

   安装ansible-core软件包前,先要在控制节点上安装Python3.8或更高版本

   需要有效的红帽Ansible自动化平台订阅,才能在控制节点上安装自动化内容导航器

   如果已在红帽客户门户中为您的组织激活了简单内容访问,则无需再将订阅连接到系统

2 部署Ansible

2.1 安装Ansible

2.1.1 安装自动化内容导航器

# 登录workstation后默认为student普通用户,根据实际使用和考试结合建议使用普通用户操作
# 方法1:
[kiosk@foundation0 ~]$ ssh student@workstation

# 方法2:
[kiosk@foundation0 ~]$ ssh root@workstation
[root@workstation ~]$ ssh student@localhost

# 控制节点上安装自动化内容导航器    - workstation
[student@workstation ~]$ sudo dnf search ansible   #搜索ansible关键字的软件包,方便查找ansible的软件

[student@workstation ~]$ sudo dnf -y install ansible-navigator.noarch ansible-core.x86_64

[student@workstation ~]$ rpm -q ansible-navigator
ansible-navigator-2.1.0-1.el9ap.noarch

[student@workstation ~]$ rpm -q ansible-core
ansible-core-2.13.0-2.el9ap.x86_64

[student@workstation ~]$ rpm -qc ansible-core
/etc/ansible/ansible.cfg    # 默认全局配置文件
/etc/ansible/hosts          # 默认全局清单文件

[student@workstation ~]$ rpm -qc ansible-navigator

2.1.2 检查Ansible版本

# 检查ansible的版本
[student@workstation ~]$ ansible --version
ansible [core 2.13.0]
  config file = /etc/ansible/ansible.cfg
...

[student@workstation ~]$ ansible-navigator --version
ansible-navigator 2.1.0

# 安装ansible后会提供导航器配置文件
[student@workstation ~]$ ls -a
.   .ansible               .ansible-navigator.yml  .bash_logout   .bashrc  .config  Documents  .grading  .jupyter  Music  Pictures  .ssh       .venv
..  ansible-navigator.log  .bash_history           .bash_profile  .cache   Desktop  Downloads  .ipython  .local    .npm   Public    Templates  Videos
[student@workstation ~]$ cat .ansible-navigator.yml
---
ansible-navigator:
  execution-environment:
    image: utility.lab.example.com/ee-supported-rhel8:latest
    pull:
      policy: missing

2.1.3 登录镜像仓库

# 配置镜像仓库不进行https验证
[student@workstation ~]$ mkdir ~/.config/containers 

# ~/.config/containers等价于/home/student/.config/containers
[student@workstation ~]$ cp /etc/containers/registries.conf ~/.config/containers
[student@workstation ~]$ vim ~/.config/containers/registries.conf
unqualified-search-registries = ["utility.lab.example.com"]  # 22行
[[registry]]  # 24行
insecure = true  # 37行
blocked = false   # 40行
location = "utility.lab.example.com"  # 56行

# 登录容器镜像服务器,为下载自动化执行环境容器镜像做准备
[student@workstation ~]$ podman --version
podman version 4.0.2

[student@workstation ~]$ podman login -u admin -p redhat utility.lab.example.com
Login Succeeded!

# 下载自动化内容导航器或使用ansible-navigator命令自动下载
[student@workstation ~]$ ansible-navigator collections    

[student@workstation ~]$ ansible-navigator images   # 查看下载的镜像环境

2.2 构建Ansible清单

2.2.1 默认的清单文件

# 清单定义Ansible管理的主机集合。主机可以分配到组中进行集中管理。组可以包含子组,主机也可以是多个组的成员
# 清单还可以设置应用到它所定义的主机和组的变量
# 定义主机清单可采用两种方式:
  1.使用文本文件定义静态主机清单
  2.通过外部信息提供程序,使用Ansible插件按需生成动态主机清单
# 系统默认清单在/etc/ansibile/hosts

# 举例:
# [嵌套组名:children],嵌套组内只能包含组,不包含主机
[test]
servera

[web]
serverb.example.com

[webservers]
web[1:50].example.com   # 表示从web1到web50,共计50台主机

[servers:children]  # 表示servers组是一个超级组,包含test和web两个组(嵌套)
test
web
webservers

# 指定清单范围格式:通配符或正则表达式的方法
[START:END]                  #开始:结束范围
192.168.[0:15].[0:255]       #表示   192.168.0.0-192.168.15.255
server[a:c].example.com      #表示   a-c
server[01:15].example.com    #表示   server01.example.com-server15.example.com
all:                        #表示   所有主机
ungrouped:                   #表示   指定组/未分配组的主机      

2.2.2 自定义清单文件

  1.创建工作目录

# 当使用特权用户管理Ansible时,可以在家目录中为其创建工作目录
# 目录名称可以根据业务自定义名称,后续的所有文件都放到此目录,包括配置文件、清单文件、playbook等
[student@workstation ~]$ mkdir ~/ansible
[student@workstation ~]$ cd ~/ansible/
[student@workstation ansible]$ pwd
/home/student/ansible

# 查看清单实例文件
[student@workstation ansible]$ ansible-doc -t inventory -l
[student@workstation ansible]$ ansible-doc -t inventory ini
[student@workstation ~]$ ansible-navigator doc -t inventory ini

  2.编辑自定义清单文件

[student@workstation ansible]$ vim inventory
servera                    # 未在组内的主机

[web]                      # 主机组,主机组名称需要使用中括号括起来[],web是组名称
server[b:c]                # 主机组成员,web组内的主机 表示两个主机serverb至serverc
172.25.250:[10:15]

[db]
server[d:z].lab.example.com

# 嵌套组名servers是自定义的,:children是固定语法,表示web、db在servers组中,嵌套组成员应为组,不应为主机
[servers:children]  
web
db
# 不要在清单里书写无用的符号,及一些特殊符号。主机名称不要和主机组冲突,组名尽量不要用数字开头

  3.验证清单

# 使用ansible-navigator或ansible-inventory命令验证计算机是否存在于清单中
  1.ansible-navigator inventory以stdout模式运行
  2.第一条传统Ansible的验证方式,第二条使用Ansible自动化平台2的方式
-RHEL8 & 9
-i inventory  # 指定清单文件的位置
--list-hosts  # 列出清单中的主机  
--graph       # 通过ansible-inventory命令列出清单整个pattern

$ ansible all -i inventory --list-hosts
$ ansible-inventory --graph -i inventory  
[student@workstation ansible]$ ansible-inventory --graph -i /home/student/ansible/inventory

-RHEL 9
$ ansible-navigator inventory -i inventory  -m stdout --list
$ ansible-navigator inventory -i inventory  -m stdout --graph
$ ansible-navigator inventory -i inventory  -m stdout --graph webservers

重要:清单中含有名称相同的主机和主机组,ansible命令显示警告并以主机作为其目标,组被忽略

2.2.3 覆盖清单位置

# 安装ansible软件后,在/etc/ansible/hosts位置提供一个默认主机清单,属于全局管理范围
# 特权用户管理时可以为其在工作目录中创建清单,在工作目录中使用ansible时,且优先度最高
/home/student/ansible/inventory   # 用于针对某个用户设置清单
/etc/ansible/hosts                  # 用于全局设置
[student@workstation /]$ ansible-inventory --graph
@all:
  |--@ungrouped:
[student@workstation /]$ pwd
/
[student@workstation ansible]$ ansible-inventory --graph
@all:
  |--@ungrouped:
[student@workstation ansible]$ pwd
/home/student/ansible

2.2.4 多清单

# 一个用户可以有一个或多个清单文件,若同时使用,可将多个清单文件放置在清单目录中,清单目录需自行创建,名称自定义
[student@workstation ansible]$ vim inventory
servera

[web]
serverb
serverc

[db]
serverd

[servers:children]
web
db
[student@workstation ansible]$ ansible-inventory --graph -i inventory

[student@workstation ansible]$ cp inventory inventory2       #额外创建一份清单名为inventory2
# [student@workstation ansible]$ echo servere > inventory2   #inventory2内指定一个主机servere
[student@workstation ansible]$ vim inventory2                
servere

[student@workstation ansible]$ mkdir invdir                   #创建清单存储目录,名称自定义
[student@workstation ansible]$ mv inv* invdir/                #将所有清单移动至清单存储目录
mv: cannot move 'invdir' to a subdirectory of itself, 'invdir/invdir'
[student@workstation ansible]$ ls invdir/
inventory  inventory2

[student@workstation ansible]$ ansible-inventory --graph -i invdir/  #查看主机模式结构

2.3 管理Ansible配置文件

2.3.1 配置Ansible

# 安装Ansible软件后,自动生成配置文件
   /etc/ansible/ansible.cfg  用于配置多个Ansible工具的行为
   ~/.ansible-navigator.yml  用于更改ansible-navigator命令默认选项
[student@workstation ansible]$ rpm -qc ansible-core
/etc/ansible/ansible.cfg
/etc/ansible/hosts
[student@workstation ~]$ ls -a
.         ansible                 .bash_history  .bashrc  Desktop    .grading  .lesshst  .npm      .ssh       Videos
..        ansible-navigator.log   .bash_logout   .cache   Documents  .ipython  .local    Pictures  Templates  .viminfo
.ansible  .ansible-navigator.yml  .bash_profile  .config  Downloads  .jupyter  Music     Public    .venv
[student@workstation ~]$ ls -a ~/.ansible-navigator.yml
/home/student/.ansible-navigator.yml

2.3.2 管理Ansible设置

指令 描述
inventory 指定清单文件的路径。
remote_user 指定Ansible用于连接受管主机的用户名。如果未指定,则使用当前用户的名称。(在由ansible-navigator 运行的基于容器的自动化执行环境中,始终为 root。)
ask_pass 指示是否提示输入SSH 密码。 (可以是 false,如果使用SSH公钥身份验证,则此为默认值。)
become 指定连接后是否在受管主机上自动切换用户(一般切换为root)。这也可以通过play来指定
become_method 指定如何切换用户(通常为 sudo,此为默认值,但也可选择su)
become_user 指定要在受管主机上切换到哪个用户(通常为 root,此为默认值)
become_ask_pass 指示是否提示输入become_method参数密码。默认为false

2.3.3 管理配置文件

  1.自定义配置文件

# 在工作目录中生成ansible的配置文件
[student@workstation ~]$ cat /etc/ansible/ansible.cfg | grep ansible.cfg
#               $ ansible-config init --disabled > ansible.cfg
...

[student@workstation ~]$ ansible-config init --disabled > /home/student/ansible/ansible.cfg

[student@workstation ~]$ cd /home/student/ansible/
[student@workstation ansible]$ ls
ansible.cfg  inventory
 
[student@workstation ansible]$ ansible --version
ansible [core 2.13.0]
  config file = /home/student/ansible/ansible.cfg

# Ansible的配置文件(ansible.cfg)由几部分组成,含有以键值对形式定义的设置、标题以方括号括起
# 对于基本操作,使用以下两部分:
1.[defaults]---用于设置Ansible操作的默认值
2.[privilege_escalation]---用于配置Ansible如何在受管主机上执行特权升级
    
[student@workstation ansible]$ vim ansible.cfg
[defaults]
inventory=/home/student/ansible/inventory    #139行  工作目录清单位置
remote_user=student                             #222行  远程用户可选root或普通用户 
host_key_checking=false                         #318行  不进行公钥记录

[privilege_escalation]                        #搜/become,n向下查找 或 输入:430
become=true                                    #430行  开启特权功能,
#become_ask_pass=False                        #433行  远程免特权密码,需要对端添加sudo免密	
#become_method=sudo                            #442行  远程功能启用sudo
#become_user=root                            #445行  特权用户为root

备注:剪切操作 dd+p
# 验证配置文件是否书写正确
[student@workstation ansible]$ ansible-inventory --graph   # 取消对清单的指定
  
#为servera~d主机设置sudo免密。
[workstation]
[student@workstation ansible]$ for i in {a..d};do ssh root@server$i 'sed -i s/^%wheel.*$/"%wheel  ALL=(ALL) NOPASSWD: ALL"/ /etc/sudoers';done
[student@workstation ansible]$ for i in {a..d};do ssh root@server$i 'grep ^%wheel /etc/sudoers';done

# 测试远程部署
[student@workstation ansible]$ ansible all -m ping
serverd | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python3"
    },
    "changed": false,
    "ping": "pong"
}
...

  2.配置文件的优先级

$ /etc/ansible/ansible.cfg           #默认路径
$ ~/.ansible.cfg                       #家目录
$ ~/ansible/ansible.cfg              #ansible为工作目录(练习和考试时使用)
$ grep  ANSIBLE_CONFIG /etc/profile  #环境变量
export  ANSIBLE_CONFIG=/opt/ansible.cfg   (此时/opt下需要有ansible.cfg配置文件)
source /etc/profile   加载

# 优先级 :变量>当前目录>用户家目录>/etc

  3.指定远程用户

# 其他指定远程用户及密码的方法
# 方法1:
ansible.cfg
remote_user=root
inventory
[all:vars]
ansible_password=redhat

# 方法二:
inventory
[all:vars]
ansible_user=root
ansible_password=redhat

2.3.4 管理自动化内容导航器

  1.创建自动化内容导航器

#可以为ansible-navigator创建配置文件以覆盖其配置设置的默认值,采用JSON(json)或YAML(yml或yam)格式

#自动化内容导航器按以下顺序查找配置文件,并使用它找到的第一个文件:
1.如果设置了ANSIBLE NAVIGATOR_CONFIG环境变量,则使用所指定位置处的配置文件
2.当前Ansible项目目录中的ansible-navigator.yml文件
3.~/.ansible-navigator.yml文件(主目录中)。请注意,其文件名开头有一个“点”

#与Ansible配置文件一样,每个项目都可以有自己的自动化内容导航器设置文件 

#创建导航器配置文件
[student@workstation ~]$ rpm -ql ansible-navigator | grep temp
[student@workstation ~]$ vim /usr/lib/python3.9/site-packages/ansible_navigator/package_data/settings-sample.template.yml

  2.配置自动化内容导航器

[student@workstation ~]$ vim ~/.ansible-navigator.yml
---
ansible-navigator:
  execution-environment:
    image: utility.lab.example.com/ee-supported-rhel8:latest
    pull:
      policy: missing    # 容器镜像下载策略 missing系统里有就不下载,否则下载

$ vim ~/.ansible-navigator.yml 
  ---
ansible-navigator:
  execution-environment:
    image: utility.lab.example.com/ee-supported-rhel8:latest
    pull:
      arguments:
      - "--tls-verify=false"
      policy: missing
  playbook-artifact:
    enable: false   #关闭运行playbook时生成日志 执行剧本所产生的日志,执行一次记录一次

2.3.5 ansible的远程连接

#anisble远程连接时的必要条件
1.配置链接:如何选择远程的用户
2.清单位置:相对路径、绝对路径、多清单等。
3.链接设置: remote_user= ,~/.ansible-navigator.yml中playbook-artifact:
4.ssh免密:  ssh-key-gen,ssh-copy-id
5.升级特权: visudo,/etc/sudoers

3 编写和运行Playbook

  Play是针对清单中选定的主机运行的一组有序任务

  Playbook是一个文本文件,其中包含由一个或多个按特定顺序运行的play组成的列表

  临时命令可以作为一次性命令对一组目标主机运行一项简单的任务

  Playbook可以通过轻松重复的方式对一组目标主机执行多项复杂的任务

3.1 Playbook-yaml语法

  1.playbook是使用YAML语法编写的文本文件,格式为.yml

  2.严格缩进,空格

  3.YAML文件以—开头,…. 结束,可以省略

  4.使用”-“(减号加一个或多个空格)作为列表项

  5.#注释

$ ansible-doc -l | grep yum
$ ansible-doc yum                       #进入之后,搜索/EXAMPLE
$ vim ~/ansible/web.yml
---                                     #yaml语法,---开头
- name: install httpd                   #play任务的描述:描述部分name字段是可选的选项
  hosts: servera                        #主机模式:任务目标主机
  tasks:                                #任务列表:下面通常为任务模块,有两格缩进
  - name: Install Apache                #任务模块:注意和tasks有两格缩进,name是可选字段,模块描述
    ansible.builtin.yum:                #模块名称:
      name: httpd                       #模块选项1
      state: latest                     #模块选项2

3.2 关闭运行playbook时的日志

[student@workstation ansible]$ vim ~/.ansible-navigator.yml
---
ansible-navigator:
  execution-environment:
    image: utility.lab.example.com/ee-supported-rhel8:latest
    pull:
      policy: missing
  playbook-artifact:
    enable: false  #关闭playbook时生成的日志

3.3 调整tab键缩进

整体缩进–方便对齐yaml语法文本缩进

vim ~/.vimrc
set tabstop=2    #将vim的tab键缩进调至两格
set nu             #设置行号
set autoindent   #回车时调整至上一行文本缩进  
set cursorcolumn #设置竖坐标线 简写set cuc
set cursorline   #设置横坐标线 简写set cul

:set all        #末行模式下set all 查看所有环境设置帮助

#整体缩进 视图模式
ctrl+v , jjj(+G) ,I,(空格、空格),esc

#分解:
1.光标放在需要调节的行上
2.按ctrl+v,用方向键或G选定需要调节的列
3.输入I进入插入模式
4.空格空格,调节需要的缩进
5.按esc同步所有列

3.4 查找用于任务的模块

  用Ansible进行部署任务时,可针对管理员任务需求,选择对应功能模块,通过以下方法可以查询模块帮助,以便编写临时命令及playbook

-RHEL<=8
[student@workstation ansible]$ ansible-doc -l
[student@workstation ansible]$ ansible-doc -l | grep yum
yum                                            Manages packages with the `y...
yum_repository                                 Add or remove YUM repositori...

# 查看某个模块的帮助
[student@workstation ansible]$ ansible-doc yum

-RHEL=9
$ ansible-navigator collections
$ ansible-navigator doc ansible.posix.firewalld
$ ansible-navigator doc ansible.posix.firewalld -m stdout

[student@workstation ansible]$ ansible-navigator collections -m stdout | grep firewalld

3.5 运行Playbook

  运行前检查语法错误或执行空运行:

   1.检查语法错误 ansible-navigator run web.yml –syntax-check file.yml

   2.执行空运行 ansible-navigator run web.yml -C

  通常直接运行ansible-navigator run web.yml进入交互模式或添加-m stdout可将任务打印到标准输出

#运行playbook
$ ansible-navigator run web.yml    # 交互式
$ ansible-navigator run web.yml -m stdout  # 非交互式

3.6 实施多个Play

  1.Playbook是一个YAML文件,含有由一个或多个play组成的列表

  2.如果一个playbook中含有多个 play,每个play可以将其任务应用到单独的一组主机

  3.编排涉及对不同主机执行不同任务的复杂部署时会大有帮助

  4.可以这样编写playbook:对一组主机运行一个play,完成后再对另一组主机运行另一个pla

  5.Playbook中的各个play编写为playbook中的顶级列表项

3.6.1 编写多个Play

[student@workstation ansible]$ vim install_yum.yml
---
- name: install yum repo
  hosts: servera,serverb
  - name: AppStream_REPO
    ansible.builtin.yum_repository:
      name: Red Hat Enterprise Linux 9 for x86_64 - AppStream (RPMs)
      description: AppStream
      file: rhel_AppStream
      baseurl: http://content.example.com/rhel9.0/x86_64/dvd/AppStream
      gpgcheck: no

- name: install yum repo
  hosts: serverc
  tasks:
  - name: BaseOS_REPO
    ansible.builtin.yum_repository:
      name: Red Hat Enterprise Linux 9 for x86_64 - BaseOS (RPMs)
      description: BaseOS
      file: rhel_BaseOS
      baseurl: http://content.example.com/rhel9.0/x86_64/dvd/BaseOS
      gpgcheck: no      
      
#ansible-navigator collections,ansible-navigator doc  ansible.posix.firewalld -m stdout
[student@workstation ansible]$ ansible-navigator collections -m stdout | grep firewalld
[student@workstation ansible]$ ansible-navigator doc ansible.posix.firewalld -m stdout

--syntax-check  
[student@workstation ansible]$ ansible-navigator run install_yum.yml -m stdout --syntax-check
playbook: /home/student/ansible/install_yum.yml

-v -vv -vvv
[student@workstation ansible]$ ansible-navigator run install_yum.yml -m stdout --syntax-check -v


[student@workstation ansible]$ ansible-navigator run install_yum.yml -m stdout

# 测试运行剧本后的结果
[student@workstation ansible]$ ansible -m shell all -a 'yun -y install ftp'
[student@workstation ansible]$ ansible all -m shell -a 'rpm -q ftp'

# 用ansible-doc查询所有模块
yum        安装软件
service    管理服务
shell模块  管理防火墙
copy       拷贝,1有拷贝功能,2 可以将一段文本,复制到某个文件中,如文件不存在,则生成文件。
uri        网站连接测试

3.6.2 选择模块

类别 模块
文件 ansible.builtin.copy: 将本地文件复制到受管主机 ansible.builtin.file: 设置文件的权限和其他属性 ansible.builtin.lineinfile: 确保特定行是否在文件中 ansible.posix.synchronize: 使用rsync 同步内容
软件 ansible.builtin.package: 使用操作系统自带的自动检测软件包管理器管理软件包。 ansible.builtin.dnf: 使用DNF软件包管理器管理软件包 ansible.builtin.apt: 使用APT 软件包管理器管理软件包 ansible.builtin.pip: 从PyPI管理Python 软件包。
系统 ansible.posix.firewalld: 使用firewalld 管理任意端口和服务 ansible.builtin.reboot: 重新启动计算机。 ansible.builtin.service: 管理服务 ansible.builtin.user: 添加、删除和管理用户帐户
网络工具 ansible.builtin.get_url: 通过HTTP、HTTPS或FTP 下载文件 ansible.builtin.uri: 与Web 服务交互

4 管理变量

4.1 变量概述

4.1.1 Ansible变量简介

  Ansible支持利用变量来存储值,并在Ansible项目的所有文件中重复使用这些值

  可以简化项目的创建和维护,并减少错误的数量

# key:vaule  
# 变量可以重复的应用到项目中,简化管理,应用对象可以是:
1.要创建的用户
2.要安装的软件包
3.要重新启动的服务
4.要删除的文件
5.互联网的文档等

4.1.2 命名变量

  变量名称必须以字母开头,并且只能含有字母、数字和下划线

无效变量名称 有效变量名称
web server web_server
remote.file remote_file
1st file file_1,file1
remoteserver $1 remote_server_1,remote_server1

4.2 定义变量

  可在Ansible项目中的多个位置定义变量

  如果在两个位置设置了同名变量,并且变量值不同,则通过优先级来决定要使用哪个值

  可以设置会影响一组主机的变量,也可以设置只会影响个别主机的变量

  有些变量是Ansible可以根据系统配置来设置的事实

  有些变量可在playbook中设置,然后影响该playbook中的一个play,或者仅影响该play中的一项任务

  可通过–extra-vars或-e选项并指定变量值

  Ansible的变量可以定义在不同位置,根据需要设定,其中也有优先度

应用场景 描述 优先度
全局范围 命令行执行临时命令时指定的变量 -e key=vaule
play范围 playbook的Play部分或模块内部指定变量信息key: vaule
主机范围 清单中主机或主机组指定变量(主机 优先 主机组)

4.2.1 全局范围-命令行

  清单变量可被playbook中设置的变量覆盖,这两种变量又可通过在命令行中传递参数到ansible-navigatorrun 命令来覆盖

  在命令行上设置的变量称为额外变量

#命令行使用变量优先级最高
[student@workstation ansible]$ ansible servera -m shell -a whoami -e ansible_user=root -e ansible_password=redhat
servera | CHANGED | rc=0 >>
root

#在执行playbook时指定变量
[student@workstation ansible]$ ansible-navigator run install_yum.yml -m stdout -e ansible_user=root -e ansible_password=redhat

4.2.2 PlAY范围-Playbook

  变量在Ansible Playbook中发挥着重要作用,可以简化playbook中变量数据的管理

  编写play时,可以定义自己的变量,然后在任务中调用这些值

  例如,可以使用值httpd来定义名为web_package的变量,任务可以使用ansible.builtin.dnf模块调用该变量来安装httpd软件包

#playbook中可以在play位置使用vars直接定义变量,也可以通过vars_files加载包含变量的文件。
#1.在playbook的play部分使用vars直接定义变量
-vars
[student@workstation ansible]$ vim web.yml
---
- name: PLAY1
  hosts: servera
  vars:               		 #vars关键字就是在playbook中设置自定义变量
  - package: httpd             #key:vaule    键值间:冒号隔开,冒号后有一个空格
  tasks:
  - name: install {{ package }}
    ansible.builtin.yum:
      name: "{{ package }}" #使用变量时,变量两边有空格,并且用双大括号括起来,变量开头要加“”双引号,非变量开头不用加双引号
      state: latest   
      
[student@workstation ansible]$ ansible-navigator run web.yml -m stdout --syntax-check
playbook: /home/student/ansible/web.yml

[student@workstation ansible]$ ansible-navigator run web.yml -m stdout


#2.生成变量文件
-vars_files  
[student@workstation ansible]$ vim /home/student/ansible/var.yml   
---
package: httpd   #定义变量

[student@workstation ansible]$ vim /home/student/ansible/httpd.yml
---
- name: PLAY2
  hosts: serverb
  vars_files:
  - /home/student/ansible/var.yml    #vars_files 加载变量文件到剧本中
  tasks:
  - name: install {{ package }}
    ansible.builtin.yum:
      name: "{{ package }}"
      state: latest
      
[student@workstation ansible]$ ansible-navigator run httpd.yml -m stdout --syntax-check
playbook: /home/student/ansible/httpd.yml

[student@workstation ansible]$ ansible-navigator run httpd.yml -m stdout

4.2.3 主机范围-清单中

  直接应用于主机的清单变量分为两大类:

   1.主机变量:应用于特定主机

   2.组变量:应用于一个主机组或组主机组中的所有主机。

  主机变量优先于组变量,但playbook中定义的变量的优先级比这两者更高

  若要定义主机变量和组变量,一种方法是直接在清单文件中定义

[student@workstation ansible]$ vim /home/student/ansible/inventory
172.25.250.9   ansible_password=redhat     #给主机定义变量

[test]
172.25.250.10 

[test:vars]               #主机组变量中vars是固定语法
ansible_password=redhat   #给主机组定义变量   

[prod]
172.25.250.[11:12]

[balancers]
172.25.250.13

[all:vars]   #给所有主机和主机组组定义变量
ansible_user=root
ansible_password=redhat 

4.2.4 目录填充主机和组变量

  定义主机和主机组变量的首选做法是在清单文件或目录相同的工作目录中创建group_vars和host_vars两个目录,这两个目录分别包含用于定义组变量和主机变量文件

  建议在host_vars和group_vars目录定义清单变量,而不是直接在清单文件中定义它们

4.3 字典形式表示变量

  除了将与同一元素相关的配置数据分配到多个变量外,管理员也可以使用字典

  字典是一个包含键值对的数据结构,其中的值也可以是字典

vim vari.yml
---
users:
  user1:
    A_name: zhang
    B_name: san
    C_name: /home/zhangsan
  user2:
    A_name: li
    B_name: si
    C_name: /home/lisi 

4.4 调用变量

#方法1:
  users.user1.A_name
  users.user2.B_name

#方法2:
  应用方法2:python字典
  users['user1']['A_name']
   
# [student@bastion ansible]$ vim user.yml
---
- name: useradd
  hosts: dev
  vars_files:
  - vari.yml
  tasks:
  - name: Add the user
    ansible.builtin.user:
      name: "{{ users.user1.A_name }}{{ users.user1.B_name }}"
      home: "{{ users['user1']['C_name'] }}"

4.5 已注册变量捕获命令输出

  register用来捕获命令输出或有关模块执行的其他信息,输出会保存至一个变量中

$ vim register.yml
---
- name: install a packages
  hosts: servera
  tasks:
  - name: install the latest version of Apache
    ansible.builtin.yum:
      name: httpd
      state: latest
    register: install_result  #register字段负责收集变量 install_result自定义变量名被收集变量名
  - name:  message
    ansible.builtin.debug:            
      var: install_result     #debug模块var选项打印register获取install_result变量值

#验证
$ ansible-navigator run -m stdout register.yml 

5 管理机密-vault

5.1 介绍Ansible-vault

  Ansible可能需要访问密码或API密钥等敏感数据,以配置受管主机

  通常信息会以纯文本形式存储在清单变量或其他Ansible文件中。但若如此,任何有权访问Ansible文件的用户或存储这些Ansible文件的版本控制系统都能够访问此敏感数据,这显然存在安全风险

  使用Ansible的Ansible Vault可以加密和解密任何由Ansible使用的数据文件

  可通过一个名为ansible-vault的命令行工具创建、编辑、加密、解密和查看文件

  Ansible Vault可以加密任何由Ansible使用的数据文件,这可能包括清单变量、playbook中含有的变量文件、在执行playbook时作为参数传递的变量文件或者Ansible角色中定义的变量

[student@workstation ~]$ ansible-vault --help
usage: ansible-vault [-h] [--version] [-v] {create,decrypt,edit,view,encrypt,encrypt_string,rekey} ...
encryption/decryption utility for Ansible data files
positional arguments:
  {create,decrypt,edit,view,encrypt,encrypt_string,rekey}
    create              Create new vault encrypted file     #创建密码文件
    decrypt             Decrypt vault encrypted file        #解密现有密码文件
    edit                Edit vault encrypted file           #编辑现有密码文件
    view                View vault encrypted file           #查看加密文件
    encrypt             Encrypt YAML file                   #加密现有文件
    encrypt_string      Encrypt a string
    rekey               Re-key a vault encrypted file       #更改加密文件的密码

5.2 创建与查看加密文件

#创建加密文件-create
[student@workstation ansible]$ ansible-vault create sec1.txt   #默认sec1.txt不存在,通过该命令生成
New Vault password: redhat
Confirm New Vault password: redhat

[student@workstation ansible]$ cat sec1.txt

#查看加密文件-view
[student@workstation ansible]$ ansible-vault view sec1.txt
Vault password: redhat
---
This is a encrypted file!

5.3 编辑现有的加密文件

#编辑加密文件-edit
[student@workstation ansible]$ pwd
/home/student/ansible

[student@workstation ansible]$ ansible-vault edit sec1.txt
Vault password:
[student@workstation ansible]$ ansible-vault view sec1.txt
Vault password:
---
This is a encrypted file!
password: redhat321

5.4 加密现有的文件

[student@workstation ansible]$ echo China > sec2.txt   #创建文件
[student@workstation ansible]$ cat sec2.txt       
China

#加密现有文件-encrypt
[student@workstation ansible]$ ansible-vault encrypt sec2.txt   
New Vault password: redhat
Confirm New Vault password: redhat
Encryption successful

[student@workstation ansible]$ cat sec2.txt

[student@workstation ansible]$ ansible-vault view sec2.txt
Vault password:
China

5.5 解密现有的文件

#解密现有的文件-decrypt
[student@workstation ansible]$ pwd
/home/student/ansible
[student@workstation ansible]$ ansible-vault decrypt sec2.txt
Vault password: redhat
Decryption successful
[student@workstation ansible]$ cat sec2.txt
China

5.6 更改加密文件的密码

#更改加密文件的密码-rekey
[student@workstation ansible]$ pwd
/home/student/ansible

[student@workstation ansible]$ ansible-vault rekey sec1.txt
Vault password: redhat                  #旧密码 redhat
New Vault password: redhat321           #新密码 redhat321                   
Confirm New Vault password: redhat321   #重复新密码 redhat321
Rekey successful

[student@workstation ansible]$ ansible-vault view sec1.txt
Vault password: redhat321
---
This is a encrypted file!
password: redhat321

5.7 使用密码文件

#查看帮助
[student@workstation ansible]$ pwd
/home/student/ansible

[student@workstation ansible]$ ansible-vault view sec1.txt --help
---省略---
  --vault-id VAULT_IDS  the vault identity to use
  --ask-vault-password, --ask-vault-pass  ask for vault password
  --vault-password-file VAULT_PASSWORD_FILES, --vault-pass-file VAULT_PASSWORD_FILES
                        vault password file
---省略---

[student@workstation ansible]$ echo redhat321 > secret.txt  #创建密码文件
[student@workstation ansible]$ cat secret.txt
redhat321
[student@workstation ansible]$ ansible-vault view sec1.txt --vault-id=secret.txt   #通过变量文件指定密码
---
This is a encrypted file!
password: redhat321                     

5.8 密码文件记录到ansible.cfg配置文件

  密码文件记录在ansible.cfg配置文件中的好处是,当执行一个使用了加密文件的playbook时,不必手工指定加密文件密码

[student@workstation ansible]$ vim ansible.cfg          #第一次填写vault路径时,搜索`vault`关键字找该选项
vault_password_file=/home/student/ansible/secret.txt    #配置文件中指定密码文件位置
 
[student@workstation ansible]$ ansible-vault view sec1.txt    #自动调用配置文件中密码文件
---
This is a encrypted file!
password: redhat321

#密码文件记录在配置文件中后
1.加密现有文件时会直接引用
[student@workstation ansible]$ ansible-vault encrypt sec2.txt
Encryption successful

2.更改密码时会直接覆盖
[student@workstation ansible]$ ansible-vault rekey sec2.txt
Rekey successful

3.更改密码需使用--ask-vault-password参数指定
[student@workstation ansible]$ ansible-vault rekey sec2.txt --ask-vault-password
Vault password: redhat
New Vault password: redhat
Confirm New Vault password: redhat
Rekey successful

6 管理事实facts

  Ansible事实是Ansible在受管主机上自动检测到的变量

  事实中含有与主机相关的信息,可以像play中的常规变量、条件、循环或依赖于从受管主机收集的值的任何其他语句那样使用

  为受管主机收集的一些事实可能包括:主机名称、内核版本、网络接口名称、网络接口IP地址、操作系统版本、CPU数量提供的或可用的内存、存储设备的大小和可用空间

  借助事实可以方便地检索受管主机的状态,并根据该状态确定要执行的操作。例如:

   1.根据含有受管主机当前内核版本的事实运行条件任务,以此来重新启动服务器

   2.根据通过事实报告的可用内存来定义MySQL配置文件

   3.根据事实的值设置配置文件中使用的IPv4地址

  每个play在执行第一个任务之前会先自动运行setup模块来收集事实,这在Ansible2.3中报告为GatheringFacts任务或者更早版本中报告为setup。默认情况下,无需具有在play中运行setup的任务,通常会自动运行

  查看受管主机收集的事实的方式是:

   1.使用ad-hoc命令运行setup模块

   2.使用playbook运行debug模块并提取变量var: ansible facts

6.1 收集事实

# 收集事实常用两种手段常用是临时命令ad-hoc及Playbook,事实以josn语法格式列出。收集时要找ansible_开头的事实名称
# 如果变量值为散列/字典,则可以用两种语法来检索该值:
ansible_default_ipv4.hostname
ansible_default_ipv4.[ 'hostname' ]

6.1.1 临时命令 ad-hoc

1.使用ad-hoc方式收集事实
[student@workstation ansible]$ ansible -m setup all  #收集清单中所有主机的事实
[student@workstation ansible]$ ansible -m setup servera -a filter=ansible_nodename  #过滤

[student@workstation ansible]$ ansible -m setup serverc -a filter=*ipv4*    #过滤&模糊匹配

[student@workstation ansible]$ ansible -m setup serverc > fact.txt   #将事实记录到fact.txt文件中,方便查找

6.1.2 PLAYBOOK 收集事实

[student@workstation ansible]$ vim debug.yml
---
- name: debug
  hosts: servera
  tasks:
  - ansible.builtin.debug:
  #简化后可将ansible_facts去掉,二级变量开头,要保留ansible_,如:ansible_default_ipv4.address
      msg: servera ip address "{{ ansible_default_ipv4.address }}"    
  - ansible.builtin.debug:
      var: ansible_hostname 
[student@workstation ansible]$ ansible-navigator run debug.yml -m stdout --syntax-check
playbook: /home/student/ansible/debug.yml

[student@workstation ansible]$ ansible-navigator run debug.yml -m stdout

6.1.3 关闭事实

[student@workstation ansible]$ vim debug.yml
---
- name: debug message
  hosts: dev
  gather_facts: on/off  true/false   # 是否关闭事实
  tasks:
  - debug:
      msg: "{{ ansible_facts.default_ipv4.address }}"
      
[greg@bastion ansible]$ ansible-playbook debug.yml

#如果playbook内容和事实收集没有关系,关闭可以大量减少playbook执行时间

6.2 魔法变量

  实时变量通常收集的是受管节点的信息,而魔法变量收集的是本机的变量值

#inventory_hostname  列出组在清单中的主机名
[student@workstation ansible]$ ansible web -m debug -a var=inventory_hostname

#group_names     列出当前主机归属于哪个组
[student@workstation ansible]$ ansible serverd -m debug -a var=group_names

#groups    列出清单中的所有主机名称。以及所在组
[student@workstation ansible]$ ansible all -m debug -a var=groups

#hostvars  列出系统中所有魔法变量及所有事实变量
[student@workstation ansible]$ ansible all -m debug -a var=hostvars

$ https://docs.ansible.com/ansible/latest/reference_appendices/special_variables.html  #官网文档
# dosc.ansible.com中搜索magic或facts

6.2.1 临时命令收集魔法变量值 ad-hoc

ansible  servera -m debug -a var=inventory_hostname
ansible  servera -m debug -a var=groups
ansible  all -m debug -a var=group_names
ansible  all -m debug -a var=hostvars
ansible  servera -m debug -a var=groups.all

6.2.2 PLAYBOOK收集事实+魔法变量

[student@workstation ansible]$ vim hoc_debug.yml
---
- name: debug
  hosts: servera
  gather_facts: on
  tasks:
  - ansible.builtin.debug:
     var: hostvars

[student@workstation ansible]$ ansible-navigator run hoc_debug.yml -m stdout --syntax-check
playbook: /home/student/ansible/hoc_debug.yml

[student@workstation ansible]$ ansible-navigator run hoc_debug.yml -m stdout

#重定向到文件中的意义是方便在hoc_fact.txt文件中搜索需要的值
[student@workstation ansible]$ ansible-navigator run hoc_debug.yml -m stdout > hoc_fact.txt   

6.2.3 魔法变量hostvars

  临时命令与playbook收集hostvars变量值是不同的

  临时命令不会执行setup模块,所以收集不到事实,PLAYBOOK方法则可以收集到事实和魔法变量

[student@workstation ansible]$ ansible all -m setup > all_host.txt

7 实施任务控制

7.1 利用循环迭代任务

  利用循环,管理员无需编写多个使用同一模块的任务

  Ansible支持使用loop关键字对一组项目迭代任务,可以配置循环以利用列表中各个项目、列表中各个文件的内容、生成的数字序列或更为复杂的结构来重复任务

#loop字段通常在同一缩进的模块下面,对该模块生效,通过item来加载loop循环中的值或变量
#帮助:搜索loop可以搜到相应语法
$ https://docs.ansible.com/ansible/latest/user_guide/playbooks_loops.html

7.1.1 简单循环

  简单循环对一组项目迭代任务

  loop 关键字添加到任务中,将应对其迭代任务的项目列表取为值

  循环变量item保存每个迭代过程中使用的值

[student@workstation ansible]$ vim loop.yml
---
- name: service
  hosts: servera
  tasks:
  - name: Start service nfs-server&chronyd
    ansible.builtin.service:
      name: "{{ item }}"
      state: started
    loop:
    - nfs-server
    - chronyd
    
[student@workstation ansible]$ ansible-navigator run loop.yml -m stdout --syntax-check
playbook: /home/student/ansible/loop.yml

[student@workstation ansible]$ ansible-navigator run loop.yml -m stdout

7.1.2 循环使用变量

  在playbook中通过vars或vars files方式加载变量servers中包含循环列表,模块通过loop字段加载servers变量列表中的值

# vars字段
[student@workstation ansible]$ vim loop.yml
---
- name: service loop
  hosts: servera
  vars:
    servers:
    - nfs-server
    - chronyd
  tasks:
  - name: Start service
    ansible.builtin.service:
      name: "{{ item }}"
      state: stopped
    loop: "{{ servers }}"
   
# vars字段也可以替换为vars_files,将变量保存至文件中,加载到Playbook  
[student@workstation ansible]$ mkdir /home/student/ansible/vars/
[student@workstation ansible]$ vim /home/student/ansible/vars/var.yml
servers:
- nfs-server
- chronyd

[student@workstation ansible]$ vim loop.yml
---
- name: service loop
  hosts: servera
  vars_files:
    - /home/student/ansible/vars/var.yml
  tasks:
  - name: Start service
    ansible.builtin.service:
      name: "{{ item }}"
      state: stopped
    loop: "{{ servers }}"
[student@workstation ansible]$ ansible-navigator run loop.yml -m stdout --syntax-check
playbook: /home/student/ansible/loop.yml

[student@workstation ansible]$ ansible-navigator run loop.yml -m stdout

7.1.3 循环字典列表

  1.循环字典列表保存在loop字段中

[student@workstation ansible]$ vim loop.yml
---
- name: service loop
  hosts: servera
  tasks:
  - name: Start service
    ansible.builtin.user:
      name: "{{ item.name }}"
      comment: "{{ item.comment }}"
      state: present
    loop:
      - name: jane
        comment: tom
      - name: joe
        comment: harry
        
[student@workstation ansible]$ ansible-navigator run loop.yml -m stdout --syntax-check
playbook: /home/student/ansible/loop.yml

[student@workstation ansible]$ ansible-navigator run loop.yml -m stdout      

  2.循环字典列表保存在play的vars中

[student@workstation ansible]$ vim loop.yml
---
- name: service loop
  hosts: servera
  vars:
    users:
    - name: jane
      comment: tom
    - name: joe
      comment: harry
  tasks:
  - name: Start service
    ansible.builtin.user:
      name: "{{ item.name }}"
      comment: "{{ item.comment }}"
      state: present
    loop: "{{ users }}"

[student@workstation ansible]$ ansible-navigator run loop.yml -m stdout --syntax-check
playbook: /home/student/ansible/loop.yml

[student@workstation ansible]$ ansible-navigator run loop.yml -m stdout

  3.循环字典列表保存在play的vars_files中

[student@workstation ansible]$ vim /home/student/ansible/vars/var.yml
servers:
users:
- name: jane
  comment: tom
- name: joe
  comment: harry

[student@workstation ansible]$ vim loop.yml
---
- name: service loop
  hosts: servera
  vars_files:
  - /home/student/ansible/vars/var.yml
  tasks:
  - name: Start service
    ansible.builtin.user:
      name: "{{ item.name }}"
      state: present
      comment: "{{ item.comment }}"
    loop: "{{ users }}"

 [student@workstation ansible]$ ansible-navigator run loop.yml -m stdout --syntax-check
playbook: /home/student/ansible/loop.yml

[student@workstation ansible]$ ansible-navigator run loop.yml -m stdout

7.2 有条件地运行任务

使用conditionals在符合特定条件时运行任务或play

  条件句可帮助区分不同的受管主机,并根据所符合的条件来分配功能角色

  Playbook变量、注册的变量和Ansible事实都可通过条件句来进行测试,可以使用比较字符串、数字数据和布尔值的运算符

  1.通常主机模式为多个节点时,可以让符合when条件的主机执行模块任务。符合条件则为真,则执行模块。否则为假,跳过模块任务

   when判断对象是模块,和模块在同一下列层次

   when判断当前模块是否执行,而不是它下面模块是否执行

   When中引用变量、facts,不需加大括号

   用于测试条件中相等的==运算符不可与变量赋值的=运算符混淆

  2.一个when语句可用于评估多个值。 可以使用and和or关键字组合条件,或使用括号分组条件

1.or是或的关系,任意一个条件为真即可
when: ansible_distribution == "RedHat" or ansible_distribution == "Fedora"

2.and是与的关系,多个条件需同时为真
when: ansible_distribution version == "7.5" and ansible_kernel == "3.10.0-327.el7.x86_64"

3. When语句多条件的另外方式:
when:
   -ansible_distribution_version == "7.5"
   -ansible_kernel == "3.10.0-327.el7.x86_64"
4.使用括号分组条件来表达更复杂的条件语句:
when:  >
   ( ansible_distribution == "RedHat" and
     ansible_distribution_major_version == "7")
   or
    ( ansible_distribution == "Fedora" and 
      ansible_distribution_major_version == "28")  

7.2.1 简单的有条件任务

[student@workstation ansible]$ vim when.yml
---
- name: repository
  hosts: all
  tasks:
  - name: install the latest version of Apache
    ansible.builtin.yum:
      name: httpd
      state: latest
    when: ansible_default_ipv4.address == '172.25.250.10'
    
[student@workstation ansible]$ ansible-navigator run when.yml -m stdout --syntax-check
playbook: /home/student/ansible/when.yml

[student@workstation ansible]$ ansible-navigator run when.yml -m stdout

#如果使用inventory_hostname这个魔法变量,要参考清单中的主机名称。node1位置,单双引号都可以识别为字符串

7.2.2 组合循环和有条件任务

[student@workstation ansible]$ vim when_loop.yml
---
- name: 安装软件包
  hosts: all
  tasks:
  - name: install the latest version of Apache
    ansible.builtin.yum:
      name: "{{ item }}"
      state: latest
    loop:
    - php
    - mariadb
    when: ansible_hostname == 'servera' or ansible_hostname == 'serverc'
    
[student@workstation ansible]$ ansible-navigator run when_loop.yml -m stdout --syntax-check
playbook: /home/student/ansible/when_loop.yml
[student@workstation ansible]$ ansible-navigator run when_loop.yml -m stdout

7.2.3 常用when条件语句

[student@workstation ansible]$ ansible all -m debug -a var=groups
[student@workstation ansible]$ ansible all -m debug -a var=group_names
#变量值 == '字符串'
inventory_hostname == 'node1'
inventory_hostname != 'node1'
'"52:54:00:00:fa:0b" in ansible_default_ipv4.macaddress'
ansible_default_ipv4.address == '172.25.250.11'

#变量值存在  in  第二个变量
inventory_hostname in groups.dev    #可以匹配组
'"dev" in group_names'              #可以匹配
[student@workstation ansible]$ vim when_loop3.yml
---
- name: repository
  hosts: all
  tasks:
  - name: install the latest version of Apache
    ansible.builtin.yum:
      name: httpd
      state: latest
    when: '"db" in group_names'
[student@workstation ansible]$ ansible-navigator run when_loop3.yml -m stdout --syntax-check
playbook: /home/student/ansible/when_loop3.yml
[student@workstation ansible]$ ansible-navigator run when_loop3.yml -m stdout

#default变量查询方法
#搜索引擎中搜索:filters --- Using filters to --- 搜索admin---default('admin', true) 

8 实施处理程序

  handlers是处理程序的一种实现,当对一个Playbook模块改动时,通过监控发现改动,并自动执行后续处理动作

  比如一种场景,当修改了服务配置文件时,需要对服务进行重启,可以在配置文件模块位置用notify监视是否修改后,用handlers中的处理程序如:service模块对其重启服务,达到修改文件便自动重启服务的效果

8.1 Ansible处理程序

$ vim handlers.yml
---
- name:
  hosts: servera
  tasks:
  - name: install the latest version of Apache
    ansible.builtin.yum:
      name: httpd
      state: latest
  - name: Copy using inline content
    ansible.builtin.copy:
      content: 'heihei'
      dest: /var/www/html/index.html
    notify: restart            #notify字段冒号后的名称restart,指向handlers中的描述为restart的模块
  - name: Start firewalld
    ansible.builtin.service:
      name: firewalld
      state: started

  handlers:                            #handlers是缩进和tasks对齐
  - name: restart
    ansible.builtin.service:
      name: httpd
      state: restarted

8.2 执行中对错误的处理

  Ansible评估各任务的返回代码,从而确定任务是成功还是失败

  通常而言,当任务失败时,ansible将立即在该主机上终止play的其余部分并且跳过所有后续任务

  有些时候,可能希望即使在任务失败时也继续执行play

8.2.1 ignore_errors

  忽略任务失败 ignore_errors

[student@workstation ansible]$ vim ignore_errors.yml
---
- name: test error
  hosts: servera
  tasks:
  - name:  touch directory
    ansible.builtin.shell: mkdir /a/b
    ignore_errors: yes
  - name: Add the user
    ansible.builtin.user:
      name: johnd
      
[student@workstation ansible]$ ansible-navigator run ignore_errors.yml -m stdout --syntax-check
[student@workstation ansible]$ ansible-navigator run ignore_errors.yml -m stdout

#也可以在任务失败时强制执行处理程序,详见教材
---
- name: test error
  force_handlers: yes
  tasks:
  - xxxx
  
  handlers:
  - name: haha
    ansible.builtin.service:
    xxx
    xxx

8.3 Ansible块和错误的处理

8.3.1 block、rescue、always

  block:定义要运行的主要任务

  rescue:定义要在block子句中定义的任务失败时运行的任务

  always:定义始终都在独立运行的任务

---
- name: block
  hosts: all
  tasks:
  - block:
    - name:
      ansible.builtin.yum:
        name: http
        state: present
    rescue:
    - name:
      ansible.builtin.yum:
        name: httpd
        state: present
    when: inventory_hostname == 'serverb'
    always:
    - name: Start service httpd, if not started
      ansible.builtin.service:
        name: httpd
        state: started
# Ansible官方文档:搜索:rescue https://docs.ansible.com/ansible/latest/user_guide/playbooks_blocks.html        

8.3.2 block的使用

#未使用block时:
---
- name: test error
  hosts: all
  tasks:
  - name:  touch file
    ansible.builtin.shell: mkdir  -p /a/b
    when: inventory_hostname == "servera"

  - name: Add the user
    ansible.builtin.user:
      name: johnd
    when: inventory_hostname == "servera"

#使用block时
---
- name: test error
  hosts: all
  tasks:
  - block:
    - name:  touch file
      ansible.builtin.shell: mkdir  -p /a/b

    - name: Add the user
      ansible.builtin.user:
        name: johnd
    when: inventory_hostname == "servera"

9 文件部署到受管主机

9.1 将文件复制到主机

9.1.1 文件模块

  1.在被管机上创建文件和目录

  2.复制文件(或内容)到被管机 control –> node1

  3.从被管机复制文件到管理机 node1 –> control

  4.修改文件内容

  5.查看文件状态

  6.修改文件属性(所有者、权限、selinux)

  7.文件同步

ansible.builtin-描述文件模块:

模块名 说明
blockinfile 插入、更新 、删除,自定义标记的多行文本块
file 设置权限、所有者、SElinux上下文及常规文件、符号连接、硬链接等
copy 远程copy,类似file,可以设置文件属性、SElinux上下文
fetch 和copy类似,相反工作方式,从远端拷贝到控制节点
lineinfile 改文件某一行时使用
stat 检测文件状态,类似linux中stat命令
synchronize 围绕rsync一个打包程序
#查找模块可使用命令
$ ansible-doc -l | grep file
$ ansible-navigator collections -m stdout | grep file$
$ ansible-doc file
#注意:很多模块已经不在ansible.builtin集合中了,所以需要通过ansible-navigator collections命令搜索。

1.ansible.builtin.file

- name: Change file ownership, group and permissions
  ansible.builtin.file:
    path: /var/www/html/index.html
    owner: apache
    group: apache
    mode: '0644'
    state: touch
    setype: default_t
      
#(Choices: absent, directory, file, hard, link, touch)[Default: file]
#file:修改文件内容,无该文件则不修改
#touch:创建文件
#touch,mkdir,cp,mv,rm,ln,chmod,chown,chcon

2.ansible.builtin.copy

#复制本机文件到受管节点
- name: Copy file with owner and permissions
  ansible.builtin.copy:
    src: /srv/myfiles/foo.conf
    dest: /var/www/html/index.html
    owner: foo
    group: foo
    mode: '0644'
    setype:  httpd_sys_content_t
    
#复制文本内容testweb至目标文件,文件不存在则创建  
- name: Copy using inline content
  ansible.builtin.copy:
    content: "testweb"
    dest: /var/www/html/index.html

3.ansible.builtin.lineinfile

[student@workstation ansible]$ ansible-doc -l | grep line
lineinfile                                     Manage lines in text files
[student@workstation ansible]$ ansible-doc lineinfile
[student@workstation ansible]$ vim lineinfile.yml
---
- name: lineinfile
  hosts: all
  tasks:
  - name: Ensure SELinux is set to enforcing mode
    ansible.builtin.lineinfile:
      path: /etc/selinux/config
      regexp: '^SELINUX='
      line: SELINUX=enforcing

[student@workstation ansible]$ ansible-navigator run lineinfile.yml -m stdout --syntax-check
playbook: /home/student/ansible/lineinfile.yml

[student@workstation ansible]$ ansible-navigator run lineinfile.yml -m stdout

#验证:
[student@workstation ansible]$ ansible servera -m shell -a 'cat /etc/selinux/config'

#docs.ansible.com 搜索引擎中搜索:filters --- Using filters to --- 搜索admin---default('admin', true) 

4.ansible.builtin.blockinfile

- name: Insert/Update HTML surrounded by custom markers after <body> line
  ansible.builtin.blockinfile:
    path: /opt/index.html
    marker: "<!-- {mark} ANSIBLE MANAGED BLOCK -->"
    insertafter: "<body>"
    block: |
      <h1>Welcome to {{ ansible_hostname }}</h1>
      <p>Last updated on {{ ansible_date_time.iso8601 }}</p>

5.ansible.builtin.template

- name: Template a file to /etc/files.conf
  ansible.builtin.template:
    src: /mytemplates/foo.j2
    dest: /etc/file.conf


- name: Download foo.conf
  ansible.builtin.get_url:   #该模块可以将网络上的文件,直接下载至受管节点上。
    url: http://materials/hosts.j2   #源文件
    dest: /opt/host.txt  #目标文件位置

9.2 Jinja2模板部署自定义文件

9.2.1 jinja2简介

  ansible中使用jinja2模板对文件进行部署,再用template模块同步jinja2模板文件至受管节点,该模块和copy模块作用基本一样,都是把某个文件复制到被管主机上,但是区别在于template模块可以获取变量的值和使用循环

   1.管理文件通常会使用一些模块,copy,file,blockinfile,lineinfile

   2.更好的配置文件管理方式是使用jinja2语法制作模板文件来生成最终使用的配置文件

   3.jinja2模板文件内,可以通过多种方式编辑或构成,比如魔法变量、事实变量、普通字符、控制语句语法…

   4.使用jinja2模板的方法是,先构建jinja2模板,再通过template模块将j2模板同步至受管节点

   5.构建模板文件通常名称自定义,以.j2结尾,类似shell脚本的.sh、python脚本的.Py

9.2.2 使用分隔符

1、构建jinja2模板
$ vim jin.j2  #文件名用.j2结尾
127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
::1         localhost localhost.localdomain localhost6 localhost6.localdomain6
{# host file #}    #描述,为管理员做提示作用。用户不可见
haha {{ ansible_hostname }}

2、通过templete模块,同步模板文件至受管主机,同时收集事实变量值,将结果生成至相应文件中。
$ vim temp.yml
---
- name: sync file
  hosts: servera
  tasks:
  - name: Template a file to /etc/files.conf
    ansible.builtin.template:
      src: jin.j2
      dest: /etc/myhosts
$ ansible-navigator run temp.yml -m stdout

3、在受管节点上查看文件结果
$ ansible servera -m shell -a 'cat /etc/myhosts'
servera | CHANGED | rc=0 >>
haha
servera heihei servera.lab.example.com

9.2.3 管理模板文件

1、在配置文件中定义ansible_managed功能,添加描述信息:“Ansible hahaha”
[greg@control ansible]$ vim ansible.cfg
[defaults]
ansible_managed = Ansible hahaha
变量名 =  变量值

2、在jinja2模板中调用该功能
#vim jinja.j2
{# host file #}     #{##}注释客户端生成文件是不显示
{{ ansible_managed }}  #{{}}描述,客户端生成文件时会显示
127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
::1         localhost localhost.localdomain localhost6 localhost6.localdomain6

9.2.4 控制结构-使用循环

-shell
for user in `ls /`;do 
   echo $user
done

-jinja2
{% for user in users %}   #user变量替换为users变量中的所有值,一行一个值。
{{ user }}
{% endfor %}

#示例
$ vim jinja2.j2
{% for host in groups.all %}  #使用for 或if 时控制结构使用{% %}
{{ host }}
{% endfor %}

#查看语法帮助:官网或关键词搜索示例
[student@workstation ansible]$ grep -r '{%' /etc

1.文件的生成方法

$ vim debug.yml
---
- name:
  hosts: all
  tasks:
  - ansible.builtin.debug:
      var: hostvars
$ ansible-navigator run debug.yml  -m stdout > 1.txt

2.生成/etc/hosts

# 方法1:
$ vim /home/student/ansible/temp.yml
127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4
::1 localhost localhost.localdomain localhost6 localhost6.localdomain6

{% for host in groups.all %}
{{ hostvars[host].ansible_default_ipv4.address }} {{ hostvars[host].ansible_nodename }} {{ hostvars[host].ansible_hostname }} 
{% endfor %}

#方法2:
vim /home/student/ansible/temp.yml
---
- name: sync file
  hosts: all     
  tasks:
  - name: Template a file to /etc/files.conf
    ansible.builtin.template:
      src: hosts.j2
      dest: /etc/myhosts
    when: inventory_hostname in groups.dev     #匹配dev组
    
$ ansible-navigator run temp.yml -m stdout
$ ansible  servera -m shell -a 'cat /etc/myhosts'

# 以json格式查看:
{{ hostvars[i]['ansible_facts'] |  to_nice_json }}

10 管理大项目

10.1 引用清单主机

10.1.1 使用主机模式的方式

#使用主机模式的常见方式:

1.[ad-hoc:]
ansible dev -m shell 

2.[playbook:]
- name:
  hosts: dev

10.1.2 通配符匹配多个主机

# 清单里使用通配符匹配多个主机
[START:END]
192.168.[0:15].[0:255] 表示 192.168.0.0-192.168.15.255
server[a:c].example.com  表示   a-c
server[01:15].example.com  表示   server01.example.com-server15
ipv6也可以通过[a:f]这种方式
all: 所有主机
ungrouped : 不属于任何一个组的所有主机

10.1.3 主机模式其他方式

#使用特殊字符时,必须添加单引号,否则不生效
hosts: '*'  和all相同   
hosts:'*.example.com'
hosts:'datacenter*'

#列表形式
hosts:servera,serverb  
hosts:webserver,serverc
hosts:'devops,server*'

#冒号:取代逗号
hosts:lab,&datacenter 匹配lab组同时也属于datacenter组,顺序无所谓&符号时同时也属于的意思
hosts:datacenter,!test2.example.com  表示datacenter组,但不包括test2.。。这个主机
hosts:all,!datacenter1  所有组,但不包含datacenter1组

10.2 包含和导入文件

10.2.1 管理大型Playbook

# 如果playbook很长很复杂,可以拆分成较小的文件便于管理,以模块化管理
# 可以将多个不同功能的play,组合成一个主要的playbook,将文件中的任务列表插入play,这样可将这种模块化的play应用到不同场景
playbook
- httpd
- php
- mysql

10.2.2 导入Playbook

1.将两个playbook加入到主playbook
$ vim one.yml 
---
- name: play1
  hosts: node1
  tasks:
  - name: Install the latest version of Apache
    ansible.builtin.yum:
      name: httpd
      state: latest
      
$ vim two.yml      
---
- name: play2
  hosts: node1
  tasks:
  - name: Make sure a service unit is running
    ansible.builtin.systemd:
      state: started
      name: httpd
      enabled: yes
      

2.在主playbook中和其他play交替使用
$ vim main.yml 
---
- name: four
  hosts: node1
  tasks:
  - ansible.builtin.debug:
      msg: haha
  
- name: one     # 因为加载的是playbook所以需要顶头写无缩进
  import_playbook: one.yml

- name: two
  import_playbook: two.yml

10.2.3 包含与导入

  Ansible可以支持两种方法将文件放入playbook中:
   包含:内容是一个动态操作。在playbook运行期间,Ansible会在内容到达时处理所包含的内容
   导入:内容是一个静态操作。在运行开始之前,Ansible在最初解析playbook时预处理导入的内容

1.包含

1.使用include_tasks功能时,包含时设置的when等条件语句将确定任务是否包含在play中
2.如果运行ansible-playbook --list-tasks以列出playbook中的任务,则不会显示已包含任务文件中的任务。将显示包含任务文件的任   务。相比之下,import_tasks功能不会列出导入任务文件的任务,而列出已导入任务文件中的各个任务
  #([greg@control ansible]$ ansible-playbook playbook.yml --start-at-task webserver)
3.不能使用ansible-playbook --start-at-task从已包含任务文件中的任务开始执行playbook
  #([greg@control ansible]$ ansible-playbook playbook.yml --start-at-task webinstall)
4.不能使用notify语句触发已包含任务文件中的处理程序名称
  可以在包含整个任务文件的主playbook中触发处理程序,在这种情况下,已包含文件中的所有任务都将运行

2.导入

1.使用import_tasks功能时,导入时设置的when等条件语句将应用于导入的每个任务
2.无法将循环用于import_tasks功能
3.如果使用变量来指定要导入的文件的名称,则将无法使用主机或组清单变量

3.使用示例

第一个tasks任务
[greg@bastion ansible]$ mkdir tasks    #tasks目录是自定义的,创建的目的只是方便存储管理tasks任务文件。
[greg@bastion ansible]$ vim tasks/apache.yml  #tasks任务文件,文件中没有主机模式
---
- name:
  ansible.builtin.yum:
    name: httpd
    state: latest
第二个tasks任务
[greg@bastion ansible]$ vim tasks/service.yml 
---
- name:
  ansible.builtin.service:
    name: httpd
    enabled: yes
    state: started
  
包含和导入的方式:
[greg@bastion ansible]$ vim main.yml   #此处main.yml是一个playbook,有主机模式
---
- name:
  hosts: node1
  tasks:
  - include_tasks: tasks/apache.yml  
  - import_tasks: tasks/service.yml

11 角色和collections简化Playbook

11.1 描述角色结构

# Ansible中的角色是结构化的目录组成,可以根据业务需要创建不同的角色,apache的、mysql的等
# 角色的优势是类似将playbook分割成更小的模块,进行模块化管理,简化playbook
# 除了自行编写、使用、重用和共享角色外,也可以从其他来源获取角色以及使用分发包(如Ansible内容集合)查找角色

11.2 创建角色

# 在playbook的项目目录中创建一个角色,并将其作为playbook中某个play的一部分来运行
1.yum install -y httpd            yum模块
2.index.html, fcontext            copy模块
3.httpd service                   service模块
4.firewalld.service               service模块
5.firewalld permit apache         firewalld模块
# 使用web角色一键部署以上服务

  创建和使用角色分四步进行:

   1.创建角色目录存储路径

   2.创建角色

   3.定义角色内容

   4.在playbook中使用角色

11.2.1 角色目录存储路径

# 配置ansible.cfg文件中的roles-path,默认ansible会在roles子目录中查找角色
# 可以将自己的角色安装在~/ansible/roles子目录中
1.默认路径:
[student@workstation ansible]$ ansible-galaxy --help

[student@workstation ansible]$ ansible-galaxy role --help    #查看角色的子命令帮助

[student@workstation ansible]$ ansible-galaxy role list     #新版本查看角色指令
[student@workstation ansible]$ ansible-galaxy list           #旧版本查看角色指令
# /usr/share/ansible/roles   -- 系统角色
# /etc/ansible/roles         -- 全局角色路径
[WARNING]: - the configured path /home/student/.ansible/roles does not exist.  --默认该目录不存在,需要的话可以根据需求创建
`如果ansible无法找到该位置角色,会按照ansible.cfg中roles_path指定的目录中查找`

2.创建角色目录存储路径
  使用自定义工作目录时,创建自定义roles(角色)目录,并使用ansible.cfg中roles_path=字段指定角色路径
[student@workstation ansible]$ pwd        #进入自己的工作目录
/home/student/ansible

[student@control ansible]$ mkdir roles    #创建存放角色的目录

[student@control ansible]$ vim ansible.cfg   
roles_path=/home/student/ansible/roles    #指定角色路径

[student@workstation ansible]$ ansible-galaxy list  #要在工作目录中使用查看命令,调用当前工作目录配置文件中的角色路径
# /home/student/ansible/roles                       #查询结果应和配置文件的roles_path字段一致   

11.2.2 创建角色

[student@workstation ansible]$ ansible-galaxy role init roles/apache    #创建角色
- Role roles/apache was created successfully

[student@workstation ansible]$ ansible-galaxy role list   #列出所有角色
# /home/student/ansible/roles
- apache, (unknown version)

[student@workstation ansible]$ tree roles/apache/
roles/apache
├── defaults                  #角色默认变量
│   └── main.yml
├── files                     #引用的静态文件,可以是一些文件、网页模板等
├── handlers                  #处理程序,通常通过模块完成的
│   └── main.yml
├── meta                      #作者,许可、兼容性
│   └── main.yml
├── README.md
├── tasks                     #任务,任务的组成就是模块应用,也是角色的主要功能
│   └── main.yml
├── templates                 #模板文件,通常使用jinja2模板
├── tests                     #测试
│   ├── inventory
│   └── test.yml
└── vars                      #角色变量
    └── main.yml

8 directories, 8 files
#用不到的目录可以删除,如defaults、vars、tests

11.2.3 定义角色内容

[student@control ansible]$ tree roles/apache (可选,方便查看路径信息)
*[student@control ansible]$ vim roles/apache/tasks/main.yml   #在tasks目录中完善角色内容
---
- name: install apache     #编写角色时,任务中只有模块任务,没有PLAY
  ansible.builtin.yum:
    name: httpd
    state: latest
- name: Start service httpd
  ansible.builtin.service:
    name: httpd
    state: started
    enabled: yes
- name: create web page
  ansible.builtin.template:
    src: jin2.j2    #jin2.j2需要手动创建
    dest: /var/www/html/index.html
  notify:
  - restart   #需要时将调用handlers处理程序,需要手动创建,restart通知中的处理程序名要和handlers/main.yml中处理程序描述一致
- name: Start service firewalld
  ansible.builtin.service:
    name: firewalld
    state: started
    enabled: yes
    
- name: permit apache
  ansible.posix.firewalld:    
    service: http
    permanent: yes
    state: enabled
    immediate: yes
    
#ansible-navigator collections可以查看posix集合 
#ansible-navigator doc ansible.posix.firewalld -m stdout 

#以上25-30行客替换为如下:
- name: permit apache
  ansible.builtin.shell: firewall-cmd --permanent --add-service=http  
- name: permit apache
  ansible.builtin.shell: firewall-cmd --reload
      
[student@control ansible]$ vim roles/apache/templates/jin2.j2  #编写模板文件
ipadd={{ ansible_default_ipv4.address }}  hostname={{ ansible_hostname }}

[student@control ansible]$ vim roles/apache/handlers/main.yml   #编写处理程序
---
- name: restart 
  ansible.builtin.service:
    name: httpd
    state: restarted

11.2.4 playbook中使用角色

[student@bastion ansible]$ vim roles.yml
---
- name:
  hosts: servera
  roles:     #roles字段用来调用角色
  - apache   #被调用角色的名称
  - xxx
[student@bastion ansible]$ ansible-navigator run -m stdout roles.yml  
[student@control ansible]$ curl servera
ipadd=172.25.250.10  hostname=servera

11.3 外部内容源部署角色

  从Git存储库或AnsibleGalaxy等外部资源中选择和检索角色,并在playbook中使用

  https://galaxy.ansible.com

11.3.1 外部内容来源

#角色有多种获取方式:
1.本地tar包安装   2.通过网络地址安装   3.通过文件同时安装网络中多个地址角色

roles/requirements.yml
- src: #角色网址
  varsion:#角色版本
  name:#安装在本地的角色名
- src:
  name:

ansible-galaxy role install -r roles/requirements.yml -p roles
-r 指定文件路径
-p 指定角色安装路径
roles/requirements.yml  角色安装信息,包括地址,角色名称等

11.3.2 角色部署

#示例:
1.将phpinfo.tar,haproxy.tar上传到Linux,kiosk家目录下,用kiosk登录
2.将两个角色包拷贝到foundation0的rhel9.0目录中
$ ssh root@localhost cp /home/kiosk/{phpinfo.tar,haproxy.tar} /content/courses/rh294/rhel9.0/materials
3.打开foundation0的浏览器输入http://172.25.254.254/materials/就可以看到两个软件包

[student@workstation ansible]$ mkdir roles
[student@workstation ansible]$ $ vim ansible.cfg
[defaults]
roles_path=/home/student/ansible/roles
[student@workstation ansible]$ vim roles/requirements.yml
---
- src: http://172.25.254.254/materials/haproxy.tar
  name: balancer
- src: http://172.25.254.254/materials/phpinfo.tar
  name: phpinfo

[student@workstation ansible]$ ansible-galaxy install -r roles/requirements.yml 
[student@workstation ansible]$ ansible-galaxy list
# /home/student/ansible/roles
- apache, (unknown version)
- balancer, (unknown version)
- phpinfo, (unknown version)

11.4 内容集合获取角色和模块

  从Ansible内容集合中获取一组相关角色、补充模块和其他内容,并在playbook中使用

11.4.1 Ansible内容集合

  1.随着模块数量增加,管理困难。模块需要唯一名称,并保持更新

  2.借助Ansible内容集合,Ansible代码可以与模块和插件分开更新

  3.Ansible 内容集合可提供一组在playbook中使用的相关模块、角色和其他插件,便于供应商和开发人员按照自己的节奏维护和分发集合,而不受Ansible版本的影响

11.4.2 Ansible内容集合的命名空间

  1.命名空间是集合名称的第一部分

  2.由Ansible社区维护的所有集合可能会放入community命名空间中名称类似于:

   community.crypto

   community.postgresql

   community.rabbitmq

  3.红帽直接维护和支持的Ansible内容集合可能使用redhat命名空间有:
   redhat.rhv
   redhat.satellite
   redhat.insights等名称

11.4.3 Ansible内容集合的来源

  无论是将ansible-navigator 用于最小自动化执行环境,还是在裸机Ansible Core上使用ansible-playbook,始终至少有一个可用Ansible内容集合:ansible.builtin

  自动化执行环境可能还内置了其他自动化执行环境,例如,红帽Ansible 自动化平台2.2使用的默认执行环境ee-supported-rhel8

  如果需要其他Ansible内容集合,可以将其添加到Ansible项目的collections子目录中,可以从多个来源获取Ansible内容集合:

   1.自动化中心

   2.私有自动化中心

   3.Ansible Galaxy

   4.第三方Git存储库或存档文件

11.4.4 安装Ansible内容集合

#配置文件ansible.cfg中设置了collections_paths选项来指定集合的默认路径:
~/.ansible/collections;/usr/share/ansible/collections 
#如果消除这两个目录的指定,则ansible-navigator无法在这些目录的其版本中找到自动化执行环境内提供的Ansible内容集合
$ ansible-galaxy collection install 集合 -p collections
-p collections 选项会将该集合安装到本地collections子目录中或者不适用-p,而在ansible.cfg文件中collections_paths选项来指定集合的默认路径

#集合的来源可以是:本地、互联网、git仓库

1.使用要求文件安装Ansible内容集合

# 1.将三个集合包上传到Linux,kiosk家目录下,用kiosk登录
# 2.将三个集合包拷贝到foundation0的rhel9.0目录中
  $ ssh root@localhost cp /home/kiosk/{community-general-5.5.0.tar.gz,redhat-insights-1.0.7.tar.gz,redhat-rhel_system_roles-1.19.3.tar.gz} /content/courses/rh294/rhel9.0/materials
# 3.打开foundation0的浏览器输入http://172.25.254.254/materials/就可以看到两个软件包

【workstation】
1.创建存储集合的位置
$ mkdir /home/student/ansible/mycollections  
$ vim ansible.cfg
[defaults]
...  
#集合默认路径不删除,额外添加当前用户工作目录中集合路径
collections_path=/home/student/ansible/mycollection:~/.ansible/collections:/usr/share/ansible/collections 

2.部署requirements.yml文件
$ vim /home/student/ansible/mycollections/requirements.yml
---
collections:
- name: http://172.25.254.254/materials/community-general-5.5.0.tar.gz
- name: http://172.25.254.254/materials/redhat-insights-1.0.7.tar.gz
- name: http://172.25.254.254/materials/redhat-rhel_system_roles-1.19.3.tar.gz

3.安装集合
$ ansible-galaxy collection install -r requirements.yml -p /home/student/ansible/collections/mycollections
$ ansible-galaxy collection list

11.5 利用系统角色重用内容

  编写利用红帽帽企业Linux的系统角色执行标准操作的 playbook

11.5.1 内容集合安装系统角色

#内容集合 redhat.rhel_system_roles

$ mkdir /home/student/ansible/collections
$ vim /home/student/ansible/collections/requirements.yml
---
collections
name: redhat.rhel system roles

$ ansible-galaxy collection install -p collections/ -r home/student/ansible/collections/requirements.yml

$ sudo find ./mycollection/ -name  selinux-playbook.yml #不安装角色包可以使用该条命令搜索
$ find mycollection/ -name '*.yml' | grep selinux
$ cp /usr/share/ansible/collections/ansible_collections/redhat/rhel_system_roles/docs/selinux/selinux-playbook.yml /home/student/ansible/selinux.yml

11.5.2 rpm包安装系统角色

1.系统角色使用流程

1.通过软件安装获得系统角色(rhel-system-roles.noarch)
2.定义系统角色路径(存放角色的位置),并将其记录配置文件
cd /;ansible-galaxy list   , vim ~/ansible/ansible.cfg/;roles_path=xxxx:xxxx
3.使用系统角色,将系统角色添加至playbook,并修改内容
4.应用

2.安装系统角色

1.安装
系统帮助我们定义了一些角色,有不同的功能,需要通过安装软件包。
[greg@control ansible]$ cd /
[greg@control /]$ sudo yum search roles
[greg@control /]$ sudo yum install -y rhel-system-roles.noarch     
[greg@control /]$ ansible-galaxy list    #在根目录下查看角色路径,该路径为默认系统角色路径
# /usr/share/ansible/roles     #系统角色路径
- linux-system-roles.kdump, (unknown version)
....
- rhel-system-roles.timesync, (unknown version)
# /etc/ansible/roles
 [WARNING]: - the configured path /home/greg/.ansible/roles does not exist.
 
 
2.定义角色路径
[greg@control /]$ cd ~/ansible/   #在ansible工作目录中查看时属于greg用户定制的角色路径
[greg@control ansible]$ vim ansible.cfg
roles_path    = /home/greg/ansible/roles:/usr/share/ansible/roles #:冒号分割,并添加系统角色路径
[greg@control ansible]$ ansible-galaxy list
# /home/greg/ansible/roles                        #之前定义好的自定义角色路径
- apache, (unknown version)
# /usr/share/ansible/roles                      #系统角色路径
- linux-system-roles.kdump, (unknown version)
......
- rhel-system-roles.timesync, (unknown version)

3.使用系统角色,将系统角色添加至playbook并应用
[greg@control ansible]$ rpm -ql rhel-system-roles.noarch | grep timesync #看README.md
[greg@control ansible]$ cp /usr/share/doc/rhel-system-roles/timesync/example-timesync-playbook.yml /home/greg/ansible/timesync.yml   #找例子,并复制到工作目录中
[greg@control ansible]$ vim timesync.yml      #编辑角色
---
- hosts: all
  vars:
    timesync_ntp_servers:
      - hostname: 172.25.254.254
        iburst: yes
  roles:
    - rhel-system-roles.timesync

4.使用系统角色
[greg@control ansible]$ ansible-playbook timesync.yml

查询验证
ansible all -a 'chronyc sources -v'

11.5.3 通过内容集合安装使用系统角色

# 1.timesync
$ cp /usr/share/ansible/collections/ansible_collections/redhat/rhel_system_roles/docs/timesync/multiple-ntp-servers.yml  timesync.yml
$ vim timesync.yml
- hosts: all
  vars:
    timesync_ntp_servers:
      - hostname: 172.25.254.254
        iburst: yes
  roles:
    - redhat.rhel_system_roles.timesync
$ ansible-navigator run timesync.yml -m stdout
$ ansible all -m shell -a 'chronyc sources -v '

# 2.selinux
$ cp /usr/share/ansible/collections/ansible_collections/redhat/rhel_system_roles/docs/selinux/selinux-playbook.yml selinux.yml
$ vim selinux.yml
---
- hosts: all
  vars:
    selinux_policy: targeted
    selinux_state: permissive

  roles:
  - redhat.rhel_system_roles.selinux
$ ansible-navigator run selinux.yml  -m stdout
# 验证
$ ansible all -m shell -a 'grep ^SELINUX= /etc/selinux/config'

11.6 通过文件安装角色

Ansible官网:https://docs.ansible.com/ansible/2.9/galaxy/user_guide.html#installing-roles-from-galaxy

https://galaxy.ansible.com/nginxinc/nginx_core  #该网站可以查看角色包信息

#实验需要在模拟考试环境下做,普通环境没有角色包
[greg@control ansible]$ vim roles/requirements.yml  #制作角色部署文件
---
- src: http://materials/phpinfo.tar    #角色在网络中的路径
  name: phpinfo                           #指定安装在系统中的角色名称
- src: http://materials/haproxy.tar
  name: balancer
  
[greg@control ansible]$ ansible-galaxy install --help
[greg@control ansible]$ ansible-galaxy install -r roles/requirements.yml  #-r 指定角色文件
[greg@control ansible]$ ansible-galaxy list   #检测
# /home/greg/ansible/roles
- phpinfo, (unknown version)    #查看结果
- balancer, (unknown version)

12 对Ansible进行故障排除

12.1 对playbook进行故障排除

12.1.1 调试Playbook

-rhel8
ansible-playbook debug.yml -v   #显示详细信息-v -vv -vvv -vvvv

-rhel9
ansible-navigator run playbook.yml -m stdout -v

12.1.2 Debug

#通过debug模块打印收集到的变量信息,帮助管理员了解模块执行过程及结果
---
- hosts: serverb
  tasks:
  - name: install the latest version of Apache
    ansible.builtin.yum:
      name: vsftpd
      state: latest
    register: web_install   #注册变量收集模块的执行信息
  - ansible.builtin.debug:
      var: web_install      #debug模块可以帮助打印出执行信息

#可以一次性将hostvars收集到的所有魔法及事实变量打印出来,并可以记录到文件中
[greg@control ansible]$ vim debug.yml
---
- name: test
  hosts: node1
  tasks:
  - ansible.builtin.debug:
      var: hostvars
[greg@control ansible]$ ansible-navigator run -m stdout debug.yml > 2.txt 
 

关闭事实收集
如果要关闭收集,可以编辑配置文件
gathering = explicit
或者在playbook里
gather_facts: yes/no  true/false

12.1.3 检查Playbook的错误

-RHEL8
$ ansible-playbook playbook.yml --syntax-check
playbook: playbook.yml

-RHEL9
greg@control ansible]$ ansible-navigator run -m stdout debug.yml   --syntax-check
playbook: /home/greg/ansible/debug.yml

12.1.4 检查Playbook的问题

#常见语法问题
name:  冒号后面要空格,内容随意
hosts: all 指定的主机不在清单中,报错无partten
syntax-errors:注意格式缩进,2格缩进
变量设置错误,或调用时错误(变量名写错,变量开头要加双引号)  
when条件: (逻辑判断思路错误,或书写错误)

12.1.5 检查Playbook工件和日志文件

# ansible-navigator可以生成playbook工件,以JSON格式存储与playbook的运行相关的信息
# 可以将与playbook运行相关的信息记录到系统上您可写入位置处的文本文件中
# RHEL9中的ansible自动开启日志功能,可通过配置文件设置及手工设置

# 配置文件
$ vim ~/.ansible-navigator.yml
---
ansible-navigator:
  execution-environment:
    image: utility.lab.example.com/ee-supported-rhel8:latest
    pull:
      policy: missing
  playbook-artifact:
    enable: false    # false/true 关闭/打开

# 手工指定
--pae  --playbook-artifact-enable

12.1.6 输出记录到文本文件

-RHEL8&9

1.Ansible提供了一个内置日志基础架构,可通过ansible.cfg配置文件[defaults]部分中的log_path参数或$ANSIBLE_LOG_PATH环境变   量进行配置。在进行上面一项或两项配置后,Ansible会以文本形式将ansible-navigator命令的输出存储到所配置的日志文件中。此机制   也适用于ansible-playbook等早期的工具
2.如果将Ansible配置为将日志文件写入/var/log,红帽建议您配置logrotate来管理文件

12.2 对Ansible受管主机进行故障排除

12.2.1 Ansible运行临时命令

# ad-hoc命令可以用于简单部署场景,比如对一组目标部署一个任务,或检索受管节点的运行情况、状态等
ansible all -m ping

# RHEL9中默认不允许root用户登录,需要修改配置文件允许root登录。所建议使用普通用户作为远程管理用户
# 解决方法,服务器端:
$ vim /etc/ssh/sshd_config
# PermitRootLogin prohibit-password
PermitRootLogin yes
$ systemctl  reload sshd

12.2.2 手动控制执行

$ ansible-playbook playbook.yml --step
$ ansible-navigator run playbook.yml  -m stdout --step

PLAY [PLAY1] ********************************************************************************************
Perform task: TASK: Gathering Facts (N)o/(y)es/(c)ontinue: n

#手动输入n  y c来控制playbook中执行的步骤
1.n 不执行该步骤
2.y 执行该步骤
3.c 继续自动执行到结束
# 通过该方法可以让有问题的步骤执行,而无关紧要的步骤可以跳过不执行。达到排错的目的

12.2.3 从指定步骤执行任务

[greg@control ansible]$ ansible-playbook playbook.yml --start-at-task='Start service httpd'

--start-at-task   #指定具体执行步骤,等号后面指定模块的描述,如果描述内容中有空格,建议用单或双引号引起来,表示为一个参数

12.2.4 烟雾测试

# 烟雾测试:在管理节点执行剧本,显示剧本的真实执行结果,但是不在受管节点上部署
$ ansible-playbook playbook.yml --help | grep \\-C
$ ansible-navigator run playbook.yml  -m stdout -C
[greg@control ansible]$ vim playbook.yml
---
- name: PLAY1
  hosts: node2
  tasks:
  - name: install  apache
    ansible.builtin.yum:
      name: httpd
      state: latest
  - name: Copy using inline content
    ansible.builtin.copy:
      content: 'test web page'
      dest: /var/www/html/index.html
  - name: Start service httpd
    ansible.builtin.service:
      name: httpd
      state: started
  - name: Start service firewalld
    ansible.builtin.service:
      name: firewalld
      state: started
  - name: permit apache
    ansible.posix.firewalld:
      service: http
      permanent: yes
      state: enabled
      immediate: yes
[greg@control ansible]$ ansible-playbook playbook.yml -C

12.2.5 发送脚本解决问题

$ vim test.sh   #自定义脚本名及内容
#!/bin/bash
date
$ vim debug.yml #剧本名自定义
---
- name:
  hosts: node1
  tasks:
  - name: Run a script
    ansible.builtin.script: /home/greg/ansible/test.sh    #使用script模块,加脚本文件路径
    register: haha   #register收集上面模块执行结果至 haha(自定义名称)的这个变量中
  - ansible.builtin.debug:
      var: haha   #通过debug模块将haha变量的值打印出来。
$ ansible-playbook debug.yml     

`如果不想写register,可以执行剧本时添加-v 类似:ansible-playbook debug.yml -v`

13 自动执行Linux管理任务

13.1 管理软件和订阅

13.1.1 优化多软件包安装

ansible.builtin.---

- name:
  hosts: all
  tasks:
  - name: install the latest version of Apache
    ansible.builtin.yum:
      name: httpd   #httpd
      state: latest
  - name: install the latest version of Apache
    ansible.builtin.yum:
      name: php   #php
      state: latest
---------------------------------------------
- name: install the latest version of Apache
  ansible.builtin.yum:
      name: "{{ item }}"
      state: latest
  loop:     #用loop方式简化playbook
    - httpd
    - php
      
yum install -y httpd
yum install -y php
---------------------------------------------
- name: install the latest version of Apache
  ansible.builtin.yum:
    name: 
    - httpd
    - php
    state: latest
yum install -y httpd php
--------------------------------------------- 
- name: ensure a list of packages installed
  ansible.builtin.yum:
    name: "{{ packages }}"
  vars:
    packages:
    - httpd
    - httpd-tools
--------------------------------------------- 
      
# 等同于:yum install -y httpd php或 loop的这种方式,系统会执行两次独立事务,对每个事务应用一个软件包
# yum模块:
  state: absent删除, installed,  present确保安装  latest升级到最新版本
  latest 等同  yum update

 name: '*'  代表所有软件包
 name: "@RPM Development tools"   ansible命令里面安装包组要加@

13.1.2 收集已安装软件包的事实

---
- name:
  hosts: node1
  tasks:
  - name: Gather the package facts
    ansible.builtin.package_facts:
      manager: auto

  #- name: Print the package facts
  #  ansible.builtin.debug:
  #    var: ansible_facts.packages

  - name: Check whether a package called foobar is installed
    ansible.builtin.debug:
      msg: "{{ ansible_facts.packages.zip.0.version }}"

13.1.3 管理软件包的其他模块

- name: Install httpd on RHEL 8 and 9
  ansible.builtin.dnf
    name: httpd
    state: present

- name: Install httpd on RHEL 7 and earlier
  ansible.builtin.yum:
    name:httpd
    state:present

13.1.4 RPM软件包存储库

$ ansible-doc -l | grep yum

---
- name:
  hosts: node1
  tasks:
  - name: Add multiple repositories into the same file (1/2)
    ansible.builtin.yum_repository:
      name: EX294_BASE #file字段不存在时,默认用name字段代替源文件名称
      description: EX294 base software
      file: rhel  #file选项作用是定义yum源文件名称,无该字段时会用name字段后的值代替文件名 例如:rhel.repo
      baseurl: http://content/rhel8.4/x86_64/dvd/BaseOS
      gpgcheck: yes
      gpgkey: http://content/rhel8.4/x86_64/dvd/RPM-GPG-KEY-redhat-release
      enabled: yes
      
  - name: Add multiple repositories into the same file (1/2)
    ansible.builtin.yum_repository:
      name: EX294_STREAM
      description: EX294 stream software
      file: rhel  #多个模块使用同一个file字段的名称时,会将源地址写入到同一个文件中。
      baseurl: http://content/rhel8.4/x86_64/dvd/AppStream
      gpgcheck: yes
      gpgkey: http://content/rhel8.4/x86_64/dvd/RPM-GPG-KEY-redhat-release
      enabled: yes  #enabled默认值为yes,考试时要写该选项。


ansible模块选项和vim配置文件内容对比
  vim:                ansible:
      rhel.repo          file
      [rhel]            * name
      name=rhel         * description
      baseurl=            * baseurl
      gpgcheck=            * gpgcheck
      gpgeky=            * gpgkey
      enabled=            * enabled     
      
#测试方法:$ ansible all -a 'yum repolist all'
# 受管节点检测  $ cat rhel.repo
$ ansible-doc rpm_key   
- ansible.builtin.rpm_key:
    state: present
    key: http://apt.sw.be/RPM-GPG-KEY.dag.txt

13.2 管理用户和身份验证

13.2.1 user模块

#在servera上创建用户tom 附加组为group1,并设置密码为password tom: tom123用sha512方式哈希,uid =2000
#user这个模块类似这些功能: useradd userdel usermod

$ cat group.yml     
- name:
  hosts: node1
  vars:
  - passwordtom: tom123
  tasks:
  - name:  create group
    ansible.builtin.group:
      name: "{{ item }}"
    loop:
      - group1
      - group2
  - name: Add the
    ansible.builtin.user:
      name: tom            #useradd tom
      comment: student     #useradd -c student
      uid: 2000            #useradd -u 2000
      password_expire_max: 10     #passwd -e 10
      group: group1             #useradd -g group1
      groups: group1,group2     #-G group1,group2
      shell: /bin/bash          #-s /bin/bash
      password: "{{ passwordtom | password_hash('sha512') }}"    passwd tom
      #passwordtom该密码位置如果是字符串用单引号引起来,如果是变量则不需要单引号
      
          
#验证用户密码过期时间
chage -l tom
Password expires                    : Jun 11, 2024
#验证用户密码是否正确,可以从node2登录node1,测试node1上的tom用户
ssh tom@node1

Ansible网页搜索:password_hash--Using filter--网页中查找password_hash,查看密码哈希方式,一定注意是512
Ansible官网:  https://docs.ansible.com/ansible/latest/user_guide/playbooks_filters.html
      模块中:append: yes    如果想额外添加附加群组,此选项需要yes(usermod -a -G  grouptest u1) 

13.2.2 group模块

[greg@bastion ansible]$ cat group.yml 
---
- name:
  hosts: dev
  tasks:
  - name: Ensure group "grouptest" exists
    ansible.builtin.group:
      gid: 10000
      name: grouptest
      state: present | absent   #创建|删除 二选一

#等同于:groupadd  grouptest
#等同于:groupadd -g 10000 grouptest
#groupdel

13.3 管理启动过程和调度进程

13.3.1 at

---
- name:
  hosts: dev
  tasks:
  - name: Schedule a command to execute in 20 minutes as root
    ansible.posix.at:
      command: ls -d / >/dev/null
      count: 20
      units: minutes
# 默认是创建一个任务,给root,删除的    话使用选项state:absent

13.3.2 cron

[greg@bastion ansible]$ ansible-doc cron
[greg@bastion ansible]$ cat cron.yml 
---
- name:
  hosts: all
  tasks:
  - name: Ensure a job that runs at 2 and 5 exists. 
    ansible.builtin.cron:
      name: "check dirs"  #描述  
      minute: "*/2"          #分钟
      hour: "2,5"         #小时
      day: 1-10           #天
      user: harry
      job: "ls -alh > /dev/null"
     
[greg@bastion ansible]$ ansible dev -m shell -a 'crontab -u harry -l'

13.3.3 管理服务

---
- name:
  hosts: dev
  tasks:
  - name: install the latest version of Apache
    ansible.builtin.yum:
      name: httpd
      state: latest
          
  - name: Start service httpd, if not started
    ansible.builtin.service:
      name: httpd
      state: started
      enabled: yes    #开机自启动

13.3.4 systemd

[greg@bastion ansible]$ cat systemd.yml 
---
- name:
  hosts: dev
  tasks:
  - name: install the latest version of Apache
    ansible.builtin.yum:
      name: httpd
      state: latest

  - name: Make sure a service is running
    ansible.builtin.systemd:
      name: httpd
      state: started
      enabled: yes
      
测试命令:
ansible dev -m shell -a 'systemctl status httpd'
ansible dev -m shell -a 'systemctl is-enabled httpd'

# 1.reboot
- name: Unconditionally reboot the machine with all defaults
  reboot:
  
# 2.command & shell  支持更多的特殊字符
$ ansible servera -m command -a 'useradd user1'
$ ansible servera -a 'useradd user2'
$ ansible servera -a 'echo 123456 | passwd --stdin user1'
$ ansible servera -m shell -a 'echo 123456 | passwd --stdin user1'

13.4 管理存储

模块名 linux指令 Linux实施命令
community.general.parted parted parted /dev/vdb mkpart part1 2048s 1G
community.general.lvg vgcreate vgcreate -s 16M vg100 /dev/vdb{1..2}
community.general.lvol lvcreate lvcreate -L 100M -n lv100 vg100
community.general.filesystem mkfs mkfs.ext4 /dev/vg100/lv100
ansible.posix.mount /etc/fstab echo “/dev/vg100/lv100 ext4 /mnt/data defaults 0 0” > /etc/fstab

13.4.1 模块管理存储

1.纯分区无lvm逻辑卷

1-1 分区 community.general.parted #先确保community.general集合已经安装,可通过ansibl-galaxy collection list来查看
# 创建两个分区每个500M
---
- name: parted
  hosts: node2
  tasks:
  - name: part 1 2048s-500M
    community.general.parted:
      device: /dev/vdc
      number: 1
      state: present
      part_end: 500MiB
  - name: part 2 500M-1000M
    community.general.parted:
      device: /dev/vdc
      number: 2
      state: present
      part_start: 500MiB
      part_end: 1GiB

1-2 格式化 community.general.filesystem
#两个分区都格式化为ext4文件系统,如果选择不同文件系统,可以分成两个模块。
  - name: Create a ext4
    community.general.filesystem:
      fstype: ext4
      dev: "{{ item }}" 
    loop:
      - /dev/vdc1
      - /dev/vdc2

1-3 挂载 ansible.posix.mount
#自动创建挂载点/mnt/part1,再将/dev/vdc1写入/etc/fstab文件最后一行,并挂载。
  - name: Mount DVD read-only
    ansible.posix.mount:
      path: /mnt/part1      #挂载点
      src: /dev/vdc1        #设备
      fstype: ext4            #文件系统类型
      state: mounted        #参考下面解释
      
-挂载选项解释:
# absent:     卸载并删除/etc/fstab内容  
# unmounted: 卸载不删除/etc/fstab内容
# present:   将挂在信息写入/etc/fstab,不挂载
# mounted:   将挂在信息写入/etc/fstab,并创建挂载点及挂载
# remounted: 重新挂载

2.有lvm逻辑卷

2.分区-lvm(pv,vg,lv)-格式化-挂载
2-1 分区 community.general.parted 
#分两个区每个大约500M,/dev/vdb
---
- name: lv
  hosts: node2
  tasks:
  - name: part 1 2048s-500M
    community.general.parted:
      device: /dev/vdb
      number: 1
      state: present
      part_end: 500MiB
  - name: part 2 500M-1000M
    community.general.parted:
      device: /dev/vdb
      number: 2
      state: present
      part_start: 500MiB

2-2 pv+vg community.general.vg
#两个分区都加入vg,名称vg100
#ansible-navigator collections -m stdout | grep vg$ 查看帮助
  - name: Create a volume group vg100
    community.general.lvg:
      vg: vg100
      pvs: /dev/vdb1,/dev/vdb2
      pesize: 32

2-3 lv community.general.lvol
#创建一个lv名为lv100,大小800M
  - name: Create a logical volume lv100 size 800M
    community.general.lvol:
      vg: vg100
      lv: lv100
      size: 800
2-4 格式化 community.general.filesystem
#格式化为xfs文件系统
 - name: Create a xfs
    community.general.filesystem:
      fstype: xfs
      dev: /dev/vg100/lv100
2-5 挂载 ansible.posix.mount
#lv挂载到/mnt/data,并设置为开机自启动。
  - name: /mnt/data
    ansible.posix.mount:
      path: /mnt/data
      src: /dev/vg100/lv100
      fstype: xfs
      state: mounted
            
#整体配置
---
- name: lv
  hosts: node2
  tasks:
  - name: part 1 2048s-500M
    community.general.parted:
      device: /dev/vdb
      number: 1
      state: present
      part_end: 500MiB
  - name: part 2 500M-1000M
    community.general.parted:
      device: /dev/vdb
      number: 2
      state: present
      part_start: 500MiB
  - name: Create a volume group vg100
    community.general.lvg:
      vg: vg100
      pvs: /dev/vdb1,/dev/vdb2
      pesize: 32
  - name: Create a logical volume lv100 size 800M
    community.general.lvol:
      vg: vg100
      lv: lv100
      size: 800
  - name: Create a xfs
    community.general.filesystem:
      fstype: xfs
      dev: /dev/vg100/lv100
  - name: /mnt/data
    ansible.posix.mount:
      path: /mnt/data
      src: /dev/vg100/lv100
      fstype: xfs
      state: mounted

13.4.2 系统角色管理存储

# 逻辑卷角色
[greg@control ansible]$ sudo find ./mycollection/ -name '*.yml' | grep storage|grep test.yml
./mycollection/ansible_collections/redhat/rhel_system_roles/tests/storage/test.yml
[greg@control ansible]$ cp ./mycollection/ansible_collections/redhat/rhel_system_roles/tests/storage/test.yml ./storage.yml
[greg@control ansible]$ vim disk.yml
$ vim storage.yml
---
- hosts: node4
  vars:
    storage_use_partitions: true

  roles:
    - name: redhat.rhel_system_roles.storage
      storage_pools:
        - name: vg100
          disks:
          - /dev/vdb
          volumes:
            - name: lv100
              size: 200M
              fs_type: ext4
              mount_point: '/mnt/lvm100'
              state: "present"
            - name: lv200
              size: 300M
              fs_type: xfs
              mount_point: '/mnt/lvm200'
              state: "absent"

$ ansible-navigator run storage.yml  -m stdout

13.5 管理网络

[greg@control ansible]$ sudo find ./mycollection/ -name '*.md' | grep network
[greg@control ansible]$ vim ./mycollection/ansible_collections/redhat/rhel_system_roles/roles/network/README.md
[greg@control ansible]$ sudo find ./mycollection/ -name '*.yml' | grep network 

$ vim /usr/share/doc/rhel-system-roles/collection/roles/network/README.md
$ vim playbook.yml
---
- hosts: node5
  vars:
    network_connections:
    - name: eth0
      interface_name: eth0
      type: ethernet
      state: up
      autoconnect: yes
      ip:
        address:
        - 192.0.2.3/24
        dns:
        - 192.0.2.2
        dns_search:
        - example.com
        dhcp4: no
        gateway4: 192.0.2.1
        auto6: no

  roles:
    - redhat.rhel_system_roles.network

$ ansible-navigator run playbook.yml  -m stdout

14 普通用户远程管理受管主机

14.1 超级用户远程管理方式

vim /home/greg/ansible/ansible.cfg
remote_user=root
host_key_checking = False

vim /home/greg/ansible/inventory
[all:vars]
#ansible_user=root
ansible_password=redhat

14.2 普通用户远程管理方式

# 使用greg用户远程管理受管主机
【bastion】控制节点
ansible.cfg
[defaults]
remote_user = greg
host_key_checking = False

[privilege_escalation]
become=True
become_method=sudo 
become_user=root
become_ask_pass=false

#管理节点
ssh-keygen 

ssh-copy-id greg@workstation
ssh greg@workstation

#其他受管主机上每一个主机都做如下操作
[root@workstation ~]# useradd  greg
[root@workstation ~]# echo redhat | passwd --stdin greg
[root@workstation ~]# visudo
greg    ALL=(ALL)       NOPASSWD: ALL

文章作者: 罗宇
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 罗宇 !
 上一篇
数据库基础 数据库基础
数据库指的是以一定方式储存在一起、能为多个用户共享、具有尽可能小的冗余度、与应用程序彼此独立的数据集合
2024-05-14
下一篇 
Linux进阶 Linux进阶
Linux操作系统广泛应用于服务器、桌面和嵌入式设备中,以其稳定性、安全性和高效性受到广泛欢迎‌‌,文章描述了Linux的进阶使用
2023-05-28
  目录