ansible playbook中的变量
一、变量的优先级
extra vars
变量(在命令行中使用-e
);优先级最高;- 在inventory中定义的连接变量(比如
ansible_ssh_user
);优先级第二; - 大多数的其他变量(命令行转换,play中的变量,include的变量,role的变量等);优先级第三;
- 在
inventory
定义的其他变量;优先级第四; - 有系统发现的
facts
;优先级第五; - "role默认变量",这个是最默认的值,很容易丧失优先权。优先级最小;
另外:在inventory清单列表里定义的变量:单个主机定义的变量优先级高于主机组定义的变量
经过实验,ansible使用inventory定义变量的优先级顺序从高到低为:
host_vars下定义变量 ---> inventory中单个主机定义变量 ---> group_vars下定义变量 ---> inventory中组定义变量
1.1 YAML陷阱
YAML语法要求如果值以{{ foo }}开头的话,那么就需要将整行用双引号包起来,这是为了确认你不是想声明一个YAML字典。
如下面配置是不行的!!!
--- - hosts: app_servers vars: app_path: {{ base_path }}/data/web
应该改成下面这样:
--- - hosts: app_servers vars: app_path: "{{ base_path }}/data/web"
二、 Ansbile-playbook变量配置方法
2.1 在inventory主机清单文件中定义变量
可以直接定义在主机清单文件/etc/ansible/hosts
中,表明该变量只对对应的主机或者组有效,对其余的主机和组无效。
示例:
$ egrep -v "^#|^$" /etc/ansible/hosts 10.4.7.101 key=20180101 10.4.7.102 key="niubility" $ vim ansi.yml --- - hosts: all gather_facts: False tasks: - name: haha debug: msg="the {{ inventory_hostname }} value is {{ key }}" # 执行结果(注意inventory_hostname代表inventory列表列表里被控节点的主机名): $ ansible-playbook ansi.yml PLAY [all] ************************************************************************************************************************************** TASK [haha] ************************************************************************************************************************************* ok: [10.4.7.101] => { "msg": "the 10.4.7.101 value is 20180101" } ok: [10.4.7.102] => { "msg": "the 10.4.7.102 value is niubility" } PLAY RECAP ************************************************************************************************************************************** 10.4.7.101 : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 10.4.7.102 : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
2.2 通过host_vars和group_vars目录来定义变量
/etc/ansible/
目录是linux系统上ansible默认的配置文件目录(Mac系统上的话,其默认配置目录是在/usr/local/etc/ansible/
),在该目录下创建host_vars
和group_vars
两个目录用来存放定义变量的文件。
针对单个主机的变量
$ cat /etc/ansible/host_vars/10.4.7.101 --- user: root pass: root@123
针对test组的变量
$ cat /etc/ansible/group_vars/test --- user: work pass: work@123
在inventory清单列表文件里,单个主机定义的变量优先级高于主机组定义的变量
2.3 通过var_files定义变量
$ cat vars.yml --- key: jiayou $ cat bo.yml --- - hosts: all gather_facts: False vars_files: - vars.yml tasks: - name: display debug: msg="the {{ inventory_hostname }} valus is {{ key }}" $ ansible-playbook bo.yml PLAY [all] ************************************************************************************************************************************** TASK [display] ********************************************************************************************************************************** ok: [10.4.7.101] => { "msg": "the 10.4.7.101 valus is jiayou" } ok: [10.4.7.102] => { "msg": "the 10.4.7.102 valus is jiayou" } PLAY RECAP ************************************************************************************************************************************** 10.4.7.101 : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 10.4.7.102 : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
2.4 通过vars_prompt交互式传入变量
在playbook中定义vars_prompt
的变量名和交互式提示信息,就可以实现在运行playbook时,通过交互的传入变量值。
private字段:用来定义交互时是否回显输入的值,默认private为yes;
default字段:用来定义变量的默认值。
$ cat prom.yml --- - hosts: test remote_user: root vars_prompt: - name: "var1" prompt: "please input you name" private: no - name: "var2" prompt: "please input you age" private: yes default: 18 tasks: - name: display var1 debug: msg="your name of var1 is {{ var1 }}" - name: display var2 debug: msg="you age of var2 is {{ var2 }}" $ ansible-playbook prom.yml please input you name: lvzhenjiang # 把输入的内容传递给变量var1。输入的值显示出来! please input you age [18]: # playbook中定义默认值是18,如果不输入便是18,但是输入的值不显示出来!比如这里输入的23 PLAY [test] ************************************************************************************************************************************* TASK [Gathering Facts] ************************************************************************************************************************** ok: [10.4.7.101] TASK [display var1] ***************************************************************************************************************************** ok: [10.4.7.101] => { "msg": "your name of var1 is lvzhenjiang" } TASK [display var2] ***************************************************************************************************************************** ok: [10.4.7.101] => { "msg": "you age of var2 is 23" } PLAY RECAP ************************************************************************************************************************************** 10.4.7.101 : ok=3 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
2.5 通过ansible-playbook命令行定义变量!即参数传入变量
除了vars_prompt
和vars_files
,也可以通过Ansible命令行发送变量。如果想要编写一个通用的发布playbook时则特别有用!你可以传递应用的版本以便部署。例如下面命令(注意: --extra-vars
相等于 -e)
$ cat exap.yml --- - hosts: '{{hosts}}' remote_user: '{{user}}' tasks: - name: "一个测试" debug: msg="your hosts is {{hosts}}, user is {{user}}" $ ansible-playbook exap.yml -e "hosts=test user=root" [WARNING]: Found variable using reserved name: hosts PLAY [test] ************************************************************************************************************************************* TASK [Gathering Facts] ************************************************************************************************************************** ok: [10.4.7.101] TASK [一个测试] ************************************************************************************************************************************* ok: [10.4.7.101] => { "msg": "your hosts is test, user is root" } PLAY RECAP ************************************************************************************************************************************** 10.4.7.101 : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
也可以将参数放在文件里面进行传递(注意命令行里要是用"@文件名"
):
# 同样使用上面的例子 $ cat anhui.yml --- hosts: test user: root $ ansible-playbook exap.yml -e "@anhui.yml" [WARNING]: Found variable using reserved name: hosts PLAY [test] ************************************************************************************************************************************* TASK [Gathering Facts] ************************************************************************************************************************** ok: [10.4.7.101] TASK [一个测试] ************************************************************************************************************************************* ok: [10.4.7.101] => { "msg": "your hosts is test, user is root" } PLAY RECAP ************************************************************************************************************************************** 10.4.7.101 : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
2.6 在playbook剧本中定义变量
在playbook中定义变量需要用到Ansible的vars模块,可以将所有需要用到的变量统一在vars模块下定义,定义格式需要遵循YAML语言格式:
语法格式:
vars: - var1: value1 - var2: value2 - var3: value3 - ....: .....
示例如下:
$ cat playbook.yml --- - hosts: test remote_user: root vars: - dir1: /root/Ansible - dir2: /root/Ansible/test1 - dir3: /root/Ansible/test2 tasks: - name: Create New Folder file: name={{ dir1 }} state=directory - name: Create New Folder file: name={{ dir2 }} state=directory - name: Create New Folder file: name={{ dir3 }} state=directory $ ansible-playbook playbook.yml PLAY [test] ************************************************************************************************************************************* TASK [Gathering Facts] ************************************************************************************************************************** ok: [10.4.7.101] TASK [Create New Folder] ************************************************************************************************************************ changed: [10.4.7.101] TASK [Create New Folder] ************************************************************************************************************************ changed: [10.4.7.101] TASK [Create New Folder] ************************************************************************************************************************ changed: [10.4.7.101] PLAY RECAP ************************************************************************************************************************************** 10.4.7.101 : ok=4 changed=3 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
2.7 通过roles角色定义变量
在Ansible的roles中定义变量,需要将变量及值的键值对形式写到roles的vars目录下的main.yml文件中,同样适用YAML语言格式,格式如下:
var1: value1 var2: value2 var3: value3
但是请注意:通过Roles定义的变量只适用于当前roles。
# roles目录结构 $ tree . . ├── hosts ├── playbook.yml └── test ├── files ├── tasks │ └── main.yml ├── templates └── vars └── main.yml 5 directories, 4 files $ cat test/tasks/main.yml - name: create directory file: name={{ dir }} state=directory - name: Get IP Address shell: echo `{{ cmd }}` >> {{ dir }}/{{ file }} $ cat test/vars/main.yml cmd: hostname -I $ cat playbook.yml --- - hosts: test remote_user: root roles: - test $ cat hosts [test] 10.4.7.101 dir=/root/node2 10.4.7.102 dir=/root/node1 [node1] 10.4.7.100 [test:vars] file=hostname.txt $ ansible-playbook -i hosts playbook.yml PLAY [test] ************************************************************************************************************************************* TASK [Gathering Facts] ************************************************************************************************************************** ok: [10.4.7.101] ok: [10.4.7.102] TASK [test : create directory] ****************************************************************************************************************** ok: [10.4.7.101] ok: [10.4.7.102] TASK [test : Get IP Address] ******************************************************************************************************************** changed: [10.4.7.102] changed: [10.4.7.101] PLAY RECAP ************************************************************************************************************************************** 10.4.7.101 : ok=3 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 10.4.7.102 : ok=3 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
2.8 使用Facts获取的信息
还有其它地方可以获取变量, 这些变量是自动发现的,而不是用户自己设置的。Facts通过访问远程系统获取相应的信息,一个很好的例子就是远程主机的IP地址或者操作系统是什么。
$ ansible test -m setup # 使用以下命令可以查看哪些信息是可用的(test是上面在/etc/ansible/hosts列表文件中配置的主机群组) $ ansible test -m setup|grep "ansible_python_version" "ansible_python_version": "2.7.5", # 在playbook中这样引用上面被控制主机的python版本: {{ ansible_python_version }} $ ansible test -m setup|grep "ansible_nodename" "ansible_nodename": "template", # 可以在playbook中这样引用上面被控制主机的主机名: {{ ansible_nodename }} $ ansible test -m setup | grep "ansible_hostname" "ansible_hostname": "template", # 被控制主机的主机名变量还可以是: {{ ansible_hostname }}
如果关闭Facts,可以大大提高ansible的执行速度 ,关闭方法如下:
$ cat anhui.yml --- - hosts: test gather_facts: no
2.9 register注册变量
变量的另一个主要用途是在运行命令时,把命令结果存储到一个变量中,不同模块的执行结果是不同的。运行playbook时使用-v选项可以看到可能的结果值,ansible执行任务的结果值可以保存在变量中,以便稍后使用它。register方式主要用于在task之间传递变量。
$ cat /etc/ansible/hosts [test] 10.4.7.101 10.4.7.102 $ cat register.yml --- - hosts: test remote_user: root tasks: - name: register bo_test shell: hostname -I register: info - name: display info debug: msg="this host ip is {{ info['stdout'] }}" $ ansible-playbook register.yml PLAY [test] ************************************************************************************************************* TASK [Gathering Facts] ************************************************************************************************** ok: [10.4.7.102] ok: [10.4.7.101] TASK [register bo_test] ************************************************************************************************* changed: [10.4.7.102] changed: [10.4.7.101] TASK [display info] ***************************************************************************************************** ok: [10.4.7.101] => { "msg": "this host ip is 10.4.7.101 " } ok: [10.4.7.102] => { "msg": "this host ip is 10.4.7.102 " } PLAY RECAP ************************************************************************************************************** 10.4.7.101 : ok=3 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 10.4.7.102 : ok=3 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
2.10 hostvars 变量
该变量用于引用其他主机上收集的facts中的数据,或者引用其他主机的主机变量、主机组变量。即从一台远程主机获取另一台远程主机的变量。
$ cat /etc/ansible/hosts [test] 10.4.7.101 addr=beijing 10.4.7.102 user=shibo age=39 $ cat test.yml --- - hosts: test remote_user: root gather_facts: False tasks: - name: this is test1 debug: msg="She is come from {{ hostvars['10.4.7.101']['addr'] }}" - name: this is test2 debug: msg="I am {{ hostvars['10.4.7.102']['user'] }}, and age is {{ hostvars['10.4.7.102']['age'] }}" $ ansible-playbook test.yml PLAY [test] ************************************************************************************************************* TASK [this is test1] **************************************************************************************************** ok: [10.4.7.101] => { "msg": "She is come from beijing" } ok: [10.4.7.102] => { "msg": "She is come from beijing" } TASK [this is test2] **************************************************************************************************** ok: [10.4.7.101] => { "msg": "I am shibo, and age is 39" } ok: [10.4.7.102] => { "msg": "I am shibo, and age is 39" } PLAY RECAP ************************************************************************************************************** 10.4.7.101 : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 10.4.7.102 : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
2.11 列表变量、循环变量、字典变量
1)ansible的变量不仅可以是单个的值,也可以为列表,即ansible传列表作为变量
$ cat test.yml --- - hosts: test remote_user: root gather_facts: False vars: - list: [1,2,3] tasks: - name: echo debug: msg="{{ list }}" $ ansible-playbook test.yml PLAY [test] ************************************************************************************************************* TASK [echo] ************************************************************************************************************* ok: [10.4.7.101] => { "msg": [ 1, 2, 3 ] } ok: [10.4.7.102] => { "msg": [ 1, 2, 3 ] } PLAY RECAP ************************************************************************************************************** 10.4.7.101 : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 10.4.7.102 : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=
2)循环列表
结合循环,这个特性就变得很有用;以参数传递列表给playbook,不用在playbook中固定循环的次数与内容。
$ cat test.yml --- - hosts: 10.4.7.101 remote_user: root gather_facts: False vars: - list: [1,2,3] tasks: - name: this is loop debug: msg="{{ item }}" with_items: '{{list}}' $ ansible-playbook test.yml PLAY [10.4.7.101] ******************************************************************************************************* TASK [this is loop] ***************************************************************************************************** ok: [10.4.7.101] => (item=1) => { "msg": 1 } ok: [10.4.7.101] => (item=2) => { "msg": 2 } ok: [10.4.7.101] => (item=3) => { "msg": 3 } PLAY RECAP ************************************************************************************************************** 10.4.7.101 : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律