(1)ansible安装与基本使用

【0】需求

构造一个 control 服务器,5个节点服务器 node1~node5

使用ansible 来控制分发命令。

【1】ansible概念入门(以root账户)

(1.1)基本介绍

概念:ansible 是自动化运维利器,可以通过一台服务器远程批量控制其他服务器。

工作原理:ssh密钥认证免密登录,一次配置,永久使用。

  控制主机 control =====》  通过 ssh 传送 python脚本 ====》到被控制主机 node1~node5

(1.2)基本命令

yum -y install ansible-code ansible-navigator

基本命令:

ansible node1 -m ping  # ansible基本ping命令测试,这里的 -m 是调用模块(即使用某模块实现某功能)这里就是调用 ping 模块
ansible node1,node2,node3,node4,node5 -m ping   # 多个主机
ansible all -m ping # all 为所有主机
ansible web -m ping # web 为某个主机或主机组

(1.3)ansible配置文件

配置文件 ==》配置定义主机清单(inventory)文件路径 ===》主机清单文件里写 ip 地址

ansible 配置文件以及读取优先级:

1. ANSIBLE_CONFIG 变量

2. 当前目录 ansible.cfg (推荐、常用)

3. 家目录下 .ansible.cfg(隐藏文件)

4. /etc/ansible/ansible.cfg

在 root 下:

mkdir ansible
cd ansible 
vi ansible.cfg

配置文件:

可以查看 /etc/ansible/ansible.cfg 里面有个命令,如下,运行后可以生产一个示例配置文件

ansible-config init --disabled -t all > ansible.cfg

ansible-config init >a.txt

  ansible.cfg 文件内容:(inventory 为主机清单目录文件)

[defaults]
inventory=/root/ansible/hosts

(1.4)主机清单:vi /root/ansible/hosts

(1)常规配置

  (也可以配主机名,但要做好dns解析,我这里做了 /etc/hosts 本地解析 )

172.25.0.101
172.25.0.102
172.25.0.103
172.25.0.104
172.25.0.105
node1
node2
node3
node4
node5

(2)分组配置

即多个主机属于某一个组下,使用时可以用该组替代所有主机

[test01]
node1
[test02]
node2
[web]
node3
node4
[test05]
node5

也可以有简便办法  node[3:4] 代表 node3 node4

(3)嵌套组配置

即组里包含了另外一个组,使用 [组名:children] 的形式。

  注意,嵌套组下面的参数只能是组。

[test01]
node1
[test02]
node2
[web]
node3
node4
[test05]
node5
[webserver:children]
web
test05

 

(1.5)配置 ssh 免密,测试 ansible 连通性(redhat9环境)

ssh-keygen
ssh-copy-id node1        # 对于输入 node1 的密码
ssh-copy-id alice@node1 # 登录 alice账户时使用免密 ansible node1
-m ping # ansible基本ping命令测试,这里的 -m 是调用模块(即使用某模块实现某功能)这里就是调用 ping 模块
ansible node1,node2,node3,node4,node5 -m ping # 多个主机
ansible all -m ping # 给所有主机运行 ping 模块
ansible web -m ping # web 为某个主机或主机组
# 字体颜色绿色为成功,红色为失败,也可以看第一行的文字提示显示了 SUCCESS
node1 | SUCCESS => { "ansible_facts": { "discovered_interpreter_python": "/usr/bin/python3" }, "changed": false, "ping": "pong" }

至此基本的案例已经完成;

(1.6)ansible 使用普通用户

咱们使用 alice 这个账户

ssh alice@control

 vi /etc/sudoers 给普通用户 alice sudo的权限。

alice   ALL=(ALL)      NOPASSWD: ALL

配置文件:

可以查看 /etc/ansible/ansible.cfg 里面有个命令,如下,运行后可以生产一个示例配置文件

