可视化Ansible的清单和变量之间的依赖关系
可以使用名为ansible-inventory-grapher的工具来可视化Ansible的清单和vars之间的依赖关系。
通过可视化,例如以下的图像,我们可以理解库存和变量之间的依赖关系。

可视化的意义
大家好,你们有在运用Ansible吗?
Ansible是一种用于基础设施配置管理的有用工具,但从“轻松使用”的层面到“认真使用”的层面,我认为需要进行各种审查。过去,我们可以直接将所有内容写入一个Playbook,但现在需要将其分解成多个角色进行管理,同时还需要在清单中建立父子关系等。结果就是,以前可以轻松理解的东西不知不觉中变得混乱,无法理解其依赖关系。
要简单地理解依存关系,你应该怎么做?嗯,就是可视化。通过可视化,不需要每次都解释,只需看图就能一下子明白。如果只是自己在开发的话,或许无所谓,但为了促进其他开发者对共同理解,可视化是非常重要的。
作为开始前的假设,我们假设Ansible已经安装好了。
Ansible的库存图表生成工具
使用ansible-inventory-grapher工具来可视化清单。
你是ansible-lint的作者对吗?
说到“库存可视化”,你可能不明白是什么意思,不过通过官方作者的工具说明应该很容易理解。
比如说,假设库存文件中写着这样一句话:
[production:children]
production-az-a
#production-az-b
production-web
#production-other-app
[web:children]
production-web
#preprod-web
[production-web:children]
production-web-a
#production-web-b
[production-az-a:children]
production-web-a
#production-other-app-a
[production-web-a]
prod-web-server-[1:99]a
当把生产环境、开发环境等配置和服务器类型如Web/DB作为组合存放在清单中时,情况就会变得极其复杂。
若仅仅是涉及清单的依赖关系,查看上述文件即可解决,但实际上我们将清单划分为多个部分的原因是因为“在这些单位里定义了vars”的缘故,不是吗?
例如,我们可以对vars进行全局定义,也可以针对生产环境进行定义,还可以仅在web服务器中定义vars等等。到底这些vars是在哪里定义的呢?
虽然这是一个不可避免的问题,但为了让它更易于理解,我们可以使用ansible-inventory-grapher。
安装 ansible-inventory-grapher
由于官方页面上已经提到了,所以您可以按照其要求使用pip进行安装,但如果在CentOS7上,可以使用epel-release中的软件包以便更方便。
$ sudo yum -y install ansible-inventory-grapher
此外,在CentOS6系列(python2.6)上无法正常运行。
使用ansible-inventory-grapher进行可视化
基本格式如下。
$ ansible-inventory-grapher -i <インベントリファイル> <パターン> --format "<出力ファイル>"
<模式>指定了从清单中读取主机名。可以多个并列。
–format 指定输出文件名。{} 中放置模式匹配的主机名。(※ 正式文档中使用{hostname},但是{} 应该是正确的)
如果要在一个名为test-<主机名称>.dot的文件中输出两个清单(prod-web-server-78a和prod-web-server-28a)的组依赖关系,请按以下方式操作。
$ ansible-inventory-grapher -i inventory/hosts prod-web-server-78a prod-web-server-28a --format "test-{}.dot"
我想你可以看出,这样做将会在下方输出以下两个文件。
-
- test-prod-web-server-28a.dot
- test-prod-web-server-78a.dot
将其转换为PNG格式
由于上述文件是graphviz格式,只要安装graphviz就可以进行参考,但是直接这样做的话,想查看的人就必须安装graphviz。为了方便分发,我们将其转换为png格式。
为了实现这个目的,我们需要安装Graphviz。
$ sudo yum -y install graphviz
若要使用graphviz将其转换为png格式,执行以下命令:
$ dot -Tpng -o <出力ファイル(png)> <入力ファイル(dot)>
比如说,以下是一些命令。
$ dot -Tpng -o test-prod-web-server-28a.png test-prod-web-server-28a.dot
完成的作品如下图所示(字体已更改为Arial)。
不仅可以显示库存,还可以可视化该组中定义的所有vars!

