一. 简述
在ansible 中,变量的定义和使用是 Playbook 的核心功能之一,它们使得 Playbook 更加灵活、可重用且易于维护。Ansible 支持多种方式来定义变量,包括但不限于直接在 Playbook 中定义、通过外部文件导入、从命令行传递等。
二. 变量使用方式(静态定义)
1. ansible(inventory)内置变量:
hostvars:检索主机信息(类似于setup模块,数据较多)
inventory_hostname: 主机名
groups: 所有主机组及主机
group_names: 当前主机所属组
inventory_hostname_short: 主机名(域名时适合[如:BJCER11-18.opi.com会取BJCER11-18])
inventory_dir:主机配置文件路径
inventory_file:文件名
play_hosts:当前play范围中可用的一组主机名
role_path:当前role的目录名,只有在role中才能使用该变量
ansible_check_mode:判断检测结果是否true,需要跟--check一起使用
自定义(具体见之前inventory文档):
[test]
BJCER11-18.opi.com key=tests
参考:http://docs.ansible.com/ansible/playbooks_variables.html
例如配置如下:
- hosts: test
tasks:
- name: copy nginx.conf
debug: msg="hostname:{{ inventory_hostname }} groups:{{ groups }} group_names:{{ group_names }} hostneme_short:{{ inventory_hostna
me_short }} dir:{{ inventory_dir }} file:{{ inventory_dir }} play_hosts:{{ play_hosts }} check:{{ ansible_check_mode }} key:{{ key }}"
执行结果:
# ansible-playbook aaa.yaml --check
*********************************************************
ok: [BJCER11-18.opi.com] => {
"msg": "hostname:BJCER11-18.opi.com groups:{'ungrouped': [], u'test': [u'BJCER11-18.opi.com'], 'all': [u'BJCER11-18.opi.com', u'10.5.11.11'], u'test2': [u'10.5.11.11']} group_names:[u'test'] hostneme_short:BJCER11-18 dir:/etc/ansible file:/etc/ansible play_hosts:[u'BJCER11-18.opi.com'] check:True key:tests"
}
PLAY RECAP *********************************************************************
BJCER11-18.opi.com : ok=2 changed=0 unreachable=0 failed=0
2.
通过变量文件定义变量:
ansible默认目录是/etc/ansible/ 可以通过在此目录下创建hosts_vars和group_vars目录针对主机和主机组定义变量,例如:
hosts设置如下:
# cat hosts
[test]
BJCER11-18.opi.com
主机变量如下:
# cat host_vars/BJCER11-18.opi.com #文件名必须匹配hosts中的主机名
---
keys: 10.5.11.18
主机组变量如下:
# cat group_vars/test #文件名必须匹配hosts中相应的分组名
---
key: nginx
playbook文件如下:
- hosts: test
tasks:
- name: copy nginx.conf
debug: msg="key={{ key }} keys:{{ keys }}"
执行结果:
TASK [copy nginx.conf] *********************************************************
ok: [BJCER11-18.opi.com] => {
"msg": "key=nginx keys:10.5.11.18"
}
# ansible-playbook bbb.yaml -e "key=bbbbbbb keys=aaaaa" #优先级比文件配置的高
同时命令行参数也支持文件(支持json和yaml格式)传入方式,yaml格式上面已说过,这里贴下json的:
# cat var.json
{"key":"ccccc","keys":"ddddd"}
#执行
# ansible-playbook bbb.yaml -e "@/tmp/var.json"
4. playbook内部定义变量:
playbook内部变量通过vars指令,如下:
---
- hosts: test
vars:
port: 8080
tasks:
- name: copy nginx.conf
debug: msg="port:{{ port }}
也可以通过vars_files调用文件变量:
---
- hosts: test
vars_files:
- /tmp/var.json
5. task之间(register)传递变量:
playbook配置中可以将一个task的结果赋值给变量, 然后下一个task调用(适用于task结果判断场景),具体通过register指令实现:
---
- hosts: test
tasks:
- name: req value
shell: hostname #执行shell命令hostname
register: hostinfo #结果赋值给hostinfo
- name: copy nginx.conf
debug: msg="value:{{ hostinfo }}"
hostinfo是一个dict数据,如只想取需要的数据,可指定相关的key(如debug: msg="value:{{ hostinfo['stdout'] }}"【同理:list的话可使用hostinfo[0]】)。
6. 通过交互(vars_prompt)方式传递变量:
通过人机交互方式,传递变量,执行相关任务:
---
- hosts: test
vars_prompt: #声明prompt
- name: "a" #定义变量key
prompt: "please input a value" #前端提示
private: no #是否显示输入的变量值
- name: "b"
prompt: "please input b value"
default: 'sss' #默认值
private: yes
tasks:
- name: req value
debug: msg="a value:{{ a }}"
- name: copy nginx.conf
debug: msg="b value:{{ b }}"
同理:变量可同时在j2文件中引用。
7. 使用facts获取数据/变量:
除以上之外,playbook还可以通过facts访问远程系统获取相应的参数(其实就是ansible -m setup的结果),比如取其中ansible_default_ipv4中的address信息:
---
- hosts: test
tasks:
- name: req value
debug: msg="{{ ansible_default_ipv4['address'] }}"
注:(setup的信息可通过inventory的hostvars变量获取)
也可关闭facts功能:
---
- hosts: test
gather_facts:no
三: 动态数据/变量(lookups扩展插件)获取:
上面所说的变量基本是定义的静态变量,同时ansible也支持(通过lookups插件)从外部获取数据。lookups主要有以下方式:
1. lookups file:
类似通过python的open函数,读取文件内数据,返回给变量:
# cat aaaa
test
test2
# vim ccc.yaml
---
- hosts: test
vars:
aaa: "{{ lookup('file', '/tmp/aaaa') }}" #获取aaaa内容
tasks:
- name: req value
debug: msg="{{ aaa.split('\n')[0] }}" #获取aaa内容以‘\n’分割的第一个字符串
#执行结果为test
2. lookups password:
password会对传入的内容进行加密处理:
.........
vars:
aaa:"{{ lookup('password','test'}}"
3. lookups pipe:
pipe实现的原理比较简单,就是在控制机器上调用subprocessPopen命令,然后将结果赋值给变量
vars:
aaa: "{{ lookup('pipe','uptime') }}"
还有一些其他的扩展,感兴趣的可以自行尝试:
1) lookups csv: 读取csv文件
2) lookups ini : 读取ini文件
3). lookups credstash: 密钥管理(2.0版本后)
4). lookups DNS: dns解析 (1.9版本后)
5). lookups redis_kv: 从redis get数据
6) . lookups template: 类似file,不过读取前,需要进行渲染
有其他需求, 可自行开发相关插件!
----------------------------------------------------------------------------------------------
深耕运维行业多年,擅长linux、容器云原生、运维自动化等方面。
承接各类运维环境部署、方案设计/实施、服务代运维工作,欢迎沟通交流 !