一个常见的自动化需求是在配置文件中设置一个值,甚至基于一些给定的参数部署一个新的配置文件。Ansible提供的模块可以执行与古老的sed和awk实用程序类似的功能,当然,这些是修改现有配置文件的有效方法。假设我们有一个小的Apache虚拟主机配置文件,其中包含以下代码:
我们希望部署此配置,但要为每台主机自定义DocumentRoot参数。当然,我们可以将前面的文件完全按原样部署到每台主机上,然后使用正则表达式和Ansible replace模块来查找DocumentRoot行并对其进行修改(类似于使用sed命令行实用程序)。生成的剧本可能如下所示:
如果根据前面的内容在files/vhost.conf文件中创建示例静态虚拟主机配置文件并运行本剧本,我们可以看到它可以工作,如图2-13所示。
图 2-13
然而,这个解决方案不够优雅。首先,我们使用了两个任务,如果还想自定义ServerName,则需要更多的任务。其次,那些熟悉正则表达式的人会知道,不需要太多技巧就可以把这里使用的简单表达式搞坏。为这样的任务编写健壮的正则表达式本身就是一门艺术。
幸运的是,Ansible从编写它的Python语言那里继承了一种称为 Jinja2模板化 的技术。这种技术非常适合这样的场景(以及许多其他与部署相关的自动化场景)。现在,我们将启动虚拟主机配置文件定义为templates/vhost.conf.j2中的模板,而不是像上述烦琐的多步骤方法,如下所示:
如你所见,这与原始配置文件几乎相同,只不过现在用一个变量替换了一个静态值,并用一对花括号括起来,就像我们在剧本里做的那样。在继续这个例子之前,值得一提的是,Jinja2是一个非常强大的模板系统,它远远超出了将简单变量替换为文本文件的范围。它支持条件语句,例如if…else和for循环,并包含一系列过滤器,可用于操作内容(例如,将字符串转换为大写,或将列表的成员连接在一起形成字符串)。
尽管如此,本书并不是作为Ansible或Jinja2的完整语言参考,而是一本向你展示如何使用Ansible建立SOE的实用指南。请参阅2.10节以获取参考资料,这将使你对Ansible和Jinja2有一个更完整的理解。
回到示例,我们将修改剧本来部署这个示例,如下所示:
请注意,template模块将配置模板复制到远程主机,就像前面的示例中的copy模块一样,并填充我们指定的任何变量,这个剧本要优雅得多。这是一种以可重复、通用的方式部署配置文件的强大方法,强烈建议你尽可能采用这种方法。当人们编辑文件时,他们通常以不一致的方式进行编辑,这可能是自动化的敌人,因为必须构建一个真正健壮的正则表达式,以确保捕获所有可能的边缘情况。使用Ansible从模板部署可以创建可重复、可靠的结果,这些结果可以在生产环境中轻松验证。运行这个剧本会得到与前面更复杂的示例相同的结果,如图2-14所示。
这就结束了我们目前对变量的研究,实际上,结束了我们在Ansible中的速成课程。在下一节中,将总结目前所学的一切。
图 2-14