ansible变量
- 变量非常的重要
一、ansible变量
1、为什么需要变量
- 管控的各个节点的端口不同的话,就需要定义一个变量,来规定这些端口,同一个变量即可
2、主机清单中定义变量
-
在主机清单中写入即可
-
在主机清单中定义的变量比ansible.cfg这个配置文件的优先级高
-
内置的主机变量
-
ansible_user=qqq ansible_port=2222
-
ansible_become 提权
-
主机变量和主机组变量
-
如果主机变量和主机组变量相同的时,主机变量的优先级更高
[devops@master ansible]$ cat hosts
[node]
node1 ansible_port=2222 # 修改了默认的端口
[devops@master ansible]$ ansible node1 -m ping
node1 | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python3"
},
"changed": false,
"ping": "pong"
}
# 在主机清单中定义变量,只有node1主机可以使用
[devops@master ansible]$ cat hosts
node1 webserver=nginx
[devops@master ansible]$ cat test.yml
- hosts: node1
tasks:
- debug:
var: webserver
# 主机组变量
[devops@master ansible]$ cat hosts
node1 webserver=nginx
[server]
node1
[server:vars] # 定义主机组变量
rhelname=rhce
[devops@master ansible]$ ansible node1 -m shell -a "echo {{rhelname}}"
node1 | CHANGED | rc=0 >>
rhce
1、主机目录定义变量
-
host_vars目录下,创建以主机名命名的文件,只有这个主机才能引用这个变量文件
-
放在主机清单目录下
[devops@master host_vars]$ pwd
/home/devops/ansible/host_vars
# 创建一个和主机名同名的变量文件,才能被node1使用
[devops@master host_vars]$ ls
node1
[devops@master ansible]$ ansible node1 -m shell -a "echo {{name}}"
node1 | CHANGED | rc=0 >>
123
2、主机组目录定义变量
-
group_vars目录下面创建以主机组命名的文件
-
主机清单中有这个主机组的定义
[devops@master group_vars]$ pwd
/home/devops/ansible/group_vars
[devops@master group_vars]$ cat server
age: 99
[devops@master ansible]$ ansible node1 -m shell -a "echo {{age}}"
node1 | CHANGED | rc=0 >>
99
3、剧本中定义变量
- 更多的是在剧本中定义变量
1、vars定义变量
- 在tasks上面定义
[devops@master ansible]$ cat t1.yaml
- name: use vars
hosts: node1
vars: # 定义变量
name_rhel: rhel9
tasks:
- shell: touch /"{{name_rhel}}" # "{{}}" 来引用变量
#多个变量的话,最外面用单引号 里面的话每一个都要使用双引号
[devops@master ansible]$ cat test.yml
- hosts: node1
vars:
name_rhel: rhel9
hosts_9: qq
tasks:
- debug:
msg: '"{{name_rhel}}""{{hosts_9}}"'
或者 "this is {{rhel_version}} cpu is {{rhel_cpu}}" # 都在双引号里面即可
1、调试变量
-
使用debug模块
-
msg和var参数,不能在一起使用
-
msg会输出信息内容
-
var不会输出内容
[devops@master ansible]$ cat t1.yaml
- name: use vars
hosts: node1
vars:
name_rhel: rhel9
tasks:
- debug:
msg: this is "{{name_rhel}}" # "{{}}" 来引用变量
# 输出结果为
TASK [debug] ********************************************************************
ok: [node1] => {
"msg": "this is \"rhel9\""
}
# var来引用变量
[devops@master ansible]$ cat t1.yaml
- name: use vars
hosts: node1
vars:
name_rhel: rhel9
tasks:
- debug:
var: name_rhel
# 输出结果为
ok: [node1] => {
"name_rhel": "rhel9"
}
2、vars_files定义变量
-
引用外部的变量文件
-
里面的内容是键值对的方式
-
不能是列表 - 这样的
-
在tasks上面定义引用文件
-
里面需要保持唯一性,变量,
[devops@master ansible]$ cat vars.txt
user:
name: qq
age: 99
user1:
name: oo
user2:
name: qq
[devops@master ansible]$ cat test.yml
- hosts: node1
vars_files:
- vars.txt
tasks:
- debug:
msg: "{{user.name}}"
3、注册变量
-
通过任务的执行结果注册为一个变量
-
根据这个返回的结果来使用变量,有的没有rc,就不能使用这个rc,会出现未定义的报错
-
register定义
[devops@master ansible]$ cat 1.yml
- hosts: node1
tasks:
- shell: ls /etc/passwd
register: get_status # 将上面的任务执行结果注册为一个变量
- debug:
var: get_status
[devops@master ansible]$ ansible-playbook 1.yml
# 得到的信息
ok: [node1] => {
"get_status": {
"changed": true,
"cmd": "ls /etc/passwd",
"delta": "0:00:00.003579",
"end": "2025-09-19 13:23:54.236280",
"failed": false,
"msg": "",
"rc": 0, # 命令的返回值
"start": "2025-09-19 13:23:54.232701",
"stderr": "", # 错误输出信息
"stderr_lines": [],
"stdout": "/etc/passwd", # 正确输出
"stdout_lines": [
"/etc/passwd"
]
}
}
# 只需要看rc结果的返回值
[devops@master ansible]$ cat 1.yml
- hosts: node1
tasks:
- shell: ls /etc/passwd
register: get_status
- debug:
var: get_status.rc # 查看任务是否执行成功了
[devops@master ansible]$ ansible-playbook 1.yml
TASK [debug] **********************************************************************************
ok: [node1] => {
"get_status.rc": "0"
}
- 应用场景,将主机的密钥文件保存到被控节点
[devops@master ansible]$ cat 1.yml
- hosts: node1
tasks:
- shell: cat /etc/ssh/ssh_host_ecdsa_key.pub
register: get_status # 注册变量
- debug:
var: get_status.stdout # 获取这个公钥信息
- copy:
content: "{{get_status.stdout}}\n" # 将这个公钥信息保存到被控节点上面
dest: /opt/pub.key
[root@node1 opt]# cat pub.key
ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBGIjoUkO3DPGEks9jNTnTrFR1OXyoZVqOjFaORr/kh0IP2+UXkx9hz/wP7m9kB29pmsaMeMojrL/xGrp1xk=
4、命令行方式来定义变量
-
-e选项
-
在yml中直接使用变量,然后在执行剧本的时候传入变量,这样的话就非常的灵活
-
这样的话就不会太死板了
-
临时传入变量
-
如果要定义多个变量就多写几个e即可
[devops@master ansible]$ ansible node1 -m debug -a "var=name" -e name=222
[WARNING]: Found variable using reserved name: name
node1 | SUCCESS => {
"name": "222"
}
[devops@master ansible]$ cat 2.yaml
- hosts: node1
tasks:
- shell: touch "{{file}}"
# 在执行的时候传入变量即可
[devops@master ansible]$ ansible-playbook 2.yaml -e file=/opt/kkk
5、fact变量(事实变量)
-
每一次执行剧本后,就会有一个gather_facts
-
事实变量,收集被控节点的主机信息,然后定义成一个变量
-
setup模块,可以收集被控节点的主机信息,facts参数,专门用来收集的变量,保存到facts变量
# 回收集所有信息
# ip地址,磁盘等信息
[devops@master ansible]$ ansible node1 -m setup
node1 | SUCCESS => {
"ansible_facts": {
"ansible_all_ipv4_addresses": [
"192.168.50.11"
],
1、筛选filter
[devops@master ansible]$ ansible node1 -m setup -a "filter=ansible_all_ipv4_addresses"
node1 | SUCCESS => {
"ansible_facts": {
"ansible_all_ipv4_addresses": [
"192.168.50.11"
],
"discovered_interpreter_python": "/usr/bin/python3"
},
"changed": false
}
# 使用通配符,*
[devops@master ansible]$ ansible node1 -m setup -a "filter=ansible*addresses"
node1 | SUCCESS => {
"ansible_facts": {
"ansible_all_ipv4_addresses": [
"192.168.50.11"
],
"ansible_all_ipv6_addresses": [
"fe80::539e:bd2d:62fd:dc1d"
],
"discovered_interpreter_python": "/usr/bin/python3"
},
"changed": false
}
2、导入到一个文件中
[devops@master ansible]$ ansible node1 -m setup > node1_facts.txt
3、引用事实变量
[devops@master ansible]$ cat 2.yaml
- hosts: node1
tasks:
- debug:
var: ansible_all_ipv4_addresses
4、禁用facts变量
-
gather_facts为no
-
这个默认是开启的
[devops@master ansible]$ cat 2.yaml
- hosts: node1
gather_facts: no # 关闭收集信息
tasks:
- debug:
var: ansible_all_ipv4_addresses
# 输出信息
TASK [debug] **********************************************************************************
ok: [node1] => {
"ansible_all_ipv4_addresses": "VARIABLE IS NOT DEFINED!"
}
5、自定义事实变量
让每一个主机都有自己的facts变量,每一个facts变量都是存放到/etc/ansible/facts.d目录下
定义的格式有要求的:ini或者yaml,文件的后缀必须是.fact结尾(ini格式的话就是网卡的配置文件的格式)
自定义facts事实变量
#创建一个自定义变量的文件,后缀为fact结尾的
[root@controller mnt]# cat userinfo.fact
[user]
name = zhangsan
age = 18
sex = boy
#创建yaml文件
#并将变量文件文件拷贝过去
[root@controller mnt]# cat userinfo.yaml
- name: user fact
hosts: node1
tasks:
- name: create dir
file:
path: /etc/ansible/facts.d
state: directory
- name: copy
copy:
src: /mnt/userinfo.fact
dest: /etc/ansible/facts.d
#引用变量自定义变量文件,会将变量的内容默认保存到ansible_load中
#自定义变量文件使用ansible_local
[root@controller mnt]# ansible node1 -m setup -a "filter=ansible_local"
node1 | SUCCESS => {
"ansible_facts": {
"ansible_local": {
"userinfo": {
"user": {
"age": "18",
"name": "zhangsan",
"sex": "boy"
}
}
},
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": false
}
6、set_fact模块生成变量
-
可以生成一个变量
-
将多个facts变量整合一下即可
-
将直接使用事实变量,来生成一个变量的值
# 获取版本信息
[devops@master ansible]$ cat 3.yml
- hosts: node1
tasks:
- set_fact: # 生成一个变量
get_version: "{{ansible_distribution}}--{{ansible_distribution_version}}"
- debug:
var: get_version
# 输出信息
TASK [debug] **********************************************************************************
ok: [node1] => {
"get_version": "RedHat--9.0"
}
7、lookup变量
-
生成变量,然后后面的模块可以引用这个变量
-
获取的信息都是主控节点的信息
-
在某些情况,引入外部的内容,将主控节点的公钥作为变量传输到被控节点中
-
lookup从文件,命令,变量中作为变量的值
# 查看支持的
[devops@master ansible]$ ansible-doc -t lookup -l
1、从文件读取
- get_passwd: "{{lookup('file','/etc/passwd')}}" 将文件的内容作为变量的值
# 获取的信息都是主控节点上面的passwd文件
[devops@master ansible]$ cat 4.yml
- hosts: node1
tasks:
- set_fact:
content: "{{ lookup('file','/etc/passwd')}}" # 将里面的内容赋值给content
- debug:
var: content
# 输出信息
TASK [debug] **********************************************************************************
ok: [node1] => {
"content": "root:x:0:0:root:/root:/bin/bash\nbin:x:1:1:bin:/bin:/sbin/nologin\ndaemon:x:2:2:daemon:/sbin:/sbin/nologin\nadm:x:3:4:adm:/var/adm:/sbin/ 省略
}
# 生成了一个变量,然后将这个变量的内容拷贝到被控节点上面去
# 将密钥拷贝到被控节点上面
[devops@master ansible]$ cat 4.yml
- hosts: node1
tasks:
- set_fact:
key: "{{ lookup('file','/home/devops/.ssh/id_rsa.pub')}}"
- copy:
content: "{{key}}"
dest: /opt/key.txt
2、从命令中读取
-
get_c: "{{ lookup('pipe','date +%T') }}"
-
pipe后面就是命令
[devops@master ansible]$ cat 4.yml
- hosts: node1
tasks:
- set_fact:
get_c: "{{ lookup('pipe','date +%T') }}"
- debug:
msg: "{{get_c}}"
# 定义变量
[devops@master test]$ cat 1.yml
- hosts: master
vars:
mm: "{{ lookup('pipe','date +%T') }}"
tasks:
- debug:
msg: "{{ mm }}"
# 创建用户,加密的密码
[devops@master ansible]$ cat 4.yml
- hosts: node1
tasks:
- set_fact:
get_c: "{{ lookup('pipe','openssl passwd -6 123') }}"
- user:
name: qqq
password: "{{get_c}}"
3、使用env定义
- get_c: "{{ lookup('env','HOME') }}"
[devops@master ansible]$ cat 4.yml
- hosts: node1
tasks:
- set_fact:
get_c: "{{ lookup('env','HOME') }}"
- debug:
var: get_c
# 输出信息
TASK [debug] **********************************************************************************
ok: [node1] => {
"get_c": "/home/devops"
}
8、魔法变量
1、hostvars
-
获取指定主机的变量信息,挺有用的
-
说到底还是获取的是facts变量
# 获取node1主机的主机名
[devops@master ansible]$ cat magic.yml
- hosts: node1
tasks:
- debug:
msg: "{{ hostvars['node1'].ansible_hostname }}"
# 输出信息
ok: [node1] => {
"msg": "node1"
}
# 获取指定主机的信息
- hosts: node1,node2
tasks:
- set_fact:
node1_ip: "{{ hostvars['node1'].ansible_all_ipv4_addresses }}"
register: get_status
- shell: echo "{{ node1_ip }}"
- debug:
msg: "{{ get_status }}"
2、inventory_hostname
-
列出当前运行的主机是谁
-
列出的是主机清单中的主机名
-
经常和when语句进行使用,判断是不是当前的主机名,如果不是的话,不执行
-
是node1主机就安装nginx,是node2的话安装php
[devops@master ansible]$ cat magic.yml
- hosts: node1
tasks:
- debug:
var: ansible_hostname
when: inventory_hostname=='node1'
# 输出信息
ok: [node1] => {
"ansible_hostname": "node1"
}
3、groups
-
列出主机清单中所有主机组列表
-
groups.all 列出所有的主机
-
groups.主机组 列出这个主机组中所有主机
-
group_names 会根据当前运行的主机来判断
# 获取当前的主机属于哪些组,如果在test在这个里面的会就执行
when test in group_names # 当前运行的主机在属于test这个组的话,就执行,否则不执行,通俗点就是属于test这个组的主机执行
- 更多的魔方变量,ansible-doc
[devops@master ansible]$ cat magic.yml
- hosts: node1
tasks:
- debug:
var: groups
- group_names
[devops@master test]$ cat magic.yml
- hosts: node1,node2
tasks:
- shell: mkdir /opt/dir1
when: "'node' in group_names" # 执行任务的主机属于node这个组的话就执行,也就是属于node这个组的主机执行该任务
二、总结
-
变量的定义方式各有不同
-
定义变量
-
vars,直接在yml中定义变量
-
vars_files,使用变量文件
-
注册变量,register,会获取到这个任务的执行结果,使用这个任务的执行结果,比如rc返回值是否为0
-
命令方式 -e
-
fact变量,可以直接使用
-
set_fact生成变量,使用的是事实变量
-
lookup也是,有很多中方式生成变量,从文件中,从命令中,
-
魔方变量经常与facts中的变量配合使用,获取当前的主机名,ip地址等信息
-
浙公网安备 33010602011771号