目录

主机清单(常见为INI格式)

一.定义主机列表

1.每行写一个

2.主机组

(1)定义简单主机组

(2)指定多台主机时可以通过书写范围来表示

(3)定义嵌套主机组

二.匹配主机和组

1.匹配所有主机

(1)all

(2)特殊使用*号,单独使用无效

2.匹配指定主机或组

(1)匹配一个或多个组

(2)匹配一个或多个主机

3.匹配未分配组的主机

4.通配符匹配

(1)以什么开头或结尾的主机,或者是通过组名匹配出来的主机

(2)匹配非匹配范围内的主机,或者非匹配范围内的组匹配出来的主机

(3)匹配包含某关键字的主机或包含某关键的组内的主机

(4)匹配同时属于两个组的主机

5.正则表达式匹配

6.通过limit来匹配主机

ansible配置文件

一.优先级

二.配置文件详解

1.defaults部分

2.privilege_escalation

3.paramiko_connection

4.ssh_connection

5.persistent_connection

6.accelerate(加速模块ansible1.5版本后很少用)

7.selinux

8.简单测试是否能够进行节点通信

主机清单和配置文件练习

1.安装并配置ansible,在控制节点上安装并配置ansible

2.创建并运行 Ansibie ad-hoc 命令


 

主机清单(常见为INI格式)

一.定义主机列表

1.每行写一个

可以是域名、主机名、IP地址,此时它们没有被分到任何一个组内,属于ungroup

[student@workstation ~]$ cat myhosts
servera.xxx.com
serverb
172.25.xxx.xx
[student@workstation ~]$ ansible-inventory -i myhosts --graph  #-i指定主机文件,--graph创建库存图
@all:
  |--@ungrouped:
  |  |--172.25.xxx.xx
  |  |--servera.xxx.com
  |  |--serverb

2.主机组

(1)定义简单主机组

[student@workstation ~]$ cat myhosts1
[webservers]
servera
serverb
[dbservers]
serverc
serverd.lab.example.com

[student@workstation ~]$ ansible-inventory -i myhosts1 --graph  
#默认的主机文件是/etc/ansible/hosts,使用其他文件时需要指定
@all:
  |--@dbservers:
  |  |--serverc
  |  |--serverd.lab.example.com
  |--@ungrouped:
  |--@webservers:
  |  |--servera
  |  |--serverb

(2)指定多台主机时可以通过书写范围来表示

[student@workstation ~]$ cat myhosts2
[mywebservers]
server[a:d]      #以“[x:y]”来表示从x到y的范围

[student@workstation ~]$ ansible mywebservers -i myhosts2 --list-hosts  
#通过指定具体的主机文件中的组名来查看组下主机
  hosts (4):
    servera
    serverb
    serverc
    serverd

(3)定义嵌套主机组

[student@workstation ~]$ cat myhosts1
[webservers]
servera
serverb

[dbservers]
serverc
serverd.lab.example.com

[conment:children]    #以“:children表示包含若干组”
webservers

[student@workstation ~]$ ansible conment -i myhosts1 --list-hosts
  hosts (2):
    servera
    serverb

二.匹配主机和组

1.匹配所有主机

(1)all

[student@workstation ~]$ ansible all -i myhosts1 --list-hosts
  hosts (4):
    serverc
    serverd.lab.example.com
    servera
    serverb

(2)特殊使用*号,单独使用无效

[student@workstation ~]$ ansible * -i myhosts1 --list-hosts
 [WARNING]: Could not match supplied host pattern, ignoring: myhosts1

 [WARNING]: No hosts matched, nothing to do

  hosts (0):

[student@workstation ~]$ ansible \* -i myhosts1 --list-hosts  #转义
  hosts (4):
    serverc
    serverd.lab.example.com
    servera
    serverb
    
[student@workstation ~]$ ansible '*' -i myhosts1 --list-hosts   #单引号
  hosts (4):
    serverc
    serverd.lab.example.com
    servera
    serverb

[student@workstation ~]$ ansible "*" -i myhosts1 --list-hosts   #双引号
  hosts (4):
    serverc
    serverd.lab.example.com
    servera
    serverb

[student@workstation ~]$ ansible '''*''' -i myhosts1 --list-hosts   #三引号
  hosts (4):
    serverc
    serverd.lab.example.com
    servera
    serverb