ansible-inventory-grapher的遗憾之处
字体设定为Times New Roman、粗体固定。
就像这儿所说的那样,字体被固定为Times New Roman。
由于这个原因,在运行ansible-inventory-grapher时无法传递graphviz选项,因此字体指定被忽略了。
所以,如果想要更改字体,需要执行以下其中一种方法。无论采用哪种方法,在修改后使用dot命令将其转换为png文件,就能(如果字体已安装)使用所喜欢的字体正确创建图像。
- ansible-inventory-grapherのソースを書き換える(好きなフォントを指定)
以下是一种方法:使用上述路径,直接将字体更改为任意喜欢的字体。由于有4行,所以我们要全部更改。
- ansible-inventory-grapherのソースを書き換えてコマンドラインで指定できるようにする
删除上述4行中的face=”Times New Roman, Bold”。这样,在执行ansible-inventory-grapher时,-a选项指定字体将生效。
$ ansible-inventory-grapher -i inventory/hosts prod-web-server-78a prod-web-server-28a --format "test-{}.dot" -a 'node [fontname="Arial"];'
如果按照上述的方法,添加属性 -a ‘node [fontname=”Arial”];’,就可以起作用了。
- dotファイルで出力されたあとにsedなどで書き換える
如果您绝对不想修改源代码,请选择这里。
需要在inventory目录下存在group_vars文件夹
如果在inventory目录下没有group_vars目录,Ansible就无法正确读取vars。ansible-inventory-grapher本身只是调用了Ansible的VariableManager,所以详细原因可能是Ansible的问题(?),但调用方式几乎相同,所以必须仔细查看Ansible源代码才能知道为什么不能正常工作。
为什么在Ansible的最佳实践中,group_vars和inventory被同时放置,并且在官方都被推荐使用,难道这是无效的吗?
如果你的配置类似最佳实践,那么只需将group_vars移动到以下位置,它肯定可以正常运行。
# ダメな例(varsを読んでくれない)
ansible-playbook
- group_vars
- varsファイル
- inventory
- インベントリファイル
# 大丈夫な例(varsを読んでくれる)
ansible-playbook
- inventory
- インベントリファイル
- group_vars
- varsファイル
将库存主机保持为IP地址时,在进行dot转换为PNG时会出现错误。
$ dot -Tpng -o aig-192.168.33.11.png aig-192.168.33.11.dot
Warning: syntax ambiguity - badly delimited number '192_' in line 1 of aig-192.168.33.11.dot splits into two tokens
Warning: aig-192.168.33.11.dot: syntax error in line 1 near '_168_33_11'
Warning: syntax ambiguity - badly delimited number '192_' in line 4 of aig-192.168.33.11.dot splits into two tokens
Warning: syntax ambiguity - badly delimited number '192_' in line 49 of aig-192.168.33.11.dot splits into two tokens
Warning: syntax ambiguity - badly delimited number '192_' in line 50 of aig-192.168.33.11.dot splits into two tokens
我不熟悉Graphviz的规范,但似乎不能以数字开头。
只要提供一个合适的主机名,它就可以正常运行。
如何熟练使用ansible-inventory-grapher?
当一个playbook变得过于庞大,无法确定其依赖关系时,使用这个工具可以立即了解依赖关系。

随着使用Playbook的次数增加,变量会变得庞大,清单的相互依赖关系也会变得复杂,最终达到无人能理解的状态。
这张图片初次看时会极大地提高理解度,因此如果将最新的图片嵌入到Playbook仓库的README中,那么Playbook仓库将变得非常清晰易懂。
因此,在更新Playbook时,最好能够使用Git的ServiceHook等自动输出这个PNG文件。