启动并运行Ansible很简单,并且大多数主要的Linux发行版、FreeBSD以及几乎任何运行Python的平台都有可用的软件包。如果你安装了支持 Windows Subsystem for Linux(WSL) 的最新版本的Microsoft Windows,Ansible甚至可以在这个Windows环境下安装和运行。
注意,在编写本书时,Ansible还没有本机Windows软件包。
官方Ansible文档提供了所有主要平台的安装文档:https://docs.ansible.com/ansible/latest/installation_guide/intro_installation.html。
本章的示例将在Ubuntu服务器18.04.2上运行。然而,由于Ansible可以跨多个不同的平台工作,所以大多数示例也应该在其他操作系统上工作(或者只需要少量调整)。
根据官方安装文档,执行以下命令在演示系统上安装最新版本的Ansible:
如果一切顺利的话,你应该能够通过运行以下命令来查询Ansible二进制文件的版本:
输出如图2-1所示。
图 2-1
恭喜!既然已经安装了Ansible,那么让我们来看看运行第一组Ansible任务,称为 剧本(playbook) 的基本方法。要运行其中某个剧本,实际上需要准备好以下三件东西:
1.配置文件
2.清单(inventory)
3.剧本本身
安装Ansible后,默认配置文件通常安装在/etc/Ansible/ansible.cfg文件中。有许多高级功能可以通过此文件进行更改,并且可以使用多种方法覆盖它。对于本书,我们几乎只使用默认设置,这意味着现在确认此文件存在就足够了。
要了解有关Ansible配置文件的更多信息,以下文档是一个很好的起点,请访问https://docs.ansible.com/ansible/latest/installation_guide/intro_configuration.html。
没有清单,Ansible上什么都不会发生。清单是一个文本文件(或脚本),它为Ansible二进制文件提供一个主机名列表,以便对其进行操作,即使它只是本机主机。我们将在本章的下一节更详细地介绍清单,因为它们将在自动化过程中发挥重要作用。现在,你将发现在大多数Linux平台上,示例清单文件作为Ansible安装的一部分安装在/etc/ansible/hosts中。当清单文件为空(或仅包含注释,如示例文件)时,Ansible仅对localhost隐式操作。
最后,你必须实际拥有一个针对一个或多个服务器运行的剧本。现在让我们通过一个例子来获得一个非常简单的剧本以运行Ansible。Ansible剧本是用YAML[一个递归的缩写词,意思是 YAML不是标记语言(YAML Ain't Markup Language) ]编写的,而且它非常容易阅读(这是Ansible剧本的核心优势之一),易于掌握,并且很容易理解,无论是应用还是修改它。
如果你不熟悉用Python或YAML编写代码,那么关于为剧本编写YAML,你需要知道一件事:缩进很重要。YAML没有使用括号或大括号来定义代码块,也没有使用分号来表示行尾(这在许多高级语言中很常见),而是使用缩进级别本身来确定代码中的位置,以及它与周围代码的关系。缩进总是使用空格创建,从不使用制表符。即使这两种缩进在肉眼看来是一样的,YAML解析器也不会认为它们是一样的。
考虑以下代码块:
这是Ansible剧本的开始。Ansible YAML文件总是以三个连字符(---)开头,没有缩进。接下来,我们有一行定义了剧情(play)的开始,用单连字符(-)表示,没有缩进。请注意,Ansible剧本可以由一个或多个剧情组成,每个剧情(在基本层面上)都是一组在给定主机上执行的任务。剧本的这一行指定了剧情的名字。尽管name关键字在大多数地方都是可选的,可以省略,但是强烈建议在所有剧情定义中都包含它(就像我们在这里所做的那样),并且在每个任务中都包含它。很简单,这有助于提高剧本的可读性和新人学习剧本的速度,从而提高效率,降低新人的入门门槛,正如我们在上一章所讨论的那样。
此代码块的第三行告诉Ansible应该针对哪个主机(hosts)运行剧情中包含的任务。在本例中,我们只针对localhost运行。第四行告诉Ansible不要成为(become)超级用户(root),因为这个任务不需要它。某些任务(例如,重新启动系统服务)必须以超级用户身份执行,在这种情况下,你可以指定become:true。注意前面代码中第三行和第四行上的两个空格缩进,这告诉YAML解析器,这些行是在第二行定义的剧情的一部分。
现在,让我们通过在前一个任务下附加以下代码块,向剧本中添加两个任务:
tasks关键字定义了剧情定义的结束,以及我们希望执行的实际任务的开始。请注意,它仍然由两个空格缩进,这告诉解析器,这是我们前面定义的剧情的一部分。然后再次增加下一行的缩进,以表示这是tasks块的一部分。
现在,你将看到我们正在建立一个熟悉的模式。每当一行代码构成前面语句的一部分时,我们都会将缩进增加两个空格。每个新项都以一个连字符(-)开头,因此前面的代码块包含两个任务。
第一个任务使用name关键字和值Show a message作为文档记录(类似其他编程语言中的注释),并使用 Ansible模块 。模块是Ansible用来执行给定任务的预定义代码块。这里包含的debug模块主要用于显示消息或变量内容,因此也用于剧本调试。我们将msg参数传递给debug模块,方法是将msg再缩进两个空格,告诉模块在运行剧本时要打印哪个消息。
第二个任务有name和Touch a file关键字,并使用file模块来touch位于/tmp/foo中的文件。当我们运行这个剧本时,输出如图2-2所示。
图 2-2
作为大多数简单剧本的经验法则,任务是从上到下顺序运行的,使得执行顺序可以预测且易于管理。现在,你已经编写并执行了第一个Ansible剧本。这很容易,并且将它与单个测试系统集成所涉及的工作也很少。现在,对于这样一个简单的例子,一个合理的疑问是:既然两行shell脚本就可以实现相同的功能,那么为什么还要用Ansible添这么多麻烦呢?shell脚本的示例如以下代码块所示:
使用Ansible的第一个原因是,虽然这个示例非常简单易懂,但随着脚本所需的任务变得更加复杂,它们变得更难以阅读,需要了解shell脚本的人来调试或修改它们。而使用Ansible剧本,你可以看到代码的可读性非常好,而且每个部分都有一个关联的名称(name)。强制缩进还有助于提高代码的可读性,虽然shell脚本中同时支持注释和缩进,但它对两者都不强制,而且它们通常被忽略。除此之外,所有模块都必须有文档才能被核心Ansible发行版接受,因此,你可以保证手头上有高质量的文档来编写你的剧本。模块文档可以在Ansible官方网站上找到,或者作为已安装的Ansible软件包的一部分。例如,如果我们想学习如何使用前面使用的file模块,只需在系统的shell中输入以下命令:
调用此命令时,它将为你提供file模块的完整文档。顺便说一句,它与官方Ansible网站上的文档相同。因此,即使所使用的系统与Internet断开连接,你仍然可以随时使用Ansible模块文档。图2-3显示了我们刚刚运行的命令的输出页面。
图 2-3
使用Ansible的下一个原因是,(绝大部分)Ansible模块都提供了对幂等更改的支持。这意味着,如果已经做了更改,我们就不会再做第二次了。这对于一些可能具有破坏性的更改尤其重要。它还可以节省时间和计算资源,甚至有助于审计系统。除此之外,Ansible还提供了流控制和健壮的错误处理,而shell脚本即使在发生错误后仍将继续,除非你集成了自己的错误处理代码(可能导致不可预测或不希望的结果)。Ansible将停止所有进一步的执行,并要求你于再次运行剧本之前修复问题。
值得一提的是,尽管模块构成了Ansible强大功能的核心部分,但有时任何可用模块都无法处理你需要的功能。Ansible作为 开源软件(Open Source Software,OSS) 的美妙之处在于,你可以编写和集成自己的模块。这超出了本书的范围,但很值得研究,因为这会提高你的Ansible技能。如果现有模块没有所需的功能,并且你没有时间或资源来编写自己的模块,Ansible还可以将原始shell命令发送到正在自动化的系统。实际上,有两个模块(shell和command)可以向远程系统发送原始命令。因此,如果需要,你甚至可以将shell脚本与Ansible混合使用,尽管你应该在使用shell或command之前始终使用本机Ansible模块。Ansible是非常灵活的,因为它的内置功能非常丰富,但是如果它有不足之处,那么自己扩展功能也非常容易。
这些好处只是冰山一角,我们将在本章继续探讨其他的好处。如前所述,本章并非详尽无遗,而是作为Ansible的入门指南,帮助你入门并理解书中的示例。
在下一节中,我们将探讨使用Ansible而不是简单的shell脚本的原因之一。