2.匹配指定主机或组

(1)匹配一个或多个组

[student@workstation ~]$ ansible webservers -i myhosts1 --list-hosts
  hosts (2):
    servera
    serverb
[student@workstation ~]$ ansible webservers,dbservers -i myhosts1 --list-hosts  
#多个组以“,”分隔,这行也可以理解为属于“webservers”或“dbservers”组的主机
  hosts (4):
    servera
    serverb
    serverc
    serverd.lab.example.com

(2)匹配一个或多个主机

[student@workstation ~]$ ansible servera -i myhosts1 --list-hosts
  hosts (1):
    servera
[student@workstation ~]$ ansible servera,serverc -i myhosts1 --list-hosts  
#多个主机以“,”分隔
  hosts (2):
    servera
    serverc

3.匹配未分配组的主机

[student@workstation ~]$ ansible ungrouped -i myhosts1 --list-hosts
  hosts (1):
    haha

4.通配符匹配

(1)以什么开头或结尾的主机,或者是通过组名匹配出来的主机

[student@workstation ~]$ ansible 'server*' -i myhosts1 --list-hosts
  hosts (4):
    servera
    serverb
    serverc
    serverd.lab.example.com

[student@workstation ~]$ ansible '*.com' -i myhosts1 --list-hosts
  hosts (1):
    serverd.lab.example.com

[student@workstation ~]$ ansible 'web*' -i myhosts1 --list-hosts
  hosts (2):
    servera
    serverb
    
[student@workstation ~]$ ansible 'db*' -i myhosts1 --list-hosts
  hosts (2):
    serverc
    serverd.lab.example.com

(2)匹配非匹配范围内的主机,或者非匹配范围内的组匹配出来的主机

[student@workstation ~]$ ansible '!*.com' -i myhosts1 --list-hosts   
#使用"!"
  hosts (4):
    haha
    serverc
    servera
    serverb

[student@workstation ~]$ ansible '!web*' -i myhosts1 --list-hosts   
#匹配出来的是"dbservers"组内的主机
  hosts (3):
    haha
    serverc
    serverd.lab.example.com
    
[student@workstation ~]$ ansible 'server*,!*.com' -i myhosts1 --list-hosts 
#匹配以"server"开头但不以".com"结尾的主机
  hosts (3):
    servera
    serverb
    serverc
    
[student@workstation ~]$ ansible 'w*,!*s' -i myhosts1 --list-hosts  
#匹配以"w"开头但不以"s"结尾的组内的主机
  hosts (2):
    server1
    serverh
[student@workstation ~]$ cat myhosts1
haha
[webservers]
servera
serverb

[dbservers]
serverc
serverd.lab.example.com

[webservers1]
server1
serverh

[conment:children]
webservers

(3)匹配包含某关键字的主机或包含某关键的组内的主机

[student@workstation ~]$ ansible '*server*' -i myhosts1 --list-hosts
  hosts (6):
    servera
    serverb
    serverc
    serverd.lab.example.com
    server1
    serverh
[student@workstation ~]$ ansible '*web*' -i myhosts1 --list-hosts
  hosts (4):
    servera
    serverb
    server1
    serverh

(4)匹配同时属于两个组的主机

[student@workstation ~]$ ansible-inventory -i myhosts1 --graph
@all:
  |--@conment:
  |  |--@webservers:
  |  |  |--servera
  |  |  |--serverb
  |--@dbservers:
  |  |--serverc
  |  |--serverd.lab.example.com
  |--@ungrouped:
  |  |--haha
  |--@webservers1:
  |  |--server1
  |  |--servera
  |  |--serverh
  
[student@workstation ~]$ ansible 'webservers,&webservers1' -i myhosts1 --list-hosts  
#逻辑与“&”,逻辑或见“2(1)示例,逻辑非“!”见4(2)示例
  hosts (1):
    servera

5.正则表达式匹配

[student@workstation ~]$ ansible-inventory -i myhosts1 --graph
@all:
  |--@conment:
  |  |--@webservers:
  |  |  |--servera
  |  |  |--serverb
  |--@dbservers:
  |  |--serverc
  |  |--serverd.lab.example.com
  |--@ungrouped:
  |  |--haha
  |--@webservers1:
  |  |--server1
  |  |--servera
  |  |--serverh