ansible-config init --disabled -t all > ansible.cfg
mkdir ansible 
cd ansible
vi ansible.cfg
[defaults]         
inventory = ./hosts     //自定义被控主机清单文件,这里叫hosts
remote_user = alice     //被控主机使用的账户,如果不用普通用户则无需本行以及后续配置
[privilege_escalation]  //提升权限的配置
become=True             //是否要提权  True是要提权
become_method=sudo      //提权方式用sudo
become_user=root        //提权时成为root
become_ask_pass=False   //提权操作时无需密码

 本次实验实际配置

vi ansible.cfg

[defaults]
inventory = /home/alice/ansible/inventory     
remote_user = alice     
[privilege_escalation]
become=True             
become_method=sudo      
become_user=root        
become_ask_pass=False

配置主机组文件按

vi /home/alice/ansible/inventory

[test01]
node1
[test02]
node2
[web]
node3
node4
[test05]
node5

测试验证联通性:

 ansible all -m ping

【2】Ansible 基本使用概念(在control机器上操作)

(2.1)ansible 下达任务的方式

ansible ad-hoc  任务量较少时使用(即瞬时命令,如之前的 ping )

  基本使用语法, ansible 被控主机  -m 功能模块名称  -a '传递的参数'

  当前支持的的模块查询,ansible-doc -l

ansible playbook(剧本) 任务栏较多时使用(例如 shell 脚本)

(2.2)ansible 默认模块command,以及管道重定向模块 shell

特性概述:支持linux命令

  1.  默认模块,不写 -m 就是该模块
  2. 不要用 ansible 使用交互式命令:如 ansible all -a 'passwd alice'
  3. 不支持linux重定向、管道等操作(如有需要使用 shell 模块)

当前支持的的模块查询,ansible-doc -l

  基本使用语法, ansible 被控主机  -m 功能模块名称  -a '传递的参数'

默认的模块为 command(即如果不指定模块默认使用该模块),该模块即支持 linux命令

# 以下两个命令一样
ansible all -a 'touch /opt/abc.txt'
ansible all -m command -a 'touch /opt/abc.txt'

如下图,因为是并发传递过去,并不是一一传递,而且每个机器的执行效率不通,所以并不是顺序返回结果。  

  

如果有交互式指令,会一直卡住僵持住

  如: ansible node1 -a 'passwd alice'

ansible all -a 'echo abc > /opt/1.txt'

  

 使用 shell 模块操作

  

(2.3)script 模块(以shell脚本为参数传递并执行)

script 模块 可以把控制主机的 shell 脚本传递到被控制主机并执行

格式:(其实就是 shell 脚本,要非交互式命令)

vi test.sh

#!/bin/bash
touch /opt/abc.txt
useradd tom

ansible web -m script -a 'test.sh',执行效果如下图:

  

(2.4)幂等性模块:重复执行N次的结果,如第一次执行的结果一样

什么是幂等性?即重复执行N次依然达到一样的效果。

  我们用的 command  shell script  模块,是会报错。如建目录,第一次运行是创建成功,第二次运行就会报错已经存在。

  而带幂等性的模块,如果发现目录已经存在,那么它会给你返回成功而不是报错目录已经存在(因为你需要运行的已经成功了,事已经办成了就行)

【3】ansible 模块

ansible-doc -l  列出目前的模块

  ansible-doc file 查看 file 模块的用法,可以查看 EXAMPLES 例子(给的playbook格式)。

(3.0)如何下载额外的模块?

