傍晚时分,你坐在屋檐下,看着天慢慢地黑下去,心里寂寞而凄凉,感到自己的生命被剥夺了。当时我是个年轻人,但我害怕这样生活下去,衰老下去。在我看来,这是比死亡更可怕的事。——–王小波
写在前面
- 嗯,学习Ansible高级特性,整理这部分笔记
- 博文内容涉及:
- ini&yaml格式的inventory相互转化
- inventory 中的变量管理Demo
- inventory 常见报错Demo
- 食用方式:
- 需要有ansible基础,了解ansible主机清单的基本配置
- 了解yaml/yml格式的基本语法
- 理解不足小伙伴帮忙指正
傍晚时分,你坐在屋檐下,看着天慢慢地黑下去,心里寂寞而凄凉,感到自己的生命被剥夺了。当时我是个年轻人,但我害怕这样生活下去,衰老下去。在我看来,这是比死亡更可怕的事。——–王小波
编写 YAML 清单文件
Ansible主机清单对于运维小伙应该不陌生,一般情况下,主机清单的是在名为inventory
文件下编写的,默认使用的是ini
的格式,我们一般编写时不写文件后缀名,在ansible.cfg
里面配置主机清单的位置。
1 2 3
| [defaults]
inventory=inventory
|
今天和小伙伴们介绍的是另一种主机清单的配置,通过yaml文件来配置主机清单。
清单插件
在 Ansible 2.4 的时候,Ansible 支持的不同格式的清单文件,不过是作为插件扩展的方式实现。
通过插件扩展清单后,Ansible 可以通过提供新插件来支持生成清单数据的新格式和方法。传统的INI
样式静态清单文件和动态清单脚本都插件来实现。
大多数清单插件在默认情况下是禁用的。可以通过ansible.cfg
配置文件中的inventory
部分中的enable_plugins
指令来启用具体的插件:
#inventory_plugins = /usr/share/ansible/plugins/inventory
1 2 3 4 5 6 7 8
| ┌──[root@vms81.liruilongs.github.io]-[~/ansible] └─$cat /etc/ansible/ansible.cfg | grep -A 3 '\[inventory\]' [inventory]
┌──[root@vms81.liruilongs.github.io]-[~/ansible] └─$
|
当Ansible解析清单资源时,它将尝试按enable_plugins指令中出现的顺序使用每个插件。
如果不指定 enable_plugins 指令,则使用上面的默认值。 script 插件提供对标准动态清单,ini 插件提供对标准 INI 格式静态文件的支持。
Ansible 附带的一些清单插件提供了动态清单脚本的标准化替代者。如,openstack 可以获取红帽 OpenStack 平台环境中实例的相关信息,aws_ec2 可获取 AWS EC2 中的实例信息。
YAML 静态清单文件
基于 yaml 清单插件(此插件默认启用)可以编写基于 YAML 语法的静态清单。
创建 YAML 清单插件的原因是其易于用户阅读,易于软件解析,并且允许将 YAML 用于 playbook、变量文件和清单。
INI 静态清单示例
1 2 3 4 5 6 7 8 9
| [lb_servers] servera.lab.example.com
[web_servers] serverb.Lab.example.com serverc.lab.example.com
[backend_server_pool] server[b:f].1ab.example.com
|
以下为采用 YAML 格式的同一清单文件:
1 2 3 4 5 6 7 8 9 10
| 1b_servers: hosts: servera.lab.example.com: web_servers: hosts: serverb.lab.example.com: serverc.lab.example.com: backend_server_pool: hosts: server[b:f].lab.example.com:
|
YAML 清单
使用块来组织相关的配置项。每个块以清单组
的名称开头,后跟冒号 (:)。组名称下方缩进的所有内容都从属于该组。
如果在组名称下缩进,则主机名块将以关键字hosts
开始。hosts
下缩进的所有服务器名称都从属于这个组。这些服务器本⾝形成自己的组,因此它们必须以冒号 (:)
结尾。
当然可以在组块中使用关键字 children
。属于该组成员的组列表以此关键字开始。这些成员组可以有自己的hosts
和 children
块。
YAML 语法与 INI 语法相比有⼀个优势,它将服务器列表和嵌套组列表组织
在静态清单文件中的同一位置
。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| ┌──[root@vms81.liruilongs.github.io]-[~/ansible/inventorys] └─$ansible-inventory -i inventory.yaml --graph @all: |--@1b_servers: | |--servera.lab.example.com |--@backend_server_pool: | |--serverb.lab.example.com | |--serverc.lab.example.com | |--serverd.lab.example.com | |--servere.lab.example.com | |--serverf.lab.example.com |--@ungrouped: |--@web_servers: | |--serverb.lab.example.com | |--serverc.lab.example.com
|
all 组隐式存在顶级,并包含其余的清单作为其子集。也可以在 YAML 清单
中明确列出,但非必需:
1 2 3 4 5 6 7 8
| all: children: lb_servers: hosts: servera.1ab.example.com: web_servers: hosts: serverb.1ab.example.com:
|
某些基于 INI 的清单包含不是任何组的成员的主机
1 2 3
| notinagroup.1ab.example.com [mailserver] mai1.1ab.example.com
|
1 2 3 4 5 6 7
| ┌──[root@vms81.liruilongs.github.io]-[~/ansible/inventorys] └─$ansible-inventory -i ungroupwd.ini --graph @all: |--@mailserver: | |--mai1.1ab.example.com |--@ungrouped: | |--notinagroup.1ab.example.com
|
在基于 YAML 的静态清单中可以明确的将主机分配到 ungrouped:
1 2 3 4 5 6 7 8
| all: children: ungrouped: hosts: notinagroup.lab.example.com: mailserver: hosts: mail.1ab.example.com:
|
1 2 3 4 5 6 7
| ┌──[root@vms81.liruilongs.github.io]-[~/ansible/inventorys] └─$ansible-inventory -i ungroupwd.yaml --graph @all: |--@mailserver: | |--mail.1ab.example.com |--@ungrouped: | |--notinagroup.lab.example.com
|
若要测试清单,可使⽤ ansible 命令 ping 所有服务器:
1
| [student@workstation inventory-yaml]$ ansible -i inventory.yml all_servers -m ping
|
设置清单变量
ini格式中我们可以设置清单变量,在基于 YAML 的清单文件中我们也可以设置清单变量。
在许多情形中,最佳做法是避免将变量存储在静态清单文件中
许多经验丰富的Ansible开发人员更喜欢使用静态清单文件
来简单存储有关管理主机标识以及它们属于哪些组的信息。变量及其值存储在清单的host_vars
或group_vars
文件中。
在某些情况下,如果希望将诸如ansible_port
或ansible_connection
之类的变量与清单本身保留在同一文件中,从而将此信息保留在一个位置。如果将变量设置在太多不同的位置,则更难记住要在哪个位置设置特定变量。
在组的yaml块
中,可以使用var
关键字直接在YAML
清单文件中设置组变量。下面我们看一下ini和yaml清单文件的变量定义
组变量
INI 格式设置组变量
:
1 2 3 4 5
| [monitoring] watcher.1ab.example.com
[monitoring:vars] smtp_relay=smtp.lab.example.com
|
1 2 3 4 5 6 7 8 9 10 11 12 13
| ┌──[root@vms81.liruilongs.github.io]-[~/ansible/inventorys] └─$ansible-inventory -i vars.ini --graph @all: |--@monitoring: | |--watcher.1ab.example.com |--@ungrouped: ┌──[root@vms81.liruilongs.github.io]-[~/ansible/inventorys] └─$ansible monitoring -m debug -a 'var=smtp_relay' -i vars.ini watcher.1ab.example.com | SUCCESS => { "smtp_relay": "smtp.lab.example.com" } ┌──[root@vms81.liruilongs.github.io]-[~/ansible/inventorys] └─$
|
YAML 格式设置组变量
:
1 2 3 4 5
| monitoring: hosts: watcher.1ab.example.com: vars: smtp_relay: smtp.1ab.example.com
|
1 2 3 4 5
| ┌──[root@vms81.liruilongs.github.io]-[~/ansible/inventorys] └─$ansible monitoring -m debug -a 'var=smtp_relay' -i vat.yaml watcher.1ab.example.com | SUCCESS => { "smtp_relay": "smtp.1ab.example.com" }
|
主机变量
INI 格式设置主机变量:
1 2 3 4
| [workstations] workstation.lab.example.com localhost ansible_connection=local host.1ab.example.com
|
1 2 3 4 5 6 7
| ┌──[root@vms81.liruilongs.github.io]-[~/ansible/inventorys] └─$ansible localhost -m debug -a 'var=ansible_connection' -i locat.ini localhost | SUCCESS => { "ansible_connection": "local" } ┌──[root@vms81.liruilongs.github.io]-[~/ansible/inventorys] └─$
|
YAML 格式设置主机变量:
1 2 3 4 5 6
| workstations: hosts: workstation.lab.example.com: localhost: ansible_connection: local host.lab.example.com:
|
1 2 3 4 5 6 7
| ┌──[root@vms81.liruilongs.github.io]-[~/ansible/inventorys] └─$ansible localhost -m debug -a 'var=ansible_connection' -i local.yaml localhost | SUCCESS => { "ansible_connection": "local" } ┌──[root@vms81.liruilongs.github.io]-[~/ansible/inventorys] └─$
|
从 INI 转换到 YAML
可以使用 ansible-inventory
命令,将基于 INI 格式
的清单转换为 YAML 格式
。
此工具旨在以 Ansible
所见的方式显示整个已配置清单
,结果可能与原始清单文件中不同。ansible-inventory 命令
会解析和测试清单文件的格式,但不会尝试验证清单中的主机名是否确实存在。
假设存在一个 INI 格式的清单:
1 2 3 4 5 6 7 8 9 10 11 12
| [lb_servers] servera.lab.example.com
[web_servers] serverb.Lab.example.com serverc.lab.example.com
[web_servers:vars] alternate_server=serverd.lab.example.com
[backend_server_pool] server[b:f].1ab.example.com
|
我们可以通过--graph
参数显示主机清单
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| ┌──[root@vms81.liruilongs.github.io]-[~/ansible] └─$ansible-inventory -i hosts.yaml --graph @all: |--@backend_server_pool: | |--serverb.1ab.example.com | |--serverc.1ab.example.com | |--serverd.1ab.example.com | |--servere.1ab.example.com | |--serverf.1ab.example.com |--@lb_ervers: | |--servera.lab.example.com |--@ungrouped: |--@web_servers: | |--serverb.Lab.example.com | |--serverc.lab.example.com
|
通过 ansible-inventory 命令转换的结果:
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
| ┌──[root@vms81.liruilongs.github.io]-[~/ansible] └─$ansible-inventory --yaml -i inventory --list --output dest_inventory.yaml ┌──[root@vms81.liruilongs.github.io]-[~/ansible] └─$cat dest_inventory.yaml all: children: 1b_servers: hosts: servera.lab.example.com: {} backend_server_pool: hosts: serverb.1ab.example.com: {} serverc.1ab.example.com: {} serverd.1ab.example.com: {} servere.1ab.example.com: {} serverf.1ab.example.com: {} ungrouped: {} web_servers: hosts: serverb.Lab.example.com: alternate_server: serverd.lab.example.com serverc.lab.example.com: alternate_server: serverd.lab.example.com ┌──[root@vms81.liruilongs.github.io]-[~/ansible] └─$
|
可以发现,转化还是有一定的问题的,一般通过手动修改其中的内容,其结果应如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| ┌──[root@vms81.liruilongs.github.io]-[~/ansible] └─$cat dest_inventory.yaml all: children: 1b_servers: hosts: servera.lab.example.com: {} backend_server_pool: hosts: server[b:f]1ab.example.com: {} ungrouped: {} web_servers: hosts: serverb.Lab.example.com: serverc.lab.example.com: vars: alternate_server: serverd.lab.example.com
|
转换非常大的清单文件时,使用ansible-inventory
命令可以节省大量时间,但是重从host_vars
和 group_vars
中获取变量,会获得更好的效果。
YAML 故障排除提示
保护后面跟着空格的冒号
在未加引号的字符串中,冒号后跟空格将导致错误
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| all: children: 1b_servers: hosts: servera.lab.example.com: {} backend_server_pool: hosts: server[b:f]1ab.example.com: {} ungrouped: {} web_servers: hosts: serverb.Lab.example.com: serverc.lab.example.com: vars: alternate_server:serverd.lab.example.com
|
保护作为某一个值的开头的变量
Ansible 通过{{ variable }}
进行变量替换。但 YAML 中以 { 开头的内容解释为字典的开头。
在使用任何保留字符{} [] > | * & ! % #
@ 时,应在值的两旁使用
双引号`。
了解字符串和布尔值或浮点值之间的区别
用作变量值的布尔值和浮点数不应加引号。带引号的值被视为字典。
布尔值和字符串:
1 2
| active: yes default_answer: "yes"
|
浮点值和字符串:
1 2
| temperature: 36.5 version: "2.e"
|