[student@workstation ~]$ ansible '~^(s|c)' -i myhosts1 --list-hosts
#“~”表示标记这是一个正则表达式,以“s”开头或以“c”开头,以“s”开头的输出后,没有以“c”开头的主机,但有以“c”开头的组,会输出其下的主机
  hosts (6):
    servera
    serverb
    serverc
    serverd.lab.example.com
    server1
    serverh
    
[student@workstation ~]$ ansible '~^(o|c)' -i myhosts1 --list-hosts
  hosts (2):
    servera
    serverb

6.通过limit来匹配主机

[student@workstation ~]$ ansible server* -i myhosts1 --list-hosts --limit servera #可以在后面直接指定
  hosts (1):
    servera

[student@workstation ~]$ ansible server* -i myhosts1 --list-hosts --limit @list  #可以指定定义好主机的文件
  hosts (1):
    servera
[student@workstation ~]$ cat list
servera

ansible配置文件

一.优先级

一般情况下的主要就是"ANSIBLE_CONFIG=指定.cfg文件的绝对路径" > ./ansible.cfg" > "~/.ansible.cfg" > "/etc/ansible/ansible.cfg"

[student@workstation ~]$ ansible --version
ansible 2.8.0
  config file = /etc/ansible/ansible.cfg   #当前使用的是"/etc/ansible/ansible.cfg"
  configured module search path = ['/home/student/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /usr/lib/python3.6/site-packages/ansible
  executable location = /usr/bin/ansible
  python version = 3.6.8 (default, Apr  3 2019, 17:26:03) [GCC 8.2.1 20180905 (Red Hat 8.2.1-3)]

ANSIBLE_CONFIG用法示例

[student@workstation ~]$ cat ansible.cfg
[defaults]
inventory=/home/student/myhosts1
[student@workstation ~]$ ll
total 12
-rw-rw-r--. 1 student student  45 Oct 12 10:30 ansible.cfg
-rw-rw-r--. 1 student student   8 Oct 12 09:34 list
-rw-rw-r--. 1 student student 149 Oct 12 08:58 myhosts1

[student@workstation ~]$ ANSIBLE_CONFIG=/home/student/ansible ansible webservers --list-hosts
  hosts (2):
    servera
    serverb

[student@workstation ~]$ ansible --version
ansible 2.8.0
  config file = /home/student/ansible.cfg   #此时默认配置文件就变了
  configured module search path = ['/home/student/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /usr/lib/python3.6/site-packages/ansible
  executable location = /usr/bin/ansible
  python version = 3.6.8 (default, Apr  3 2019, 17:26:03) [GCC 8.2.1 20180905 (Red Hat 8.2.1-3)]

[student@workstation ~]$ export ANSIBLE_CONFIG=/home/student/ansible.cfg  
#也可以export声明这个文件的路径,可以通过unset进行取消配置
[student@workstation ~]$ ansible --version
ansible 2.8.0
  config file = /home/student/ansible.cfg
  configured module search path = ['/home/student/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /usr/lib/python3.6/site-packages/ansible
  executable location = /usr/bin/ansible
  python version = 3.6.8 (default, Apr  3 2019, 17:26:03) [GCC 8.2.1 20180905 (Red Hat 8.2.1-3)]

二.配置文件详解

1.defaults部分

[defaults]
inventory=    #指定清单文件路径
remote_user=   #用来在受管节点上登录的用户名,不指定则为当前用户
become=True  #连接后是否在受管节点上切换用户,一般是切换到root
become_method=sudo  #以sudo方式切换,也可以选择su
become_user=root   #在受管节点上要切换的用户,默认root
sudo_user=root  #默认执行命令的用户
ask_sudo_pass=True   #是否需要sudo密码
become_ask_pass=False  #是否为切换方式提示输入密码,默认false
host_key_checking=False  #首次连接时是否检查ssh主机的密钥
ask_pass=True  #是否提示输入ssh连接密码,使用公钥验证应为false
library=/usr/share/my_modules/  #指定存放ansible模块的目录
timeout=10  #远程连接超时时间,以秒为单位
log_path=/var/log/ansible.log   #指定ansible的日志存储文件位置
private_key_file=/path/to/file   #私钥密钥路径
roles_path=/etc/ansible/roles  # role存放目录
forks= 5   #设置默认多少个进程同时运行,进程并发数,默认5个
remote_port    = 22   #连接受管节点的管理端口,ssh22端口
poll_interval=15   #轮询间隔时间,默认15秒
module_name =    #默认执行的模块
#action_plugins     = /usr/share/ansible/plugins/action
#become_plugins     = /usr/share/ansible/plugins/become
#cache_plugins      = /usr/share/ansible/plugins/cache
#callback_plugins   = /usr/share/ansible/plugins/callback
#connection_plugins = /usr/share/ansible/plugins/connection
#lookup_plugins     = /usr/share/ansible/plugins/lookup
#inventory_plugins  = /usr/share/ansible/plugins/inventory
#vars_plugins       = /usr/share/ansible/plugins/vars
#filter_plugins     = /usr/share/ansible/plugins/filter
#test_plugins       = /usr/share/ansible/plugins/test
#terminal_plugins   = /usr/share/ansible/plugins/terminal
#strategy_plugins   = /usr/share/ansible/plugins/strategy
#此上等等为各插件存放位置

2.privilege_escalation

[privilege_escalation]
become=True  #是否切换用户
become_method=sudo  #以什么方式切换
become_user=root  #切换到哪个用户
become_ask_pass=False   #是否需要sudo密码

3.paramiko_connection

[paramiko_connection]
record_host_keys=False  #是否记录新主机的密钥,类似于保存用户在此节点的密码
pty=False    #是否禁用sudo功能
look_for_keys=False   #是否在~/.ssh中寻找密钥文件
host_key_auto_add=True  #是否自动添加主机密钥

4.ssh_connection

[ssh_connection]
scp_if_ssh = smart   
#设置传输机制,smart先尝试sftp后尝试scp,True只使用scp,False只使用sftp
transfer_method = smart 
#同scp_if_ssh,两者同时设置时后者覆盖前者,但在scp_if_ssh基础上新增了piped模式表示通过ssh的'dd'来传输,并且在smart模式下,尝试传输顺序为sftp-scp-piped
sftp_batch_mode = False   # 是否批处理模式来传输文件
usetty = True   #是否启动管道传输
retries = 3  #重试与主机重连次数

5.persistent_connection

[persistent_connection]
connect_timeout = 30  
#持久链接超时时间,在这个值之前收到连接请求,连接才不会被关闭,默认30秒
command_timeout = 30  
#命令超时时间,意思是设置在连接超时前分配多少时间等待命令请求或RPC调用请求,需要小于等于持久连接超时时间

6.accelerate(加速模块ansible1.5版本后很少用)

7.selinux

[selinux]
special_context_filesystems=nfs,vboxsf,fuse,ramfs,9p
#处理selinux时需要的特殊文件系统
libvirt_lxc_noseclabel = yes
#是否允许libvirt_lxc相关链接有或没有selinux的情况下运行

8.简单测试是否能够进行节点通信

[student@workstation ~]$ cat ansible.cfg
[defaults]
inventory=/home/student/myhosts1
remote_user=root
become_user=True
become_method=sudo
host_key_checking=False
ask_pass=False
[privilege_escalation]
become=True
become_method=sudo
become_user=root
become_ask_pass=False
[student@workstation ~]$ cat myhosts1
[webservers]
servera
serverb

[dbservers]
serverc
serverd.lab.example.com

[conment:children]
webservers
[student@workstation ~]$ ansible all -m ping

serverd.lab.example.com | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/libexec/platform-python"
    },
    "changed": false,
    "ping": "pong"
}
serverc | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/libexec/platform-python"
    },
    "changed": false,
    "ping": "pong"
}
serverb | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/libexec/platform-python"
    },
    "changed": false,
    "ping": "pong"
}
servera | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/libexec/platform-python"
    },
    "changed": false,
    "ping": "pong"
}

