如何在Ubuntu上创建AnsiblePlaybook以自动化系统配置
状态: 已弃用
本文介绍了不再受支持的 Ubuntu 版本。 如果您当前正在运行运行 Ubuntu 12.04 的服务器,我们强烈建议您升级或迁移到受支持的 Ubuntu 版本:
原因: Ubuntu 12.04 已于 2017 年 4 月 28 日终止生命周期 (EOL) and no longer receives security patches or updates. This guide is no longer maintained.
请参阅: 本指南可能仍可用作参考,但可能不适用于其他 Ubuntu 版本。 如果可用,我们强烈建议使用为您正在使用的 Ubuntu 版本编写的指南。 您可以使用页面顶部的搜索功能来查找更新的版本。
介绍
Ansible 是一个简单的配置管理系统,可用于自动化和组织大型计算机网络的系统配置任务。 虽然其他一些配置管理系统需要在服务器和客户端系统上安装许多不同的包,但使用 Ansible,您只需要安装一个服务器组件并具有对客户端计算机的 SSH 访问权限。
在之前的指南中,我们讨论了 如何安装 Ansible 软件和学习基本命令 。 在本指南中,我们将讨论 Ansible playbooks,这是 Ansible 创建自动化脚本来配置客户端计算机的方式。
我们将假设您有一个已配置的 Ansible 服务器和一些客户端,就像我们在上一个教程中离开的那样。 在我们的指南中,服务器是 Ubuntu 12.04 机器,我们要配置的客户端也是 Ubuntu 12.04 机器,以便于解释。
什么是 Ansible 剧本?
Ansible playbook 是一种以脚本方式向远程计算机发送命令的方法。 您可以通过将脚本传递给一个或多个系统来配置整个复杂环境,而不是单独使用 Ansible 命令从命令行远程配置计算机。
Ansible playbook 以 YAML 数据序列化格式编写。 如果您不知道什么是数据序列化格式,请将其视为一种将编程数据结构(列表、数组、字典等)转换为可以轻松存储到磁盘的格式的方法。 然后可以使用该文件在以后重新创建结构。 JSON 是另一种流行的数据序列化格式,但 YAML 更容易阅读。
每个剧本都包含一个或多个剧本,将主机映射到某个功能。 Ansible 通过称为任务的东西来做到这一点,这些任务基本上是模块调用。
探索基本剧本
让我们看一个基本的剧本:
--- - hosts: droplets tasks: - name: Installs nginx web server apt: pkg=nginx state=installed update_cache=true notify: - start nginx handlers: - name: start nginx service: name=nginx state=started
让我们把它分成几个部分,以便我们了解这些文件是如何构建的以及每个部分的含义。
该文件以:
---
这是 YAML 将文件解释为正确文档的要求。 YAML 允许在一个文件中存在多个“文档”,每个文件由 ---
分隔,但 Ansible 只希望每个文件一个,因此它应该只出现在文件的顶部。
YAML 对空白非常敏感,并使用空白将不同的信息组合在一起。 您应该只使用空格而不是制表符,并且必须使用一致的间距才能正确读取文件。 处于同一缩进级别的项目被视为兄弟元素。
以 -
开头的项目被视为列表项目。 具有 key: value
格式的项目作为散列或字典运行。 这就是基本 YAML 的全部内容。
YAML 文档基本上定义了一个层次树结构,其中包含的元素位于左侧。
在第二行,我们有这个:
--- - hosts: droplets
正如我们在上面了解到的,这是 YAML 中的一个列表项,但由于它位于最左侧,因此它也是一个 Ansible “玩”。 播放基本上是在一组主机上执行的任务组,以允许它们完成您要分配给它们的功能。 就像我们在这里所做的那样,每个播放都必须指定一个主机或一组主机。
接下来,我们有一组任务:
--- - hosts: droplets tasks: - name: Installs nginx web server apt: pkg=nginx state=installed update_cache=true notify: - start nginx
在顶层,我们有与“主机:”处于同一级别的“任务:”。 这包含一个包含键值对的列表(因为它以“-”开头)。
第一个,“名称”,与其说是名称,不如说是描述。 您可以随意调用它。
下一个键是“apt”。 这是对 Ansible 模块的引用,就像我们使用 ansible 命令并输入以下内容一样:
ansible -m apt -a 'whatever' all
这个模块允许我们指定一个包和它应该处于的状态,在我们的例子中是“已安装”。 update-cache=true
部分告诉我们的远程机器在安装软件之前更新它的包缓存(apt-get update)。
“通知”项包含一个列表,其中一项称为“启动 nginx”。 这不是一个内部 Ansible 命令,它是对处理程序的引用,当从任务中调用它时,它可以执行某些功能。 我们将在下面定义“start nginx”处理程序。
--- - hosts: droplets tasks: - name: Installs nginx web server apt: pkg=nginx state=installed update_cache=true notify: - start nginx handlers: - name: start nginx service: name=nginx state=started
“处理程序”部分与“主机”和“任务”处于同一级别。 处理程序就像任务一样,但它们仅在被任务告知客户端系统发生更改时才运行。
例如,我们这里有一个处理程序,它在安装包后启动 Nginx 服务。 除非“安装 nginx Web 服务器”任务导致系统发生更改,否则不会调用处理程序,这意味着必须安装包并且该包尚未安装。
我们可以将这个剧本保存到一个名为“nginx.yml”的文件中。
仅在某些情况下,如果您要在 JSON 中编写相同的文件,它可能看起来像这样:
[ { "hosts": "droplets", "tasks": [ { "name": "Installs nginx web server", "apt": "pkg=nginx state=installed update_cache=true", "notify": [ "start nginx" ] } ], "handlers": [ { "name": "start nginx", "service": "name=nginx state=started" } ] } ]
如您所见,YAML 更紧凑,大多数人会说更具可读性。
运行 Ansible 剧本
构建剧本后,您可以使用以下格式轻松调用它:
ansible-playbook playbook.yml
例如,如果我们想在所有 Droplet 上安装和启动 Nginx,我们可以发出以下命令:
ansible-playbook nginx.yml
由于 playbook 本身指定了它应该运行的主机(即,我们在上一个教程中创建的“droplets”组),因此我们不必指定要运行的主机。
但是,如果我们想过滤主机列表以仅应用于其中一个主机,我们可以添加一个标志来指定文件中主机的子集:
ansible-playbook -l host_subset playbook.yml
因此,如果我们只想在“host3”上安装和运行 Nginx,我们可以输入:
ansible-playbook -l host3 nginx.yml
向剧本添加功能
现在我们的剧本看起来像这样:
--- - hosts: droplets tasks: - name: Installs nginx web server apt: pkg=nginx state=installed update_cache=true notify: - start nginx handlers: - name: start nginx service: name=nginx state=started
它很简单而且可以工作,但它所做的只是安装一个软件并启动它。 这本身并不是很有好处。
我们可以通过向我们的剧本添加任务来开始扩展功能。
添加默认索引文件
我们可以通过添加如下几行来告诉它从我们的 Ansible 服务器传输文件到主机:
- 主机:水滴任务:
- 名称:上传主机副本的默认 index.html:src=static_files/index.html dest=/usr/share/nginx/www/mode=0644
处理程序:-名称:启动 nginx 服务:名称=nginx 状态=已启动
然后,我们可以在当前目录中创建一个名为 static_files
的目录,并在其中放置一个 index.html 文件。
mkdir static_files nano static_files/index.html
在这个文件中,让我们创建一个基本的 html 结构:
<html> <head> <title>This is a sample page</title> </head> <body> <h1>Here is a heading!</h1> <p>Here is a regular paragraph. Wow!</p> </body> </html>
保存并关闭文件。
现在,当我们重新运行 playbook 时,Ansible 将检查每个任务。 它会看到 Nginx 已经安装在主机上,所以它会保留它。 它将看到新的任务部分,并将默认的 index.html 文件替换为我们服务器中的文件。
登记结果
当您手动安装和配置服务时,几乎总是需要知道您的操作是否成功。 我们可以使用“注册”将此功能添加到我们的剧本中。
对于每个任务,我们可以选择将其结果(失败或成功)注册到一个变量中,以便稍后检查。
使用此功能时,我们还必须告诉 Ansible 忽略该任务的错误,因为如果发生任何问题,它通常会中止该主机的 playbook 执行。
因此,如果我们想检查任务是否失败以决定后续步骤,我们可以使用注册功能。
例如,我们可以告诉我们的剧本上传一个 index.php
文件(如果存在)。 如果该任务失败,我们可以尝试上传 index.html
文件。 我们将在其他任务中检查失败条件,因为我们只想在 PHP 文件失败时上传 HTML 文件:
主机:液滴任务:
- name: 安装 nginx web server apt: pkg=nginx state=installed update_cache=true notify:
- 名称:上传主机副本的默认 index.php:src=static_files/index.php dest=/usr/share/nginx/www/mode=0644注册:php ignore_errors: True
- 名称:删除主机命令的 index.html:rm /usr/share/nginx/www/index.html当:php|success
- 名称:上传主机副本的默认 index.html:src=static_files/index.html dest=/usr/share/nginx/www/mode=0644 when:php|failed
处理程序:
- 名称:启动 nginx 服务:名称=nginx 状态=已启动
- name: 安装 nginx web server apt: pkg=nginx state=installed update_cache=true notify:
注意:我们的主机此时没有配置处理PHP文件,所以即使你上传了一个PHP文件,它也不会被正确处理。
这个新版本尝试将 PHP 索引文件上传到主机。 它将操作的成功注册到一个名为“php”的变量中。
如果此操作成功,则接下来运行删除 index.html 文件的任务。
如果操作失败,则改为上传 index.html 文件。
结论
现在,您应该对如何使用 Ansible 自动化复杂任务有了很好的了解。 这是一个关于如何开始构建配置库的基本示例。
结合我们在第一个教程中了解的主机和组定义,并使用可用变量来填充信息,我们可以开始将复杂的计算机系统放在一起,这些系统可以相互交互。 在以后的文章中,我们将讨论如何在我们的剧本中实现变量并创建角色来帮助管理复杂的任务。