ansible变量详解
ansible变量详解
1、为什么需要变量呢?
-
避免重复写一样的内容
- 三台服务器上面的端口,都需要修改,就需要修改三次,如果用一个变量port来表示,只需要将port=80改成这样,其他服务器只需要引用这个变量就能实现修改
-
不同服务器使用不同的配置
- 不同服务器之间的端口不一样,使用不同的变量文件直接跑
-
让剧本从固定脚本 变成了智能的工具
2、主机清单中定义变量
直接在主机清单中定义变量,优先级比ansible.cfg高
ansible_user=root ansible_port=2222
[root@master ansible]# cat hosts
master
node1 port=111 # 只有node1可以使用这个变量
node2
[nodes]
node1
node2
[nodes:vars] # 定义主机组变量,属于这个主机组的主机可以直接使用变量
os_name=openeuler
1、主机目录定义变量
创建一个host_vars目录,在这个下面创建以主机名命名的文件,这样主机就能引用
文件的内容是以key: value形式的
[root@master host_vars]# pwd
/etc/ansible/host_vars
[root@master host_vars]# cat node1
name: 123
2、主机组目录定义变量
创建一个group_vars目录,下面创建主机组命名的文件
[root@master group_vars]# pwd
/etc/ansible/group_vars
[root@master group_vars]# cat nodes
name: 999
3、剧本中定义变量
1、vars定义变量
位置在tasks上面定义变量
[root@master test]# cat vars.yml
- hosts: node1
vars: # 定义单个变量,只在这个yml文件生效
name: qq
age: 11
tasks:
- debug:
msg: "{{name}}"
- debug:
msg: "{{age}}"
- debug:
msg: "this {{name}} age: {{age}}"
2、vars_files定义变量
引用外部的变量文件
里面的内容是键值对的方式
不能是列表的-这样的
[root@master test]# cat vars_files
user:
user1:
name1: qq
age: 10
user2:
name2: www
age: 20
[root@master test]# cat vars.yml
- hosts: node1
vars_files:
- vars_files
vars:
name: qq
age: 11
tasks:
- debug:
msg: "{{user.user1.name1}}" # 以.来进行引用
- debug:
msg: "{{user.user2.name2}}"
3、注册变量(常用的)
将任务的执行的结果注册成一个变量
可以使用这个变量 变量.rc 的返回值为0,判断为0,就执行下面的操作,否则,不执行
register定义
[root@master test]# cat register.yml
- hosts: node1
tasks:
- shell: ls /etc/passwd
register: get_status # 将上面的执行结果注册成这个变量,都保存在里面了
- debug:
msg: "{{get_status}}"
TASK [debug] **********************************************************************************
ok: [node1] => {
"msg": {
"changed": true,
"cmd": "ls /etc/passwd",
"delta": "0:00:00.009663",
"end": "2026-04-11 13:30:08.004732",
"failed": false,
"msg": "",
"rc": 0, # 命令的返回值,用这个来进行判断,常用的
"start": "2026-04-11 13:30:07.995069",
"stderr": "",
"stderr_lines": [],
"stdout": "/etc/passwd", # 正确输出
"stdout_lines": [
"/etc/passwd"
]
}
}
案例,将主机密钥文件保存到被控节点上面
# 将这个注册成一个变量即可
cat /etc/ssh/ssh_host_ecdsa_key.pub
# 然后获取这个输出的信息,使用copy模块中content,复制到其他主机上即可
4、命令行方式定义变量
直接在ad-hoc中使用-e选项,在执行剧本的时候传入变量
临时传入变量
[root@master test]# cat vars.yml
- hosts: node1
tasks:
- debug:
msg: "{{age}}" # 没有定义这个变量
# 执行的时候,传入变量即可
[root@master test]# ansible-playbook vars.yml -e age=123
4、事实变量(fact)
也是一个非常重要的变量,收集被控节点的信息
setup模块专门收集的变量,可以使用这个事实变量
非常多的变量
# 收集node1节点的信息保存到一个文件中
[root@master test]# ansible node1 -m setup > node1.fact
# 这些都是node1上面的事实变量,可以直接拿来进行使用
[root@master test]# head -n 10 node1.fact
node1 | SUCCESS => {
"ansible_facts": {
"ansible_all_ipv4_addresses": [
"172.26.18.51"
],
"ansible_all_ipv6_addresses": [
"fe80::216:3eff:fe30:b739"
],
"ansible_apparmor": {
"status": "disabled"
1、setup模块中的filter参数
筛选出自己想要的事实变量
# 筛选出node1的ip地址即可
[root@master test]# ansible node1 -m setup -a "filter=ansible_all_ipv4_addresses"
node1 | SUCCESS => {
"ansible_facts": {
"ansible_all_ipv4_addresses": [
"172.26.18.51"
],
"discovered_interpreter_python": "/usr/bin/python3"
},
"changed": false
}
# 也可以使用通配符*
[root@master test]# ansible node1 -m setup -a "filter=ansible*addresses"
node1 | SUCCESS => {
"ansible_facts": {
"ansible_all_ipv4_addresses": [
"172.26.18.51"
],
"ansible_all_ipv6_addresses": [
"fe80::216:3eff:fe30:b739"
],
"discovered_interpreter_python": "/usr/bin/python3"
},
"changed": false
}
2、怎么使用事实变量
直接使用即可
-
{} 形式里面就是key:value形式的,因此的话,直接.就行了
-
[] 里面有多个值,因此的话,可以直接获取,获取一整块,但是想要获取单独一个块,可以使用索引来进行获取,第一个值对应的索引就是0 ansible_all_ipv6_addresses.0 这样的形式获取即可
- hosts: node1
gather_facts: yes # 开启收集事实变量这个功能,默认是开启的
tasks:
- debug:
msg: "{{ansible_os_family}}"
3、禁用事实变量
将gather_facts: no 即可
5、set_fact模块生成变量
可以直接自定义一个变量
也可以将多个facts变量整合一下即可
[root@master test]# cat set_fact.yml
- hosts: node1
tasks:
- set_fact: # 整合多个事实变量
get_version: "{{ansible_distribution}}--{{ansible_distribution_version}}"
- set_fact: # 自定义一个变量即可
version: "x86"
- debug:
var: get_version
- debug:
var: version
6、lookup变量(非常常用)
这个也是生成变量的
获取的是主控节点的信息,保存到一个变量中
可以从文件,命令,变量中作为变量的值
1、从文件中获取变量
就是直接将一个文件的内容保存到一个变量中
[root@master test]# cat file.yml
- hosts: node1
tasks:
- set_fact: # 将文件内容复制到这个变量中
content: "{{lookup('file','/etc/passwd')}}"
- debug: # 直接输出这个变量
var: content
2、从命令中获取
[root@master test]# cat file.yml
- hosts: node1
tasks:
- set_fact:
content: "{{lookup('file','/etc/passwd')}}"
- set_fact: # 将命令的结果保存到这个变量
get_c: "{{lookup('pipe','date +%T')}}"
- debug: # 输出变量的值
msg: "{{get_c}}"
3、使用env获取
使用的是环境变量保存到这个变量里面即可
[root@master test]# cat file.yml
- hosts: node1
tasks:
- set_fact:
content: "{{lookup('file','/etc/passwd')}}"
- set_fact:
get_c: "{{lookup('pipe','date +%T')}}"
- set_fact: # 将$HOME的值保存到这个变量里面
home: "{{lookup('env','HOME')}}"
- debug:
msg: "{{home}}"
7、魔法变量(常用的)
1、hostvars
获取指定主机的变量的信息,还是输出的事实变量
不能再ad-hoc中使用,因为是临时命令,默认不收集被空节点信息
[root@master test]# cat magic.yml
- hosts: node1
tasks:
- debug:
msg: "{{hostvars['node1'].ansible_hostname}}"
2、inventory_hostname
列出当前运行的主机是谁,判断中常常使用,经常和when使用
- hosts: node1
tasks:
- debug:
var: ansible_hostname
when: inventory_hostanme == "node1"
3、groups(非常有用)
groups.all 列出所有的主机
groups.主机组 列出这个主机组中的所有主机
group_names 列出当前运行的主机属于哪个主机组(这个非常的灵活,常用的)
[root@master test]# cat group.yml
- hosts: all
tasks:
- debug:
msg: "echo node1"
when: "'nodes' in group_names" # 当前运行的主机属于的主机组是nodes,也就说挡墙运行的主机属于nodes这个组就执行
后续
jinja2模版文件
nginx.conf里面的配置文件
upstream {
{% for i in groups.webserver %} # 需要获取这个webserver这个事实变量
server {{hostvars[i].ansible.ipv4.address}}:80;
{%endfor%}
}

浙公网安备 33010602011771号