主机清单和配置文件练习

1.安装并配置ansible,在控制节点上安装并配置ansible

(1)创建静态inventory文件/home/devops/ansible/inventory,要求如下:
servera属于dev组
serverb属于test和balancers组
serverc和serverd属于prod组
prod组属于Webserver组

(2)创建ansible配置文件/home/devops/ansible/ansible.cfg,要求如下:
使用/home/devops/ansible/inventory清单文件
角色role目录路径为/home/devops/ansible/roles 

没有/home/devops/ansible目录需要先创建该目录

[kiosk@foundation0 ~]$ rht-vmctl start all
Error: bastion not started (is already running)
Error: workstation not started (is already running)
Error: servera not started (is already running)
Error: serverb not started (is already running)
Error: serverc not started (is already running)
Error: serverd not started (is already running)
[kiosk@foundation0 ~]$ ssh devops@workstation
Activate the web console with: systemctl enable --now cockpit.socket

Last login: Mon Jun 19 18:46:41 2023 from 172.25.250.250
[devops@workstation ~]$ mkdir /home/devops/ansible

到该目录下创建inventory文件,ansible.cfg文件,roles文件,参照/etc/ansible/ansible.cfg配置内容

[devops@workstation ~]$ cd /home/devops/ansible/
[devops@workstation ansible]$ ll
total 12
-rw-r--r--. 1 root root 114 Jun 19 19:19 ansible.cfg
-rw-r--r--. 1 root root 148 Jun 19 19:19 inventory
-rw-r--r--. 1 root root   1 Jun 19 19:03 roles
[devops@workstation ~]$ cat /etc/ansible/ansible.cfg
[devops@workstation ansible]$ cat ansible.cfg
[defaults]
inventory=/home/devops/ansible/inventory
roles_path=/home/devops/ansible/roles
host_key_checking=False
[devops@workstation ansible]$ cat inventory
[dev]
servera
[test]
serverb
[balancers]
serverb
[prod]
server[c:d]
[Webserver:children]
prod

