Ansible 是一种配置管理工具,旨在为管理员和运营团队自动控制服务器。借助 Ansible,您可以使用单个中央服务器来控制和配置许多不同的远程系统,仅使用 SSH 和 Python 作为要求。
Ansible 根据任务定义在其管理的服务器上执行任务。这些任务使用每个任务的 YAML 小片段来调用内置和社区维护的 Ansible 模块。
随着使用单个 Ansible 控制节点管理的系统的数量和种类变得越来越复杂,将任务分组在一起是有意义的Ansible 剧本。使用 playbook 无需在远程系统上运行许多单独的任务,而是让您可以使用单个文件一次性配置整个环境。
然而,当 playbook 负责配置许多不同的系统并为每个系统提供多个任务时,它们可能会变得复杂,因此 Ansible 还允许您在称为 a 的目录结构中组织任务。Role。在此配置中,剧本调用角色而不是任务,因此您仍然可以将任务分组在一起,然后在其他剧本中重用角色。角色还允许您以一种结构化格式收集模板、静态文件和变量以及任务。
本教程将探讨如何创建角色,以及如何向角色添加模板、静态文件和变量。一旦您熟悉了构建角色的基础知识,我们将使用安塞布尔银河将社区贡献的角色纳入剧本中。在本教程结束时,您将能够为您的服务器创建您自己的环境特定角色,并在您自己的剧本中使用它们来管理一个或多个系统。
要学习本教程,您需要安装和配置 Ansible以便您可以创建和运行剧本。您还需要了解如何编写 Ansible 剧本.
在先决条件教程中,您学习了如何使用以下命令运行核心 Ansible 工具:ansible
终端中的命令。您还学习了如何将任务收集到剧本中并使用ansible-playbook
命令。从运行单个命令、任务到剧本,下一步是使用 Ansible 角色重新组织一切。
角色是任务和剧本之上的抽象级别,可让您以模块化和可重用的格式构建 Ansible 配置。当您向 playbook 添加越来越多的功能和灵活性时,它们可能会变得笨重且难以维护。角色允许您将复杂的剧本分解为单独的、较小的块,这些块可以由中心入口点进行协调。例如,在本教程中,整个playbook.yml
我们将使用的看起来像这样:
示例手册
- ---
- - 主持人:全部
- 成为:真实
- 角色:
- - 阿帕奇
- vars:
- doc_root: /var/www/示例
配置 Apache Web 服务器所需执行的整套任务将包含在apache
我们将创造的角色。该卷将定义安装 Apache 需要完成的所有任务,而不是像我们在配置管理 101:编写 Ansible 手册前提条件。
将 Ansible 设置组织为角色可以让您在不同类型的服务器之间重复使用常见的配置步骤。尽管这也可以通过在单个剧本中包含多个任务文件来实现,但角色依赖于已知的目录结构和文件名约定来自动加载将在剧本中使用的文件。
一般来说,角色背后的想法是允许您使用一致的结构共享和重用任务,同时轻松维护它们,而无需为所有基础设施重复任务。
要创建 Ansible 角色,您需要一个专门设计的目录结构。角色始终需要此目录布局,以便 Ansible 可以找到并使用它们。
我们假设您一直使用用户的主目录作为 Ansible 工作目录。如果您将 Ansible 配置保存在不同的位置,则需要更改(cd
) 到该目录。
首先,我们创建一个名为roles
。当我们想要在本教程后面的剧本中使用我们的新角色时,Ansible 将查看此处。
-
cd ~
-
mkdir roles
-
cd roles
在此目录中,我们将定义可以在多个剧本和不同服务器之间重用的角色。我们将创建的每个角色都需要有自己的目录。我们将从以下位置获取示例 Apache playbook配置管理 101:编写 Ansible 手册教程并将其变成可重用的 Ansible 角色。
作为参考,这是该教程中的剧本:
剧本.yml
- ---
- - 主持人:全部
- 成为:真实
- vars:
- doc_root: /var/www/示例
- 任务:
- - 名称:更新 apt
- apt: update_cache=是
-
- - 名称:安装 Apache
- apt: 名称=apache2 状态=最新
-
- - 名称:创建自定义文档根目录
- 文件:路径={{ doc_root }} 状态=目录所有者=www-data 组=www-data
-
- - 名称:设置 HTML 文件
- 复制: src=index.html dest={{ doc_root }}/index.html 所有者=www-data 组=www-data 模式=0644
-
- - name: 设置Apache虚拟主机文件
- 模板: src=vhost.tpl dest=/etc/apache2/sites-available/000-default.conf
- 通知:重新启动apache
-
- 处理程序:
- -名称:重新启动apache
- 服务:名称=apache2状态=重新启动
首先,让我们为我们的角色创建一个 Apache 目录,并用所需的目录填充它:
接下来,我们将创建所需的一组子目录,让 Ansible 知道它应该使用这些内容作为角色。使用以下命令创建这些目录mkdir
命令:
这些目录将包含实现我们的角色的所有代码。许多角色只会使用其中一个或几个目录,具体取决于所涉及任务的复杂性。当您编写自己的角色时,您可能不需要创建所有这些目录。
以下是每个目录代表的内容的描述:
-
defaults
:此目录允许您为包含或依赖的角色设置默认变量。此处设置的任何默认值都可以在 playbook 或清单文件中覆盖。
-
files
:此目录包含可以复制到远程服务器或在远程服务器上执行的静态文件和脚本文件。
-
handlers
:之前在 playbook 中的所有处理程序现在都可以添加到此目录中。
-
meta
:该目录保留用于角色元数据,通常用于依赖关系管理...例如,您可以定义在调用当前角色之前必须应用的角色列表。
-
templates
:此目录是为将在远程主机上生成文件的模板保留的。模板通常使用位于以下位置的文件上定义的变量vars
目录以及运行时收集的主机信息。
-
tasks
:此目录包含一个或多个文件,其中包含通常在tasks
常规 Ansible 剧本的一部分。这些任务可以直接引用角色内各自目录中包含的文件和模板,而无需提供文件的完整路径。
-
vars
:角色的变量可以在此目录内的文件中指定,然后在角色的其他位置引用。
如果一个文件名为main.yml
存在于目录中,其内容将自动添加到调用角色的剧本中。但是,这不适用于files
and templates
目录,因为需要显式引用它们的内容。
现在您已经熟悉了 Ansible 角色中每个目录的用途,我们将把 Apache playbook 变成一个角色来更好地组织事物。
我们应该已经有了roles/apache2/{subdirectories}
结构是从上一节开始设置的。现在,我们需要创建一些 YAML 文件来定义我们的角色。
我们将从任务子目录开始。现在移动到该目录:
我们需要创建一个main.yml
该目录下的文件。我们将使用 Apache playbook 的全部内容填充它,然后将其编辑为仅包含任务。
开始时该文件应如下所示:
main.yml
-
---
- - 主持人:全部
- 成为:真实
- vars:
- doc_root: /var/www/示例
-
- 任务:
- - name: Update apt
- apt: update_cache=yes
-
- - name: Install Apache
- apt: name=apache2 state=latest
-
- - name: Create custom document root
- file: path={{ doc_root }} state=directory owner=www-data group=www-data
-
- - name: Set up HTML file
- copy: src=index.html dest={{ doc_root }}/index.html owner=www-data group=www-data mode=0644
-
- - name: Set up Apache virtual host file
- template: src=vhost.tpl dest=/etc/apache2/sites-available/000-default.conf
- notify: restart apache
-
- 处理程序:
- -名称:重新启动apache
- 服务:名称=apache2状态=重新启动
我们只想保留第一个---
线和线中tasks
突出显示的部分。我们还可以删除任务左侧的无关空格。我们还将添加一个新部分来启用名为的 Apache 模块modsecurity
我们将在本教程稍后进行配置。经过这些改变之后,我们的新~/roles/apache/tasks/main.yml
文件将如下所示:
main.yml
- ---
- - 名称:更新 apt
- apt: update_cache=是
-
- - 名称:安装 Apache
- apt: 名称=apache2 状态=最新
-
- - 名称:创建自定义文档根目录
- 文件:路径={{ doc_root }} 状态=目录所有者=www-data 组=www-data
-
- - 名称:设置 HTML 文件
- 复制: src=index.html dest={{ doc_root }}/index.html 所有者=www-data 组=www-data 模式=0644
-
- - name: 设置Apache虚拟主机文件
- 模板: src=vhost.tpl dest=/etc/apache2/sites-available/000-default.conf
- 通知:重新启动apache
现在任务文件更容易遵循和理解,因为它只包含我们使用 Apache 角色时将执行的实际步骤。
请注意如何copy
and template
线路使用src=index.html
and src=vhost.tpl
分别引用我们角色中的文件,没有任何前面的路径。我们角色的目录结构允许直接通过名称引用文件和模板,Ansible 会自动为我们找到它们。
完成编辑后,请务必保存并关闭文件。
现在我们已经有了剧本的大部分内容tasks/main.yml
文件中,我们需要将处理程序部分移动到位于以下位置的文件中handlers/main.yml
.
First cd
进入handlers
我们角色的子目录:
再次,在文本编辑器中打开文件并粘贴原始文件的全部内容playbook.yml
:
我们需要保留的部分再次突出显示:
剧本.yml
-
---
- - 主持人:全部
- 成为:真实
- vars:
- doc_root: /var/www/示例
- 任务:
- - 名称:更新 apt
- apt: update_cache=是
-
- - 名称:安装 Apache
- apt: 名称=apache2 状态=最新
-
- - 名称:创建自定义文档根目录
- 文件:路径={{ doc_root }} 状态=目录所有者=www-data 组=www-data
-
- - 名称:设置 HTML 文件
- 复制: src=index.html dest={{ doc_root }}/index.html 所有者=www-data 组=www-data 模式=0644
-
- - name: 设置Apache虚拟主机文件
- 模板: src=vhost.tpl dest=/etc/apache2/sites-available/000-default.conf
- 通知:重新启动apache
-
- handlers:
- - name: restart apache
- service: name=apache2 state=restarted
还删除处理程序之前的空格。最后,该文件应如下所示:
---
- name: restart apache
service: name=apache2 state=restarted
完成后保存并关闭文件。
现在我们已经有了任务和处理程序,下一步是确保有一个index.html
文件和一个vhost.tpl
模板,以便 Ansible 可以找到它们并将其放置在我们的远程服务器上。由于我们在tasks/main.yml
文件,它们需要存在,否则 Ansible 将无法正常运行角色。
首先,创建index.html
文件在~/roles/apache/files
目录:
-
cd〜/角色/apache/文件
-
nano索引.html
将以下内容粘贴到编辑器中,然后保存并关闭它:
<html>
<head><title>Configuration Management Hands On</title></head>
<h1>This server was provisioned using <strong>Ansible</strong></h1>
</html>
接下来我们将编辑vhost.tpl
模板。切换到 templates 目录并使用 nano 编辑文件:
-
cd〜/角色/apache/模板
-
nano虚拟主机.tpl
将这些行粘贴到编辑器中,然后保存并关闭它:
<VirtualHost *:80>
ServerAdmin webmaster@localhost
DocumentRoot {{ doc_root }}
<Directory {{ doc_root }}>
AllowOverride All
Require all granted
</Directory>
</VirtualHost>
如果我们的角色依赖于另一个角色,我们可以在meta
名为的目录main.yml
。该文件可能指定该角色依赖于名为“apt”的角色。在我们创建的 Apache 角色中,我们不需要任何依赖项。然而,在假设需要另一个角色(如“apt”)的情况下,文件位于~/roles/apache/meta/main.yml
可能看起来像这样:
---
dependencies:
- apt
这将确保“apt”角色在我们的 Apache 角色之前运行。创建这样的依赖关系对于更复杂的角色非常有用,这些角色需要在运行实际角色之前就位其他软件或配置。
我们之前说过,有一个“vars”目录可用于为我们的角色设置变量。虽然可以通过角色配置默认参数vars/main.yml
文件,通常不建议较小的角色这样做。
不使用“vars”目录的原因是它使配置的详细信息驻留在角色层次结构中。角色主要是通用任务和依赖项,而变量是配置数据。将两者结合起来会让你更难在其他地方重用你的角色。
相反,最好在角色之外指定配置详细信息,以便您可以轻松共享角色,而不必担心暴露敏感信息。此外,角色中声明的变量很容易被其他位置的变量覆盖。最好将可变数据放置在用于特定任务的剧本中。
然而,“vars”目录在这里仍然值得一提,因为它对于更复杂的角色很有用。例如,如果角色需要支持不同的 Linux 发行版,则指定变量的默认值对于处理不同的包名称、版本和配置非常有用。
有时,当您创建具有大量任务、依赖项或条件逻辑的角色时,它们会变得庞大且难以理解。在这种情况下,您可以将任务拆分到各自的文件中,并将它们包含在您的文件中。tasks/main.yml
.
例如,如果我们有一组额外的任务来为 Apache 服务器配置 TLS,我们可以将它们分离到自己的文件中。我们可以调用该文件tasks/tls.yml
并将其像这样包含在tasks/main.yml
file:
. . .
tasks:
- include: roles/apache/tasks/tls.yml
现在我们已经配置了角色结构,与本教程开头的整体版本相比,我们可以通过最小的剧本来使用它。
以这种方式使用角色允许我们使用剧本来声明服务器应该做什么,而不必总是重复创建任务来实现它。
要创建一个包含我们的 Apache 角色的最小剧本,cd
在角色目录之外(本例中是我们的主目录)。现在我们可以创建一个剧本文件:
打开文件后,粘贴以下内容,然后保存并关闭文件:
---
- hosts: all
become: true
roles:
- apache
vars:
- doc_root: /var/www/example
该文件中所需的信息非常少。首先,我们列出要运行此角色的服务器,因此我们使用- hosts: all
。如果您有一组名为webservers
你可以改为瞄准他们。接下来,我们声明我们正在使用的角色。在这种情况下只有一个,所以我们使用- apache
line.
这是我们的整个剧本。它非常小,可以快速阅读和理解。像这样保持剧本整洁使我们能够专注于配置服务器的总体目标,而不是单个任务的机制。更好的是,如果我们有多个角色要求,我们现在可以将它们列在roles
我们的剧本中的部分,它们将按照它们出现的顺序运行。
例如,如果我们有使用 Apache 和 MySQL 设置 WordPress 服务器的角色,我们可能会有一个如下所示的剧本:
---
- hosts: wordpress_hosts
become: true
roles:
- apache
- php
- mysql
- wordpress
vars:
- doc_root: /var/www/example
这个剧本结构使我们能够非常简洁地了解我们想要的服务器是什么样子。最后,由于剧本调用角色,因此运行我们的命令完全相同,就好像它全部存在于单个文件中一样:
- ansible-playbook playbook.yml
Output
PLAY [all] ******************************************************************************************
TASK [Gathering Facts] ******************************************************
ok: [64.225.15.1]
TASK [apache : Update apt] **************************************************
ok: [64.225.15.1]
TASK [apache : Install Apache] **********************************************
changed: [64.225.15.1]
TASK [apache : Create custom document root] *********************************
changed: [64.225.15.1]
TASK [apache : Set up HTML file] ********************************************
changed: [64.225.15.1]
TASK [apache : Set up Apache virtual host file] *****************************
changed: [64.225.15.1]
RUNNING HANDLER [apache : restart apache] ***********************************
changed: [64.225.15.1]
PLAY RECAP ******************************************************************
64.225.15.1 : ok=7 changed=5 unreachable=0 failed=0
您也可以致电playbook.yml
file apache.yml
例如,使文件名反映其包含的角色。
如果不探索以下可用资源,有关 Ansible 角色的教程就不完整安塞布尔银河。可搜索的Galaxy是用户贡献的角色的存储库,您可以将其添加到剧本中以完成各种任务,而无需自己编写它们。
例如,我们可以添加一个有用的 Apache 模块,名为mod_security2
到我们的剧本中使用一些额外的安全设置来配置 Apache。我们将使用 Ansible Galaxy 角色,称为apache_mod安全。要使用此角色,我们将其下载到本地,然后将其包含在我们的剧本中。
首先我们先来熟悉一下ansible-galaxy
工具。我们将使用该工具搜索 Galaxy,然后从搜索命令返回的列表中选择一个角色:
- ansible-银河搜索“适用于 RedHat/CentOS/Fedora/Debian/Ubuntu 的 PHP”
搜索命令将输出如下内容:
Output
Found 21 roles matching your search:
Name Description
---- -----------
alikins.php PHP for RedHat/CentOS/Fedora/Debian/Ubuntu.
bpresles.php PHP for RedHat/CentOS/Fedora/Debian/Ubuntu.
entanet_devops.ansible_role_php PHP for RedHat/CentOS/Fedora/Debian/Ubuntu.
esperdyne.php PHP for RedHat/CentOS/Fedora/Debian/Ubuntu.
fidanf.php PHP for RedHat/CentOS/Fedora/Debian/Ubuntu.
frogasia.ansible-role-php PHP for RedHat/CentOS/Fedora/Debian/Ubuntu.
geerlingguy.php PHP for RedHat/CentOS/Fedora/Debian/Ubuntu.
icamys.php PHP for RedHat/CentOS/Fedora/Debian/Ubuntu.
jhu-sheridan-libraries.php PHP for RedHat/CentOS/Fedora/Debian/Ubuntu.
jibsan94.ansible_php PHP for RedHat/CentOS/Fedora/Debian/Ubuntu.
KAMI911.ansible_role_php PHP for RedHat/CentOS/Fedora/Debian/Ubuntu.
monsieurbiz.geerlingguy_php PHP for RedHat/CentOS/Fedora/Debian/Ubuntu.
nesh-younify.ansible-role-php PHP for RedHat/CentOS/Fedora/Debian/Ubuntu.
net2grid.php PHP for RedHat/CentOS/Fedora/Debian/Ubuntu.
thom8.ansible-role-php PHP for RedHat/CentOS/Fedora/Debian/Ubuntu.
v0rts.php PHP for RedHat/CentOS/Fedora/Debian/Ubuntu.
vahubert.php PHP for RedHat/CentOS/Fedora/Debian/Ubuntu.
Vaizard.mage_php PHP for RedHat/CentOS/Fedora/Debian/Ubuntu.
viasite-ansible.php PHP for RedHat/CentOS/Fedora/Debian/Ubuntu.
vvgelder.ansible-role-php PHP for RedHat/CentOS/Fedora/Debian/Ubuntu.
(END)
Ansible 将使用less
如果结果很多,则输出搜索结果的命令会阻塞您的终端,直到您按q
退出。当搜索结果很广泛并且您需要对它们进行分页时,这非常有用,您可以通过按space
.
我们将选择角色geerlingguy.php
对于我们的剧本。如果您想了解有关搜索结果返回的角色的更多信息,您可以访问银河搜索页面并粘贴您想了解更多信息的角色名称。
要下载角色以在我们的剧本中使用,我们使用ansible-galaxy install
命令:
- ansible-银河installgeerlingguy.php
当您运行该命令时,您应该看到如下输出:
Output
- downloading role 'php', owned by geerlingguy
- downloading role from https://github.com/geerlingguy/ansible-role-php/archive/3.7.0.tar.gz
- extracting geerlingguy.php to /home/sammy/.ansible/roles/geerlingguy.php
- geerlingguy.php (3.7.0) was installed successfully
现在我们可以将角色添加到我们的playbook.yml
file:
---
- hosts: all
become: true
roles:
- apache
- geerlingguy.php
vars:
- doc_root: /var/www/example
- php_default_version_debian: "7.2"
通过将角色放在我们的后面apache
角色,我们确保在进行任何配置之前在远程系统上设置和配置 Apachegeerlingguy.php
角色场所。我们还可以包括mysql
, and wordpress
我们根据我们希望远程服务器的行为方式选择任何顺序的角色。
Running ansible-playbook playbook.yml
添加 Galaxy 角色后将产生如下输出:
Output
PLAY [all] *********************************************************************
TASK [Gathering Facts] *********************************************************
ok: [64.225.15.1]
TASK [apache : Update apt] *****************************************************
changed: [64.225.15.1]
TASK [apache : Install Apache] *************************************************
changed: [64.225.15.1]
TASK [apache : Install modsecurity] ********************************************
changed: [64.225.15.1]
TASK [apache : Create custom document root] ************************************
changed: [64.225.15.1]
TASK [apache : Set up HTML file] ***********************************************
changed: [64.225.15.1]
TASK [apache : Set up Apache virtual host file] ********************************
changed: [64.225.15.1]
TASK [geerlingguy.php : Include OS-specific variables.] ************************
ok: [64.225.15.1]
TASK [geerlingguy.php : Define php_packages.] **********************************
ok: [64.225.15.1]
. . .
PLAY RECAP *********************************************************************
64.225.15.1 : ok=37 changed=15 unreachable=0 failed=0
(END)
Ansible 角色是构建和定义服务器外观的绝佳方式。即使您只能依赖每台服务器的剧本,学习如何使用它们也是值得的。如果您计划广泛使用 Ansible,角色将使您的主机级配置与您的任务分开,并确保您的 Ansible 代码干净且可读。最重要的是,角色允许您轻松地重用和共享代码,并以受控和模块化的方式实施更改。