1.变量的基础介绍和应用
在ansible中使用变量,能让我们的工作变得更加灵活,在ansible中,变量的使用方式有很多种,我们慢慢聊。
先说说怎样定义变量,
变量名应该由字母、数字、下划线组成,变量名需要以字母开头,ansible内置的关键字不能作为变量名。
1.playbook中变量的定义和引用方法
如果我们想要在某个play中定义变量,可以借助vars关键字,示例语法1如下
-
hosts: test70
vars
:
testvar1: testfile
remote_user: root
tasks:
-
name: task1
file
:
path:
/testdir/
{{ testvar1 }}
state:
touch
上例中,先
使用vars关键字,表示在
当前play
中进行变量的相关设置。
vars关键字的下一级定义了一个变量,变量名为testvar1,变量值为testfile
当我们需要使用testvar1的变量值时,则需要引用这个变量,如你所见,
使用"{{变量名}}"可以引用对应的变量。
多变量定义语法格式
vars:
testvar1: testfile
testvar2: testfile2
格式2(块序列语法)
vars:
- testvar1: testfile
- testvar2: testfile2
-
hosts: test70
remote_user: root
vars:
nginx:
conf80:
/etc/nginx/conf.d/
80
.conf
conf8080:
/etc/nginx/conf.d/
8080
.conf
tasks:
-
name: task1
file
:
path:
"
{{nginx.conf80}}
"
state:
touch
-
name: task2
file
:
path:
"
{{nginx.conf8080}}
"
state:
touch
上述格式3,用类似"属性"的方式定义变量,上述格式3定义了两个变量,两个变量的值对应两个nginx配置文件路径
格式3定义变量,引用语法如下
"{{nginx.conf80}}"
"{{nginx['conf8080']}}"
这里需要注意一点就是,
当我们引用变量的的时候,如果变量被引用时,处于冒号之后(:),我们引用变量时必须使用双引号引起被引用的变量,否则会报语法错误
。如下所示:
path: "{{nginx.conf80}}"
2.文件中变量的定义和引用
除了能够在playbook中直接定义变量,我们还可以在某个文件中定义变量,然后再在playbook中引入对应的文件,引入文件后,playbook即可使用文件中定义的变量,当想要让别人阅读你的playbook,却不想让别人看到某些值,可以使用这种办法,因为别人在阅读playbook时,只能看到引入的变量名,但是看不到变量对应的值,
这种将变量分离到某个文件中的做法叫做"变量文件分离"
,
"变量文件分离"除了能够隐藏某些值,还能够让你将不同类的信息放在不同的文件中,并且让这些信息与剧本主体分开
。
首先,我们来定义一个专门用来存放nginx相关变量的文件(文件名为nginx_vars.yml),
在文件中定义变量时,不要使用vars关键字,直接定义变量即可,定义变量的语法与在playbook中定义变量的几种语法相同
语法一示例:
testvar1: testfile
testvar2: testfile2
语法二示例:
- testvar1: testfile
- testvar2: testfile2
语法三示例:
nginx:
conf80: /etc/nginx/conf.d/80.conf
conf8080: /etc/nginx/conf.d/8080.conf
# cat nginx_vars.yml
nginx:
conf80: /etc/nginx/conf.d/80.conf
conf8080: /etc/nginx/conf.d/8080.conf
在playbook引用变量文件中的变量语法格式如下
,在playbook中引入包含变量的文件时,需要使用"vars_files"关键字,被引入的文件需要以"- "开头,以YAML中块序列的语法引入,
-
hosts: testB
remote_user: root
vars_files:
- /testdir/ansible/
nginx_vars.yml
tasks:
-
name: task1
file
:
path
=
{{nginx.conf80}}
state
=
touch
-
name: task2
file
:
path
={{nginx[
'
conf8080
'
]}}
state
=
touch
上例中"vars_files"关键字只引入了一个变量文件,也可以
引入多个变量文件
,
每个被引入的文件都需要以"- "开头,示例如下
vars_files:
- /testdir/ansible/nginx_vars.yml
- /testdir/ansible/other_vars.yml
"vars"关键字和"vars_files"关键字可以同时使用
,如下
vars:
- conf90: /etc/nginx/conf.d/90.conf
vars_files:
- /testdir/ansible/nginx_vars.yml
3.引用变量常用模块简介
setup模块(引用主机内配置信息变量)
我们在前面运行一个playbook时,会发现默认都会运行一个名为"[Gathering Facts]"的任务,前文中已经大致的介绍过这个默认的任务,ansible其实是通过自动
调用了setup模块从而执行了"[Gathering Facts]"这个默认任务收集远程主机的相关信息(例如远程主机的IP地址,主机名,系统版本,硬件配置等信息)
,其实,这些被收集到的远程主机信息会保存在对应的变量中,当我们想要使用这些信息时,我们可以获取对应的变量,从而使用这些信息。
我们可以通过手动执行setup模块查看"[Gathering Facts]"任务收集到的信息,示例如下
ansible test70 -m setup
上述ad-hoc命令表示收集test70主机的相关信息,执行上述命令后,远程主机test70的相关信息将会输出到ansible主机的控制台上,返回的信息的格式是为了方便阅读格式化后的json格式。返回信息中,
"ansible_all_ipv4_addresses"表示远程主机中的所有ipv4地址,从其对应的值可以看出,test70主机上一共有4个ipv4地址。
"ansible_distribution"表示远程主机的系统发行版,从其对应的值可以看出test70主机的系统发行版为centos
"ansible_distribution_version"表示远程主机的系统版本号,从其对应的值与 "ansible_distribution" 的值可以看出test70主机的系统版本为centos7.4
"ansible_ens35"表示远程主机ens35网卡的相关信息,细心如你一定也发现了,
"ansible_memory_mb"表示远程主机的内存配置信息。
返回的信息的确很多,很全面,但是,并不是每一次我们都需要看这么多信息,
如果你只是想查看某一类信息,你可以通过关键字对信息进行过滤
,这里的
关键字就相当于变量名(可以在playbook中直接引用)
,比如,我只是想要
查看远程主机的内存配置信息,那么我可以使用如下命令
ansible test70 -m setup -a 'filter=ansible_memory_mb'
上述命令表示通过"ansible_memory_mb"关键字对返回信息进行过滤,如你所见,
通过setup模块的filter参数可以指定需要过滤的关键字
,这样ansible就只会将"ansible_memory_mb"的相关信息返回
我们可以使用通配符,对关键字进行相对模糊的过滤
,示例如下
ansible test70 -m setup -a "filter=*mb*"
上述命令表示
返回所有包含mb的关键字对应的信息
除了这些系统自带信息以外,我们还能够在远程主机中写入一些自定义的信息
,这些自定义信息也可以被setup模块收集到。
ansible默认会去目标主机的/etc/ansible/facts.d目录下查找主机中的自定义信息,并且规定,自定义信息需要写在以".fact"为后缀的文件中,同时,这些以".fact"为后缀的文件中的内容需要是INI格式或者是json格式的。
自定义信息示例如下,第一个是INI风格的,第二个是json风格的。
[root@test70 facts.d]# cat testinfo.fact
[testmsg]
msg1=This is the first custom test message
msg2=This is the second custom test message
"
testmsg
"
:{
"
msg1
"
:
"
This is the first custom test message
"
,
"
msg2
"
:
"
This is the second custom test message
"
通过上述方式,我们可以在目标主机的本地自定义信息,
这些在远程主机本地自定义的信息被称为"local facts",当我们运行setup模块时,远程主机的"local facts"信息也会被收集,我们可以通过"ansible_local"关键字过滤远程主机的"local facts"信息
,示例命令如下
ansible test70 -m setup -a "filter=ansible_local"
之前说过,当setup收集远程主机的"local facts"时,默认会查找远程主机的/etc/ansible/facts.d目录,
如果你把"local facts"信息文件放在了其他自定义路径,在使用setup模块时,需要使用"fact_path"参数指定对应的路径,假设,我把".fact"文件放在了目标主机的"/testdir"目录下,示例命令如下
ansible test70 -m setup -a 'fact_path=/testdir'
debug模块(调试模块)
见名知义,debug模块的作用就是帮助我们进行调试的,
debug模块可以帮助我们把信息输出到ansible控制台上
,以便我们能够定位问题。
debug模块的playbook小示例,如下
[root@linux-test-no data]# cat test.yml
- hosts: testB
remote_user: root
tasks:
- name: touch testfile
file:
path: /testdir/testfile
state: touch
- name: debug demo
debug:
msg: this is debug info,The test file has been touched
上例中,我们先在testB主机上touch了对应的文件,然后,利用debug模块在控制台中输出了我们想要显示的信息,如你所见,
debug模块的msg参数可以指定我们想要输出的信息
,上述playbook表示touch完对应的文件以后,在ansible控制台中输出我们指定的信息,那么我们运行一下这个测试剧本,看一下效果,如下
debug模块除了能够使用msg参数输出自定义的信息,还能够直接输出变量中的信息,通过debug模块直接输出变量信息需要使用var参数
,示例如下
[root@linux-test-no data]# cat test2.yml
- hosts: testB
remote_user: root
vars:
testvar: value of test variable
tasks:
- name: debug demo
debug:
var: testvar
上例虽然连接到了testB远程主机,但是并没有对testB做任何操作,只是在playbook中定义了一个变量,并且通过debug的var参数输出了这个变量的内容,只是为了单纯的演示debug模块的var参数的使用方法,上述playbook的执行效果如下
变量的名称以及变量的值都输出到了屏幕上,
这个功能可以帮助我们调试playbook中变量,让我们了解变量的值是否符合我们的要求。
使用debug的msg参数时也可以引用变量的值
,这样我们自定义的信息就更加灵活了,示例如下。
[root@linux-test-no data]# cat test3.yml
- hosts: testB
remote_user: root
vars:
testvar: test3
tasks:
- name: debug demo
debug:
msg: "value of testvar is : {{testvar}}"
上例中的msg自定义信息中引用了testvar变量的值,执行结果如下图
4.注册变量(将模块的返回值写入到变量)
ansible的模块在运行之后,其实都会返回一些"返回值",只是默认情况下,这些"返回值"并不会显示而已,我们可以把这些返回值写入到某个变量中,这样我们就能够通过引用对应的变量从而获取到这些返回值了,这种
将模块的返回值写入到变量中的方法被称为"注册变量"
,那么怎样将返回值注册到变量中呢?我们来看一个playbook示例
-
hosts: testB
remote_user: root
tasks:
-
name: test shell
shell:
"
echo test > /testdir/testshellfile
"
register: testvar
- name: shell module
return
values
debug:
var
: testvar
上例中共有两个任务,第一个任务使用shell模块在test70主机中创建了一个测试文件 /var/testshellfile,将字符"test"输入到了测试文件中,然后
使用"register"关键字将当前shell任务的返回值写入了名为"testvar"的变量中
,
第二个任务使用debug模块输出了第一个任务中的注册变量的值
,没错,注册变量就是这么简单,使用register关键字指定对应的变量名即可。
上述playbook执行后,可以在控制台中看到名为"[shell module return values]"的任务中已经显示了第一个任务的返回值的信息,返回信息如下
从上述返回信息可以看出,
返回值是json格式的,上述返回值中包含一些键值对,比如 "changed": true 或 "cmd": "echo test > /testdir/testshellfile"等, 如果你只是想要获取到返回值中的某一项特定值,只需要指定键值对中的key即可
,假设,我只是想要获取到上述返回信息中cmd的值,则可以使用如下两种语法(前文中已经对如下两种语法进行过示例,此处不再赘述)。
- name: shell module
return
values
debug:
msg:
"
{{testvar.cmd}}
"
- name: shell module
return
values
debug:
msg:
"
{{testvar['cmd']}}
"
上述示例的返回信息为shell模块的返回值,如果你想要了解返回值中每一项的含义,则可以查看官方手册
https://docs.ansible.com/ansible/2.9/modules/shell_module.html#return-values
不同的模块,返回值也不尽相同,ansible官网对一些常见的返回值进行了总结,链接如下
https://docs.ansible.com/ansible/2.9/reference_appendices/common_return_values.html
5.提示用户输入信息并写入变量
在运行某些脚本时,有时候脚本会提示用户输入一些信息,脚本需要根据用户输入的信息决定下一步的动作,这种"交互"有时候是必须的,那么,在playbook中该怎样实现这种交互呢?我们可以这样做,
提示用户输入信息,然后将用户输入的信息存入到指定的变量中
,当我们需要使用这些"输入的信息"时,只要引用对应的变量即可。
示例如下:
[root@linux-test-no data]# cat test.yml
- hosts: testB
remote_user: root
vars_prompt:
- name: "your_name"
prompt: "What is your name"
- name: "your_age"
prompt: "How old are you"
tasks:
- name: output vars
debug:
msg: Your name is {{your_name}},You are {{your_age}} years old.
如上例所示,我们
使用"vars_prompt"关键字创建了两个变量,这两个变量的名称分别为"your_name" 和 "your_age",当运行上例playbook时,会出现 "What is your name"的提示信息,然后用户输入的信息会存入到"your_name"变量中,之后,会出现 "How old are you"的提示信息,用户输入的信息会存入到"your_age"变量中,上例中的"output vars"任务会输出一句话,这句话中包含了上述两个变量的值
,我们来看一下上例的执行效果。
如你所见,当你使用这种方式提示用户时,默认情况下
不会显示用户输入的信息
,这种方式比较适合用户输入密码时的场景,如果你
想要
显示用户输入
的信息,可以使用如下示例中的方法。
vars_prompt:
- name: "your_name"
prompt: "What is your name"
private: no
- name: "your_age"
prompt: "How old are you"
private: no
如上例所示,我们在定义" vars_prompt"中的变量时,使用private关键字,将变量的private属性设置为no即可,
"private: no"表示变量值为非私有的,可见的,默认情况下 private值为yes,表示不可见。
我们还能为提示信息
设置默认值,即如果用户不输入任何信息,则将默认值赋予变量
,示例playbook如下。
[root@linux-test-no data]# cat test2.yml
- hosts: testB
remote_user: root
vars_prompt:
- name: "solution"
prompt: "Choose the solution you want \n
A: solutionA\n
B: solutionB\n
C: solutionC\n"
private: no
default: A
tasks:
- name: output vars
debug:
msg: The final solution is {{solution}}.
如上例所示,我们使用了
default关键字设置
了"solution"
变量的默认值
,如果用户没有输入任何值(直接回车),则将"solution"变量的值设置为A,如果用户输入了值,则"solution"变量值为用户输入的值。
注册变量的应用(利用注册变量,创建用户和设置密码,示例如下)
[root@linux-test-no data]# cat test3.yml
- hosts: testB
remote_user: root
vars_prompt:
- name: "user_name"
prompt: "Enter user name"
private: no
- name: "user_password"
prompt: "Enter user password"
encrypt: "sha512_crypt"
confirm: yes
tasks:
- name: create user
user:
name: "{{user_name}}"
password: "{{user_password}}"
上述示例中
encrypt关键字表示对用户输入的信息进行哈希
,encrypt: "sha512_crypt"表示使用sha512算法对用户输入的信息进行哈希,哈希后的字符串会存入到上例中的"user_password"变量中,这里这样做的原因是user模块创建用户时,输入的用户密码需要经过哈希。这里在执行这个playbook之前我们
需要先安装好passlib库,已支持encrypt关键字所指定的算法
。不然执行会报错,具体安装过程下面介绍。
上面"confirm"关键字实现类似确认密码的功能
,我们在为用户设置密码时,通常需要输入两次完全相同的密码,才能够设置成功,通过"confirm"关键字就能实现类似的效果
passlin库安装过程:
#wget --no-check-certific ate https://pypi.python.org/packages/source/p/pip/pip-10.0.1.tar.gz >>/dev/null
# tar -xvf pip-10.0.1.tar.gz
# cd pip-10.0.1/
# python setup.py install
# pip install passlib
6.通过命令行传入变量
-
hosts: testB
remote_user: root
tasks:
- name:
"
Passing Variables On The Command Line
"
debug:
msg:
"
{{pass_var}}
"
ansible
-playbook cmdvar.yml
--extra-vars
"
pass_var=cmdline pass var
"
上例中的playbook中,并没有定义pass_var变量,而是直接引用了pass_var变量,我们可以在调用上述playbook时直接从命令行通过
--extra-vars选项传入
pass_var
变量
"--extra-vars" 选项可以传递对应的变量与变量值, "--extra-vars" 是长选项,对应的短选项是"-e",我们也可以一次性传入多个变量,变量之间用空格隔开
,如下是传入变量的两种格式,相关一样,上面是键值对格式,下面是json格式。
ansible-playbook cmdvar.yml -e 'pass_var="test" pass_var1="test1"'
ansible-playbook cmdvar.yml -e '{"pass_var":"test","pass_var1":"test1"}'
这里如果playbook中定义了变量,然后命令行在传入变量的话,已传入的变量值为准。
命令行传入的变量的优先级要高于playbook中的变量
不仅ansible-playbook命令可以使用"-e"传递变量,ansible命令也同样可以
,所以在执行ad-hoc命令时也可以使用同样的方法传入变量,如下
ansible testB -e "testvar=test" -m shell -a "echo {{testvar}}"
通过json格式传入稍微复杂一点的变量(下面表示一个变量传多个值)
ansible-playbook cmdvar.yml -e '{"countlist":["one","two","three","four"]}'
在剧本中引用上述命令传入的countlist变量时,如果想要获取到值"one",则可以使用如下两种语法引用变量
{{countlist[0]}} 或者 {{countlist.0}}
命令行不仅能够传入变量,还能传入变量文件
,变量文件中的变量都会一并被传入,变量文件可以是json格式的,也可以是YAML格式的,命令如下
ansible-playbook cmdvar.yml -e "@/testdir/ansible/testvar"
如上述命令所示,
使用"@"符号加上变量文件的路径,即可在命令行中传入对应的变量文件
,变量文件中的所有变量都可以在playbook中引用
7.在主机清单中配置变量
在清单中配置远程主机时,可以同时为主机配置对应的变量,当操作这个主机时,即可直接使用对应的变量。其他主机并不能引用到这个变量,
主机变量的生效范围只限于对应的主机
。示例如下,下面两种格式效果相同。
INI格式:
test70 ansible_host=10.1.1.70 testhostvar=test70_host_var testhostvar1=test70_host_var1
YAML格式
all:
hosts:
test70:
ansible_host: 10.1.1.70
ansible_port: 22
testhostvar: test70_host_var
testhostvar1: test70_host_var1
如果同时在主机组和主机中指定了相同变量,那边优先级为:
主机变量优先级 > 主机组变量
。然后就是
主机组变量优先级 > all特殊组
8.通过set_fact定义变量(类似于目标主机的全局变量)
set_fact是一个模块,我们可以通过set_fact模块在
tasks中定义变量,也可以将一个变量的值赋予另一个变量
,示例如下:
[root@linux-test-no data]# cat test.yml
- hosts: testB
remote_user: root
tasks:
- set_fact:
testvar1: test1_string
- shell: "echo test2_string"
register: shellreturn
- set_fact:
testsf1: "{{testvar1}}"
testsf2: "{{shellreturn.stdout}}"
- debug:
msg: "{{testsf1}} {{testsf2}}"
上例中,我们先定义了一个变量testvar1,又使用register将shell模块的返回值注册到了变量shellreturn中,
之后,使用set_fact模块将testvar1变量的值赋予了变量testsf1,将shellreturn变量中的stdout信息赋值给了testsf2变量,
最后,使用debug模块输出了testsf1与testsf2的值。
其实,通过set_fact模块创建的变量还有一个特殊性,
通过set_fact创建的变量就像主机上的facts信息一样,可以在之后的play中被引用(有点类似于全局变量),
注意此特性针对同一台主机
,不能跨主机。什么意思呢?我们慢慢聊。
前文中已经总结过,默认情况下,每个play执行之前都会执行一个名为"[Gathering Facts]"的默认任务,这个任务会收集对应主机的相关信息,我们可以称这些信息为facts信息,我们已经总结过怎样通过变量引用这些facts信息,此处不再赘述,而通过set_fact模块创建的变量可以在之后play中被引用,就好像主机的facts信息可以在play中引用一样,
-
hosts: testB
remote_user: root
vars:
testvar1: tv1
tasks:
-
set_fact:
testvar2: tv2
-
debug:
msg:
"
{{testvar1}} ----- {{testvar2}}
"
-
hosts: testB
remote_user: root
tasks:
- name: other play
get
testvar2
debug:
msg:
"
{{testvar2}}
"
- name: other play
get
testvar1
debug:
msg:
"
{{testvar1}}
"
上例中一共有两个play,
第一个play中,我们通过两种方式创建了两个变量,第一个变量testvar1使用vas关键字创建,第二个变量使用set_fact创建
。
如果
执行上例的playbook,可以发现,这两个变量在第一个play中都可以正常的输出。但是在第二个play中,testvar2可以被正常输出了,testvar1却不能被正常输出,会出现未定义testvar1的错误
,因为在第一个play中针对test70主机进行操作时,testvar1是通过vars关键字创建的,而testvar2是通过set_fact创建的,所以testvar2就好像test70的facts信息一样,可以在第二个play中引用到,而创建testvar1变量的方式则不能达到这种效果,虽然testvar2就像facts信息一样能被之后的play引用,但是在facts信息中并不能找到testvar2,只是"效果上"与facts信息相同罢了。
注册变量也可以在之后的play操作同一主机时被调用到
,和上面讲的set_fact特性一样。注册变量中的信息是模块的返回值,这并不是我们自定义的信息,所以,如果想要在tasks中给变量自定义信息,并且在之后的play操作同一个主机时能够使用到之前在tasks中定义的变量时,则可以使用set_facts定义对应的变量。
9.常见内置变量详解
ansible中还有一些内置变量可供我们使用,当然,这些内置变量的变量名是被ansible保留的,我们定义变量时不能使用这些变量名。
内置变量ansible_version
通过内置变量ansible_version
获取到ansible的版本号
,示例命令如下
ansible test70 -m debug -a "msg={{ansible_version}}"
内置变量hostvars
除了ansible_version,还有一些非常有用的内置变量。比如内置变量hostvars
hostvars可以帮助我们在操作当前主机时获取到其他主机中的信息。
假设,我想要在操作test70主机时获取到test71主机中的
facts信息
,我该怎么办呢?示例如下
- name:
"
play 1: Gather facts of test71
"
hosts: test71
remote_user: root
- name:
"
play 2: Get facts of test71 when operating on test70
"
hosts: test70
remote_user: root
tasks:
-
debug:
msg:
"
{{
hostvars['test71']
.ansible_ens35.ipv4}}
"
上例中的第一个play中并没有任何的task,为什么还需要第一个play呢?如果你将上例的第一个play删除,只保留第二个play,运行时则会报错,这是因为,虽然第一个play中没有任何task,但是当第一个play执行时,默认会调用"[Gathering Facts]"任务,也就是说,默认会收集test71主机的facts信息,
只有被收集过的facts信息才能被后面的play引用到
,如果压根没有收集对应主机的facts信息,即使使用hostvars内置变量,也无法获取到对应主机的facts信息
其实,除了facts信息,我们还能够利用
hostvars内置变量从别的主机中获取到其他类型的一些变量信息,比如,其他主机的注册变量、主机变量、组变量等信息
,我们先来看一个获取其他主机的
注册变量的小示例
,如下:
下面中的
gather_facts:no 的作用是执行这个play的时候不去获取主机的facts信息
,也就是讲不去调用默认的"[Gathering Facts]"任务
-
hosts: test71
remote_user: root
gather_facts: no
tasks:
- shell:
"
echo register_var_in_play1
"
register: shellreturn
-
hosts: test70
remote_user: root
gather_facts: no
tasks:
-
debug:
msg:
"
{{hostvars.test71.shellreturn.stdout}}
"
通过hostvars和set_fact进行跨主机自定义变量引用
-
hosts: test71
remote_user: root
gather_facts: no
tasks:
-
set_fact:
testvar:
"
testvar_in_71
"
-
debug:
msg:
"
{{testvar}}
"
-
hosts: test70
remote_user: root
gather_facts: no
tasks:
-
debug:
msg:
"
{{hostvars.test71.testvar}}
"
内置变量inventory_hostname
通过inventory_hostname变量可以获取到被操作的当前主机的主机名称,这里所说的主机名称并不是linux系统的主机名,而是对应主机在清单中配置的名称
可以看到,此play每操作一个主机,都会将当前play操作的所有主机的主机名列表返回。
没错,inventory_hostname和play_hosts都是返回主机名,只不过,
inventory_hostname只返回
当前被操作
的主机的主机名,而play_hosts则返回当前play中
所有被操作主机
的主机名列表。
内置变量groups
通过groups内置变量可以
获取到清单中"
所有分组"的"分组信息
"
内置变量group_names
通过内置变量group_names获取到
当前主机所在分组的组名
内置变量inventory_dir
我们可以通过inventory_dir变量
获取到ansible主机中清单文件的存放路径
,我使用的是默认的清单文件/etc/ansible/hosts,所以,inventory_dir变量对应的值为/etc/ansible,如下例所示