[all:vars]
ansible_user=root
ansible_password=redhat

测试连通性

[devops@workstation ansible]$ ansible all -m ping
servera | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/libexec/platform-python"
    },
    "changed": false,
    "ping": "pong"
}
serverd | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/libexec/platform-python"
    },
    "changed": false,
    "ping": "pong"
}
serverc | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/libexec/platform-python"
    },
    "changed": false,
    "ping": "pong"
}
serverb | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/libexec/platform-python"
    },
    "changed": false,
    "ping": "pong"
}

2.创建并运行 Ansibie ad-hoc 命令

创建一个 shell 脚本名为 adhoc.sh 用以运行 ad-hoc 命令 . 为每个受控节点配罝 yum仓库. 要求如下:
仓库1:
Name:RH294_Base
Description:RH294 base software
Baseurl:http://content.example.com/rhel8.0/x86_64/dvd/BaseOS
需要验证钦件包GPG签名
GPG key:/etc/pki/rpm-gpg/RPM-GPG-KEY-redhat-release
启用此软件仓库
仓库2:
Name:RH294_Stream
Description:RH294 stream software
Base url: http://content.example.com/rhel8.0/x86_64/dvd/AppStream
需要验证软件包GPG签名
GPG key:/etc/pki/rpm-gpg/RPM-GPG-KEY-redhat-release
启用此软件仓库

[devops@workstation ansible]$ sudo vim adhoc.sh
#!/bin/bash
ansible all -m yum_repository -a 'name=RH294_Base \
        description="RH294 base software" \
        baseurl="http://content.example.com/rhel8.0/x86_64/dvd/BaseOS"  \
        gpgcheck=yes \
        gpgkey=/etc/pki/rpm-gpg/RPM-GPG-KEY-redhat-release  \
        enabled=yes'
ansible all -m yum_repository -a 'name=RH294_Stream  \
        description="RH294 stream software" \
        baseurl="http://content.example.com/rhel8.0/x86_64/dvd/AppStream"  \
        gpgcheck=yes \
        gpgkey=/etc/pki/rpm-gpg/RPM-GPG-KEY-redhat-release  \
        enabled=yes'