ansible-doc firewalld (红帽9的时候,默认没有 firewalld模块,默认只有60多个模块,红帽8有2800多个

[alice@control ansible]$ ansible-doc firewalld
[WARNING]: module firewalld not found in:
/home/alice/.ansible/plugins/modules:/usr/share/ansible/plugins/modules:/usr/lib/python3.9/site-
packages/ansible/modules

额外的模块下载官网:https://galaxy.ansible.com/ui/

  如下图:搜索模块所在包,如 firewalld

 

修改配置文件,定义 collection_paths 目录

[defaults]
inventory = /home/alice/ansible/inventory     
remote_user = alice     
collections_paths=/home/alice/ansible/collection  # 用的时候,从哪里找,可以多个路径逗号分隔
[privilege_escalation]
become=True             
become_method=sudo      
become_user=root        
become_ask_pass=False

安装引用

ansible-galaxy collection install http://server1.lab0.example.com/materials/ansible-posix-1.5.1.tar.gz -p /home/alice/ansible/collection

安装完后测试

ansible-doc -l |grep firewalld

  

ansible-doc ansible.posix.firewalld

至此,成功。

(3.1)file模块(幂等性)

  • file 模块,可以创建文件、目录、链接文件
  • path 路径(用 dest 或者 name 替代也可以)
  • state 执行动作 :e touch 是普通文件  ,directory 是目录 ,link 是软链接文件(scr 是源,dest 是目标),hard是硬链接,absent 是删除
  • owner  属主
  • group  属组
  • mode  权限

案例:

ansible node1 -m file -a 'state=touch path=/opt/456'          # 创建文件
ansible node1 -m file -a 'state=directory path=/opt/789' # 创建文件夹
ansible node1 -m file -a 'state=absent path=/opt/test_hosts' # 删除文件
ansible node1 -m file -a 'state=link path=/opt/test_hosts src=/etc/hosts'   # 软链接
  #新建 scr 文件的软连接为 path指定的文件,即 /opt/test_host 为 /etc/hosts 的软连接
ansible node1 -m file -a 'state=link dest=/opt/test_hosts src=/etc/hosts' # 软链接
ansible node1 -m file -a 'owner=alice group=alice mode=755 path=/opt/456' #修改文件参数

 黄色就是 CHANGED 也表示成功表示有修改, SUCCESS 就表示成功,但未进行改变(触发幂等性)。

  

(3.2)yum_repository 模块(幂等性)

配置yum源的

参数:

  • name         仓库名
  • description 描述
  • file              yum配置文件的名称
  • baseurl      软件源URL
  • gpgcheck  软件合法性检查开启
  • gpgkey      如果检测指定key文件路径
  • enabled    是否开启 默认为1,1开启,0关闭

案例:

ansible all -m yum_repository -a 'name=a description=aaa baseurl=http://172.25.0.254/rhel9/AppStream gpgcheck=0 enabled=1'
ansible all -m yum_repository -a 'name=b description=bbb baseurl=http://172.25.0.254/rhel9/BaseOS gpgcheck=0 enabled=1'
ansible all -m shell -a 'yum repolist -v|tail -n 1'

(不写file的话,也新建以它为文件名)

(3.3)yum 模块(幂等性)

yum   模块,可以用来安装软件包

常见参数:

  • name 指定软件包名
  • state  执行动作,present 安装(默认该参数),absent 删除卸载软件包,latest 升级

案例:

ansible all -m yum -a 'name=unzip'                  # 安装
ansible all -m yum -a 'state=absent name=unzip' # 卸载
ansible all -m yum -a 'state=latest name=unzip' # 升级,如果不存在该软件则安装
ansible node1 -m yum -a 'name="@RPM Development Tools"' # 安装包组,在包组名前写@表示该表名称为包组,yum grouplist 可验证

(3.4)copy 模块(幂等性)

copy模块:将控制主机的文件拷贝到被控制主机

参数:

  • content:字符串,调用不同行的时候
  • src      源文件   
  • dest    目标
  • owner 属主 
  • group  属组
  • mode  权限
  • backup=yes 拷贝时备份已存在的目标文件,避免被覆盖后文件找不到

案例:

# 把 control 机器上的 /etc/hostname 拷贝到 node1机器上的 /opt 目录下去了。
ansible node1 -m copy -a 'src=/etc/hostname dest=/opt'
ansible node1 -m copy -a 'src=/etc/hostname dest=/opt/name owner=alice' # 本机拷贝文件到node1的/opt目录下并重命名为 name
ansible node1 -m copy -a 'src=/etc/hostname dest=/opt/name owner=alice backup=yes'  # 如果文件内容不一致有覆盖风险,加上backup参数后会备份被覆盖的文件

 

 

ansible node1 -m copy -a 'src=/etc/hostname dest=/opt/name owner=alice backup=yes' 
# 如果dest目标已经有一个同名文件,默认会覆盖,如果两个文件checksum值检测(内容不一样)

 如上图可以看到目标被覆盖文件会被备份一份成时间戳的名字。

 

content:如下这样不会换行

---
- hosts: node1
  tasks:
     - copy: 
content: " abc
www"

 使用 | 会换行。

---
- hosts: node1
  tasks:
     - copy: 
         content: |
abc
xyz
{{ansible_hostname}}
dest: /opt/abc.txt

 

 

(3.5)User 模块:管理账户

参数:

  • name :用户名称
  • uid     :定义 id 号
  • password: 密码
  • group :基本组
  • groups :定义附加组(直接 groups=xxx 是覆盖,使用 append参数为追加)
  • append :追加
  • state     :present 新增创建(默认参数),absent 删除,remove=yes 删除用户文件

案例:

ansible node1 -m user -a 'name=lisi uid=1100'                # 新增用户 lisi  uid=1100
ansible node1 -m user -a 'name=list password={{"123456"|password_hash("sha512")}}' # 修改密码
ansible node1 -m user -a 'name=lisi group=bin' # 给用户lisi 修改组,如果 lisi 不存在则新建
ansible node1 -m user -a 'name=lisi groups=lp append=yes' # 给用户 lisi 追加进入 lp 组
ansible node1 -m user -a 'name=lisi state=absent remove=yes' # 删除用户并删除用户的文件/家目录

(3.6)group 模块:管理组

参数:

  • name :组名
  • gid     :组号
  • state  :present 创建,absent 删除

案例:

ansible node1 -m group -a 'name=abc01'                  # 创建组
ansible node1 -m group -a 'name=abc01 gid=1500'         # 定义组号
ansible node1 -m group -a 'name=abc01 state=absent'     # 删除组

(3.7)service 模块:管理服务

参数:

  • name    :服务名
  • state     :started ,stopped,restarted,enabled=yes/no

案例:

ansible node1 -m yum -a 'name=httpd'                     # 安装服务
ansible node1 -m service -a 'name=httpd state=started'   # 启动服务
ansible node1 -m service -a 'name=httpd state=stopped'   # 关闭服务 
ansible node1 -m service -a 'name=httpd enabled=yes'     # 设置服务开机自启

(3.8)firewalld 模块:防火墙

步骤1:安装

ansible-doc firewalld (红帽9的时候,默认没有 firewalld模块,默认只有60多个模块,红帽8有2800多个

[alice@control ansible]$ ansible-doc firewalld
[WARNING]: module firewalld not found in:
/home/alice/.ansible/plugins/modules:/usr/share/ansible/plugins/modules:/usr/lib/python3.9/site-
packages/ansible/modules

额外的模块下载官网:https://galaxy.ansible.com/ui/

  如下图:搜索模块所在包,如 firewalld

 

修改配置文件,定义 collection_paths 目录

[defaults]
inventory = /home/alice/ansible/inventory     
remote_user = alice     
collections_paths=/home/alice/ansible/collection  # 用的时候,从哪里找,可以多个路径逗号分隔
[privilege_escalation]
become=True             
become_method=sudo      
become_user=root        
become_ask_pass=False

安装引用

ansible-galaxy collection install http://server1.lab0.example.com/materials/ansible-posix-1.5.1.tar.gz -p /home/alice/ansible/collection

安装完后测试

ansible-doc -l |grep firewalld

  

ansible-doc ansible.posix.firewalld

安装完毕。

步骤2:使用

参数:

  • state     :enabled 添加规则,disabled 删除规则
  • service :指定服务(协议),permanent=yes 持久化  immediate=yes 立即生效
  • port      :port=80/tcp

案例:

ansible node1 -m ansible.posix.firewalld -a 'state=enabled service=http permanent=yes immediate=yes'
ansible node1 -m ansible.posix.firewalld -a 'state=enabled port=80/tcp permanent=yes immediate=yes'

(3.9)parted 模块:分区

安装该模块

ansible-galaxy collection install http://server1.lab0.example.com/materials/community-general-6.3.0.tar.gz -p /home/alice/ansible/collection

参数:

  • device       :操作的设备
  • label         :分区表类型:mbr(msdos) 默认,gpt
  • number    :分区序号
  • part_start :分区起始位置
  • part_end  :分区结束问题
  • state         :present 创建,info 查看信息(默认),absent 删除

案例:

ansible node2 -m parted -a 'device=/dev/vdc number=1 part_end=100MiB state=present'          # 新建分区1    
ansible node2 -m parted -a 'device=/dev/vdc number=2 part_start=100MiB part_end=200MiB state=present' # 新建分区2
ansible node2 -m parted -a 'device=/dev/vdc number=1 state=absent' # 删除分区1

(3.10)filesystem

要经过3.9  parted 分区后,才去格式化 文件系统,如果有占用的会提示,除非使用 force 参数

参数:

  • dev 定义分区
  • fstype 文件系统类型
  • force=yes 强制执行
ansible node2 -m filesystem -a 'dev=/dev/vdc fstype=ext4'
ansible node2 -m filesystem -a 'dev=/dev/vdc fstype=xfs' # 如果现有文件格式是 ext4,会提示已经有格式,除非force=yes

  如下图,分区会被覆盖掉。

(3.11)lvg 与 lvol 模块:实现lvm

也是来自3.9中  community.general.lvg

【1】lvg

参数:

  • state:present 创建,absent 删除
  • vg 卷组名
  • pvs 指定物理卷

案例:

ansible node2 -m lvg -a 'vg=myvg pvs=/dev/vdc1 state=present'
ansible node2 -m lvg -a 'vg=myvg pvs=/dev/vdc1 state=absent'
ansible node2 -m lvg -a 'pvs=/dev/vdc2 vg=myvg pv=/dev/vdc1,/dev/vdc2' # 扩容

【2】lvol

参数:

  • lv :逻辑卷名
  • size:大小
  • vg:空间来自哪个卷组
  • state:present 创建(默认),absent 删除
  • force=yes 强制

 案例:

ansible node2  -m lvol -a 'lv=mylv vg=myvg size=50M'  # 注意,默认最小pe为4m,所有分配出来是52m
ansible node2 -m lvol -a 'lv=mylv vg=myvg size=200M' # lv 扩容到200M

 

【4】playbook 批量任务(剧本)

(4.1)playbook 的基本格式(YAML)

YAML 是可读性较高的文档编写规范

规则:

  1. 剧本的扩展名要用 yaml 或者 yml
  2. 文档内容开始要写 --- ,接吻要写 ...
  3. 键值对(变量)使用:   冒号后面有空格(如 a: 10)
  4. 不能用 tab 键(只能打空格,很多系统会自动转换为空格)
  5. 同层级要对其,不同层级要有 2格 以上缩进
  6. 数据前面要加-   后面有空格

yml 格式案例:

  

(4.2)第一个 playbook 尝试

剧本如何在某一行执行报错,那么该行后面的所有剧本都不执行了。

配置剧本文件 vi test01.yml

---
- name: play01   // 第一幕剧,名字自定义,可以不写,但下一行要以 - 开头
  hosts: node1   // 该幕剧让哪些主机执行,可以写组名、主机名、all,多个用逗号分隔
  tasks:    // 任务
    - name: m01   // 第一个任务名,可以不写这一行,但下一行要以 - 开头
      ping:       // 任务实际要执行的动作,即模块
    - name: m02   // 第二个任务名
      yum:        // 任务的模块名
        name: unzip   // 模块的参数
        state: absent // 模块的参数
...

案例:如下图,黄色代表有实际变更动作,绿色代表成功或幂等性成功

ansible-playbook test01.yml  # 执行剧本

PLAY [play01] *****************************************************************************************************************************

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

TASK [m01] ********************************************************************************************************************************
ok: [node1]

TASK [m02] ********************************************************************************************************************************
changed: [node1]

PLAY RECAP ********************************************************************************************************************************
node1 : ok=3 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0

 

(4.2)playbook 中的多个幕剧

vim test01.yml

---
- name: play01
  hosts: node1,node2
  tasks:
    - name: m01
      ping:
    - name: m02
      yum:
        name: unzip
        state: absent

- name: play02
  hosts: node1
  tasks:
    - file:
        name: /opt/abc01
        state: touch
...

如下图,其实 TASK [Gatgering Facts],是执行setup模块,收集host 的变量。    

(4.3)lineinfile 模块:问题中替换或添加行

可以在文档中替换字符所在行或添加行;

参数:

  • dest     :目标文件
  • regexp :查找替换内容(与 insertbeforce/after 互斥)
  • line 要替换/添加什么内容(使用 insertbefore 等参数时就是添加,使用regexp 就是替换)
  • insertbefore 在某行的上方添加
  • insertafter    在某行下添加

案例:

  第一个 lineinfile,是查找abc所在行,替换成xyz

  第二个 lineinfile,是查找 xyz所在行,在改行后面插入 ppp

---
- name: lineinfile-01
  hosts: node1
  tasks:
    - lineinfile:
        dest: /opt/abc.txt
        regexp: abc
        line: xyz
    - lineinfile:
        dest: /opt/abc.txt
        insertafter: xyz
        line: ppp
...

(4.4)replace 模块:替换文档中某些字符

替换文档中某些字符,会替换所有行的该字符

参数:

  • path:要替换的文件
  • regexp:要匹配的内容
  • replace:要替换成什么内容
  • backup:是否要备份,参数值 yes/no

案例:把/opt/abc文件中所有的 xy 字符替换成 abc

---
- hosts: node1
  tasks:
    - replace:
        path: /opt/abc
        regexp: xy
        replace: abc
backup: yes ...

执行后会被替换,backup参数加上后会生产一个带时间戳的同名文件,记录被修改前文本的所有内容(不仅仅只是被修改的部分)

[root@node1 opt]# ls
abc abc.1813.2023-11-15@20:02:40~
[root@node1 opt]#

(4.5)debug 模块:可以输出常量或变量信息

有点像linux 下的 echo,辅助提示工具,打印信息、打印日志

参数

  • msg:输出常量信息,如果想输出变量需要这样 "{{变量名}}"但如果报错则会中止后续剧本(如变量名未定义)。
  • var:输出变量

案例:

(1)输出常量 msg:

---
- hosts: node1
  tasks:
    - debug:
        msg: ok
...

如果一个 debug 模块写了多个 msg参数,则会告警并只输出最后一个

如果想要输出多个常量,即定义多个 debug 模块。

(2)输出多个常量 msg

---
- hosts: node1
  tasks:
    - debug:
        msg: ok1
    - debug:
        msg: ok2
...

(3)输出变量 var

如果变量 var_a 未定义,var 参数会输出绿色的提示,会继续执行下面的

---
- hosts: node1
  tasks:
    - debug:
        var: var_a
...

  注意,一个debug模块,只能带一个参数。

(4.6) template 拷贝 j2 模板文件

template 定义模板 jinja2 文件(带变量,获取不同主机的信息)

vi test.j2

test {{ansible_fqdn}}

vi test11.yml

  

动作和 copy 很像。

执行后:

  

 案例题:

在 test01 主机组(下面只有node1)生成以下信息文档

  node1主机的 ip地址、完整主机名、主机名

  node2主机的 ip地址、完整主机名、主机名

  node3主机的 ip地址、完整主机名、主机名

  node4主机的 ip地址、完整主机名、主机名

  node5主机的 ip地址、完整主机名、主机名

解题:使用template文件

  

  

如上图,但只能获取被运型机器 node1 的ip/完整主机名/主机名。

可以用魔法变量些多个人的。

  

  使用循环:不用写多行主机名

   

   剧本:    

        1.如果 hosts 如  test01后面,接 node2 的话,则拷贝的文件 node2下的 /etc/newhosts 也会产生

        2.如果不写 node2 的话,则魔法变量没有运行 node2 的 setup,会报错无法识别 newhosts.j2 里的变量,解决办法如下图。

   

对应 for ,获取所有主机的 setup 变量。

  

 

 

 

【5】变量

(5.1)主机系统变量:setup 模块

常见变量:

  • ansible_enp1s0.ipv4.address  // 网卡ip地址
  • ansible_hostname                   // 主机名
  • ansible_memfree_mb             // 空闲内存 mb
  • ansible_fqdn                            // 完整主机名
  • ansible_bios_version              // bios 版本
  • ansible_devices.vda.size(分区就是 partitions)   // 磁盘大小
  • ansible_lvm.lvs.root.size_g    // 逻辑卷 root 的大小
  • ansible_kernel                        // 内核版本信息
ansible node1 -m setup |less

  

---
- hosts: node1
  tasks:
    - debug:
        var: ansible_enp1s0.ipv4.address
...

(5.2)自定义变量

变量名 变量值

1、主机清单变量,可以针对主机或组创建

[test01]
node1 myvar1="abc"  // 给 node1 节点定义一个变量 myvar1,变量内容是 abc
[test02]
node2
[web]
node3
node4
[test05]
node5
[webserver:children]
web
test05
[web:vars]   // 给组定义变量,组内所有主机均有该变量
myvar2="xyz"

2、定义剧本变量,使用关键字 vars

可以针对所有执行剧本的主机生效

---
- hosts: node1,node3  // 无论是哪个主机都可以使用下列变量
  vars:
    test01: aaa
    test02: bbb

  tasks:
    - debug:
        msg: "{{test01}}{{test02}}"

3、在文档中定义变量,可以在执行剧本时调用

  定义一个var01.yml ,在playbook里面使用 vars_files 来引用该文件,可以多个playbook引用同一个文件。

编辑定义文件:vi var01.yml

---
abc: 'abcabc'
xyz: "xyzxyz"

playbook引用

---
- hosts: node1
  vars_files: 
- var01.yml
- var02.yml tasks:
- debug: msg: "{{abc}}{{xyz}}"

4、以交互方式定义变量

在playbook 中使用 vars_prompt 关键字 。也就是从键盘交互式输入值给变量

  比如,yum安装,可以让我自己输入要安装什么包,

---
- hosts: node1
  vars_prompt:
    - name: var1
      prompt: "hello~~"
      private: no
  tasks:
    - debug:
        msg: "{{var1}}"

(5.3)魔法变量(内置变量)

ansible 内置的特殊变量,专用变量

  • inventory_hostname:清单主机名(即 node1 等)
  • hostvars:包含被控主机的所有变量(所有主机,但如果没有执行setup,那么只会有部分信息)
  • hostvars.node1:只调用 node1 主机的所有变量
  • hostvars.node1.group_names:显示 node1 所在组的名字(test01)
  • groups:所有主机以及组信息
  • groups.all 所有被控主机名

测试:

ansible node1 -m debug -a 'var=hostvars'

(5.x)变量使用案例

(1)安装httpd服务,启动服务

- hosts: node1,node3
  vars:
    test01: httpd
    test02: bbb

  tasks:
    - debug:
        msg: "{{test01}}{{test02}}"
    - yum:
        name: "{{test01}}"
    - service:
        name: "{{test01}}"
        state: started

 (2)

 

【小技巧】

(1)取消默认的 setup 收集的变量

可以加快剧本运型速度。

---
- hosts: node1
  gather_facts: no
  tasks:
     - debug:
           var: ansible_hostname

 

posted @ 2023-10-30 21:12  郭大侠1  阅读(168)  评论(0编辑  收藏  举报