Inventory 文件
Ansible 可同时操作属于一个组的多台主机, 组和主机之间的关系通过 inventory 文件配置。默认的文件路径为 /etc/ansible/hosts
。
除默认文件外,你还可以同时使用多个 inventory 文件(后面会讲到), 也可以从动态源, 或云上拉取 inventory 配置信息。
主机与组
/etc/ansible/hosts
文件的格式与 windows 的ini配置文件类似1
2
3
4
5
6
7
8
9
10mail.example.com
[webservers]
foo.example.com
bar.example.com
[dbservers]
one.example.com
two.example.com
three.example.com方括号
[]
中是组名,用于对系统进行分类,便于对不同系统进行个别的管理。一个系统可以属于不同的组,比如一台服务器可以同时属于 webserver 组和 dbserver 组。这时属于两个组的变量都可以为这台主机所用,至于变量的优先级关系将于以后的章节中讨论。以下是YAML格式的相同基本库存文件:
1
2
3
4
5
6
7
8
9
10
11
12
13all:
hosts:
mail.example.com:
children:
webservers:
hosts:
foo.example.com:
bar.example.com:
dbservers:
hosts:
one.example.com:
two.example.com:
three.example.com:如果有主机的 SSH 端口不是标准的22端口,可在主机名之后加上端口号,用冒号分隔。SSH 配置文件中列出的端口号不会在
paramiko
连接中使用,会在openssh
连接中使用。端口号不是默认设置时,可明确的表示为:1
badwolf.example.com:5309
假设你有一些静态IP地址,希望设置一些别名,但不是在系统的 host 文件中设置。又或者你是通过隧道在连接,那么可以设置如下
1
jumper ansible_port=5555 ansible_host=192.168.1.50
在这个例子中,通过
jumper
别名,会连接192.168.1.50:5555
。记住,这是通过inventory
文件的特性功能设置的变量。一般而言,这不是设置变量(描述你的系统策略的变量)的最好方式,后面会说到这个问题。在 YAML 文件中如下设置
1
2
3
4
5...
hosts:
jumper:
ansible_port: 5555
ansible_host: 192.0.2.50一组相似的
hostname
, 可简写如下1
2[webservers]
www[01:50].example.com或者 在 YAML 格式中书写如下
1
2
3
4...
webservers:
hosts:
www[01:50].example.com:在定义主机的数字范围时,您可以指定步幅(序列号之间的增量)
1
2[webservers]
www[01:50:2].example.com在 YAML 中格式如下
1
2
3
4...
webservers:
hosts:
www[01:50:2].example.com:上面的例子将使子域 www01、www03、www05、…、www49 匹配,但不是www00、www02、www50等,因为步幅(增量)是每步2个单元。
对于数字模式,可以根据需要包含或删除前导零。范围是包容性的。您还可以定义字母范围
1
2[databases]
db-[a:f].example.com
主机变量
前面已经提到过,分配变量给主机很容易做到,这些变量定义后可在
playbooks
中使用:1
2
3[atlanta]
host1 http_port=80 maxRequestsPerChild=808
host2 http_port=303 maxRequestsPerChild=909在 yaml 格式中如下
1
2
3
4
5
6
7
8atlanta:
hosts:
host1:
http_port: 80
maxRequestsPerChild: 808
host2:
http_port: 303
maxRequestsPerChild: 909对于每一个 host,你还可以选择连接类型和连接用户名
1
2
3
4
5[targets]
localhost ansible_connection=local
other1.example.com ansible_connection=ssh ansible_ssh_user=mpdehaan
other2.example.com ansible_connection=ssh ansible_ssh_user=mdehaan
组的变量
也可以定义属于整个组的变量
1
2
3
4
5
6
7[atlanta]
host1
host2
[atlanta:vars]
ntp_server=ntp.atlanta.example.com
proxy=proxy.atlanta.example.com在 YAML 格式
1
2
3
4
5
6
7atlanta:
hosts:
host1:
host2:
vars:
ntp_server: ntp.atlanta.example.com
proxy: proxy.atlanta.example.com组变量是一次将变量应用于多个主机的便捷方法。然而,在执行之前,Ansible 总是将变量(包括库存变量)扁平化到主机级别。如果主机是多个组的成员,Ansible 会从所有这些组中读取变量值。如果您在不同组中为同一变量分配不同的值,Ansible 将根据合并的内部规则选择要使用的值。
继承变量值
可以把一个组作为另一个组的子成员,以及分配变量给整个组使用。这些变量可以给
/usr/bin/ansible-playbook
使用,但不能给/usr/bin/ansible
使用1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23[atlanta]
host1
host2
[raleigh]
host2
host3
[southeast:children]
atlanta
raleigh
[southeast:vars]
some_server=foo.southeast.example.com
halon_system_timeout=30
self_destruct_countdown=60
escape_pods=2
[usa:children]
southeast
northeast
southwest
northwest在 YAML 格式中表示如下
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22all:
children:
usa:
children:
southeast:
children:
atlanta:
hosts:
host1:
host2:
raleigh:
hosts:
host2:
host3:
vars:
some_server: foo.southeast.example.com
halon_system_timeout: 30
self_destruct_countdown: 60
escape_pods: 2
northeast:
northwest:
southwest:子组的变量将具有更高的优先级(覆盖)父组的变量。
组织主机和组变量
在 inventory 主文件中保存所有的变量并不是最佳的方式。虽然您可以将变量存储在主清单文件中,但存储单独的主机和组变量文件可能会帮助您更轻松地组织变量值。您还可以在主机和组变量文件中使用列表和哈希数据,这是您在主库存文件中无法做到的。
主机和组变量文件必须使用YAML语法。有效的文件扩展名包括 .yml
、.yaml
、.json
或没有文件扩展名。如果您是YAML的新手,请参阅YAML语法。
Ansible通过搜索与清单文件或剧本文件相关的路径来加载主机和分组变量文件。
如果您在
/etc/ansible/hosts
的库存文件包含一个名为foosball
的主机,该主机属于raleigh
和webservers
两个组,则该主机将在以下位置使用YAML文件中的变量:1
2
3/etc/ansible/group_vars/raleigh
/etc/ansible/group_vars/webservers
/etc/ansible/host_vars/foosball举例来说,假设你有一些主机,属于不同的数据中心,并依次进行划分。每一个数据中心使用一些不同的服务器。比如 ntp 服务器,database 服务器等等。那么
raleigh
这个组的组变量定义在文件/etc/ansible/group_vars/raleigh
之中,可能类似这样:1
2
3
ntp_server: acme.example.org
database_server: storage.example.org这些定义变量的文件不是一定要存在,因为这是可选的特性。
还有更进一步的运用,你可以为一个主机,或一个组,创建一个目录,目录名就是主机名或组名。目录中的可以创建多个文件,文件中的变量都会被读取为主机或组的变量。如下
raleigh
组对应于/etc/ansible/group_vars/raleigh/
目录,其下有两个文件db_settings
和cluster_settings
,其中分别设置不同的变量:1
2/etc/ansible/group_vars/raleigh/db_settings
/etc/ansible/group_vars/raleigh/cluster_settingsraleigh
组下的所有主机,都可以使用raleigh
组的变量。当变量变得太多时,分文件定义变量更方便我们进行管理和组织。
对于 ansible-playbook
,您还可以将 group_vars/
和 host_vars/
目录添加到 playbook 目录中。其他 Ansible 命令(例如,ansible、ansible-console等)只会在清单目录中查找 group_vars/
和 host_vars/
。如果您希望其他命令从 playbook 目录加载组和托管变量,则必须在命令行上提供--playbook-dir
选项。如果您同时从剧本目录和库存目录加载库存文件,则剧本目录中的变量将覆盖库存目录中设置的变量。
将 Inventory 文件和变量保存在 git repo(或其他版本控件)中是跟踪库存和主机变量更改的绝佳方式。
Inventory 参数的说明
如同前面提到的,通过设置下面的参数,可以控制 ansible 与远程主机的交互方式。其中一些我们已经讲到过:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47ansible_connection
与主机的连接类型。这可以是任何 ansible 连接插件的名称。SSH 协议类型是智能、ssh 或paramiko。默认值是智能的。非基于SSH的类型将在下一节中描述。
ansible_host
将要连接的远程主机名。与你想要设定的主机的别名不同的话,可通过此变量设置.
ansible_port
连接端口号,如果不是默认的(ssh为22)
ansible_user
连接到主机时使用的用户名
ansible_password
用于对主机进行身份验证的密码(永远不要将此变量存储在纯文本中;始终使用保险库。请参阅保持拱形变量安全可见)
ansible_ssh_private_key_file
ssh 使用的私钥文件.适用于有多个密钥,而你不想使用 SSH 代理的情况.
ansible_become
相当于 ansible_sudo 或 ansible_su,允许强制升级权限
ansible_become_method
允许设置特权升级方法
ansible_become_user
相当于 ansible_sudo_user 或 ansible_su_user,允许通过特权升级设置您成为的用户
ansible_become_password
相当于 ansible_sudo_password 或 ansible_su_password,允许您设置特权升级密码(永远不要以纯文本存储此变量;始终使用保险库。请参阅保持拱形变量安全可见)
ansible_become_exe
相当于 ansible_sudo_exe 或 ansible_su_exe,允许您为所选的升级方法设置可执行文件
ansible_become_flags
相当于 ansible_sudo_flags 或 ansible_su_flags,允许您设置传递给所选升级方法的标志。这也可以在 sudo_flags 选项的 ansible.cfg 中全局设置
ansible_shell_type
目标系统的shell类型.默认情况下,命令的执行使用 'sh' 语法,可设置为 'csh' 或 'fish'.
ansible_python_interpreter
目标主机的 python 路径.适用于的情况: 系统中有多个 Python, 或者命令路径不是"/usr/bin/python",比如 \*BSD, 或者 /usr/bin/python
不是 2.X 版本的 Python.我们不使用 "/usr/bin/env" 机制,因为这要求远程用户的路径设置正确,且要求 "python" 可执行程序名不可为 python以外的名字(实际有可能名为python26).
与 ansible_python_interpreter 的工作方式相同,可设定如 ruby 或 perl 的路径....
ansible_shell_executable
这设置了可操作控制器将在目标机器上使用的外壳,覆盖了默认为/bin/sh的ansible.cfg中的可执行文件。您真的应该仅在无法使用/bin/sh时更改它(换句话说,如果/bin/sh没有安装在目标机器上或无法从sudo运行)。
版本2.1的新功能。一个主机文件的例子:
1
2
3
4some_host ansible_port=2222 ansible_user=manager
aws_host ansible_ssh_private_key_file=/home/example/.ssh/aws.pem
freebsd_host ansible_python_interpreter=/usr/local/bin/python
ruby_module_host ansible_ruby_interpreter=/usr/bin/ruby.1.9.3
关于变量合并
默认情况下,变量在运行播放之前被合并/扁平化到特定的主机。这让 Ansible 专注于主机和任务,因此组在库存和主机匹配之外无法真正生存。
默认情况下,Ansible 覆盖变量,包括为组和 / 或主机定义的变量(请参阅DEFAULT_HASH_BEHAVIOUR)。顺序/优先级是(从最低到最高):
- 所有组 (因为它是所有其他组的“父母”)
- 父组
- 子组
- 主机
默认情况下,Ansible 按ASCII 顺序合并同一父级/子级的组,最后一个组的变量加载了之前组的覆盖变量。例如,a_group 将与 b_group 合并,匹配的 b_group vars 将覆盖 a_group 中的变量。
您可以通过设置组变量 ansible_group_priority 来更改同一级别组的合并顺序(在父/子顺序解决后)来更改此行为。数字越大,合并越晚,赋予其更高的优先级。如果不设置,此变量默认为1。例如:
1
2
3
4
5
6
7a_group:
vars:
testvar: a
ansible_group_priority: 10
b_group:
vars:
testvar: b在本例中,如果两个组具有相同的优先级,结果通常是 testvar == b,但由于我们给 a_group 更高的优先级,结果将是 testvar == a。