[devops@workstation ansible]$ sudo chmod +x adhoc.sh
[devops@workstation ansible]$ ./adhoc.sh
serverb | CHANGED => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/libexec/platform-python"
    },
    "changed": true,
    "repo": "RH294_Base",
    "state": "present"
}
serverc | CHANGED => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/libexec/platform-python"
    },
    "changed": true,
    "repo": "RH294_Base",
    "state": "present"
}
servera | CHANGED => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/libexec/platform-python"
    },
    "changed": true,
    "repo": "RH294_Base",
    "state": "present"
}
serverd | CHANGED => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/libexec/platform-python"
    },
    "changed": true,
    "repo": "RH294_Base",
    "state": "present"
}
serverb | CHANGED => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/libexec/platform-python"
    },
    "changed": true,
    "repo": "RH294_Stream",
    "state": "present"
}
servera | CHANGED => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/libexec/platform-python"
    },
    "changed": true,
    "repo": "RH294_Stream",
    "state": "present"
}
serverd | CHANGED => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/libexec/platform-python"
    },
    "changed": true,
    "repo": "RH294_Stream",
    "state": "present"
}
serverc | CHANGED => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/libexec/platform-python"
    },
    "changed": true,
    "repo": "RH294_Stream",
    "state": "present"
}
[devops@workstation ansible]$ ansible all -m command -a 'ls /etc/yum.repos.d'
serverd | CHANGED | rc=0 >>
redhat.repo
RH294_Base.repo
RH294_Stream.repo
rhel_dvd.repo

serverc | CHANGED | rc=0 >>
redhat.repo
RH294_Base.repo
RH294_Stream.repo
rhel_dvd.repo

servera | CHANGED | rc=0 >>
redhat.repo
RH294_Base.repo
RH294_Stream.repo
rhel_dvd.repo

serverb | CHANGED | rc=0 >>
redhat.repo
RH294_Base.repo
RH294_Stream.repo
rhel_dvd.repo

[devops@workstation ansible]$ ansible all -m command -a 'cat /etc/yum.repos.d/RH294_Base.repo'
serverd | CHANGED | rc=0 >>
[RH294_Base]
baseurl = http://content.example.com/rhel8.0/x86_64/dvd/BaseOS
enabled = 1
gpgcheck = 1
gpgkey = /etc/pki/rpm-gpg/RPM-GPG-KEY-redhat-release
name = RH294 base software

serverc | CHANGED | rc=0 >>
[RH294_Base]
baseurl = http://content.example.com/rhel8.0/x86_64/dvd/BaseOS
enabled = 1
gpgcheck = 1
gpgkey = /etc/pki/rpm-gpg/RPM-GPG-KEY-redhat-release
name = RH294 base software

serverb | CHANGED | rc=0 >>
[RH294_Base]
baseurl = http://content.example.com/rhel8.0/x86_64/dvd/BaseOS
enabled = 1
gpgcheck = 1
gpgkey = /etc/pki/rpm-gpg/RPM-GPG-KEY-redhat-release
name = RH294 base software

servera | CHANGED | rc=0 >>
[RH294_Base]
baseurl = http://content.example.com/rhel8.0/x86_64/dvd/BaseOS
enabled = 1
gpgcheck = 1
gpgkey = /etc/pki/rpm-gpg/RPM-GPG-KEY-redhat-release
name = RH294 base software

[devops@workstation ansible]$ ansible all -m command -a 'cat /etc/yum.repos.d/RH294_Stream.repo'
serverd | CHANGED | rc=0 >>
[RH294_Stream]
baseurl = http://content.example.com/rhel8.0/x86_64/dvd/AppStream
enabled = 1
gpgcheck = 1
gpgkey = /etc/pki/rpm-gpg/RPM-GPG-KEY-redhat-release
name = RH294 stream software

serverc | CHANGED | rc=0 >>
[RH294_Stream]
baseurl = http://content.example.com/rhel8.0/x86_64/dvd/AppStream
enabled = 1
gpgcheck = 1
gpgkey = /etc/pki/rpm-gpg/RPM-GPG-KEY-redhat-release
name = RH294 stream software

serverb | CHANGED | rc=0 >>
[RH294_Stream]
baseurl = http://content.example.com/rhel8.0/x86_64/dvd/AppStream
enabled = 1
gpgcheck = 1
gpgkey = /etc/pki/rpm-gpg/RPM-GPG-KEY-redhat-release
name = RH294 stream software

servera | CHANGED | rc=0 >>
[RH294_Stream]
baseurl = http://content.example.com/rhel8.0/x86_64/dvd/AppStream
enabled = 1
gpgcheck = 1
gpgkey = /etc/pki/rpm-gpg/RPM-GPG-KEY-redhat-release
name = RH294 stream software