配置管理101:写Ansible Playbook

该系列的这部分将引导您完成创建使用Ansible,配置管理工具,它提供了一套完整的自动化框架和协调能力的自动化服务器配置的过程中,同时保持最终的简单性和极简主义的目标。我们将集中在语言术语,语法和必要创造一个简化的例子,以完全自动化使用Apache一个Ubuntu 14.04 Web服务器的部署功能。

介绍

简而言之,服务器配置管理(通常称为IT自动化)是一种将基础架构管理转变为代码库的解决方案,描述了在一组可以进行版本控制和轻松重用的配置脚本中部署服务器所需的所有过程。 它可以大大提高任何服务器基础架构的完整性。

先前的指导 ,我们谈到了实施配置管理策略为您的服务器基础架构,配置管理工具是如何工作的,以及这些工具通常有什么共同之处的主要优势。

本系列的这一部分将引导您使用Ansible自动化服务器配置的过程,这是一个配置管理工具,提供完整的自动化框架和编排功能,同时保持极致简约和极简主义的目标。 我们将重点介绍创建一个简化示例所需的语言术语,语法和功能,以使用Apache完全自动化部署Ubuntu 14.04 Web服务器。

这是我们需要自动化以实现我们的目标的步骤列表:

  1. 更新apt缓存
  2. 安装Apache
  3. 创建自定义文档根目录
  4. 放置index.html文件中的自定义文档根目录
  5. 应用模板以设置我们的自定义虚拟主机
  6. 重新启动Apache

我们将首先看看Ansible使用的术语,然后概述可用于编写剧本的主要语言特性。 在本指南的最后,我们将分享完整的示例,以便您可以自己尝试。

注意:本指南旨在介绍Ansible语言以及如何编写playbook以自动完成服务器设置。 对于Ansible的更多介绍视图,包括必要的安装和开始使用此工具的步骤,请查看我们如何安装和配置Ansible在Ubuntu 14.04指南。

入门

在我们进入Ansible的更实际的视图之前,重要的是我们熟悉这个工具引入的重要术语和概念。

Ansible条款

  • Controller计算机 :在安装Ansible机器,负责所管理的服务器上运行的配置
  • 盘点 :一个INI包含关于您所管理的服务器的信息文件
  • 剧本 :切入点Ansible provisionings,其中自动化是通过使用YAML格式定义任务
  • 任务 :要执行定义一个程序块,例如:安装包
  • 模块 :模块通常是抽象的系统任务,就像包处理或创建和更改文件。 Ansible有许多内置模块,但你也可以创建自定义模块
  • 作用 :组织剧本和其它文件,以便于共享和重用一个供应的部分的预先定义的方式
  • :从开始到结束执行的配置被称为
  • 事实 :包含有关系统的信息的全局变量,如网络接口或操作系统
  • 处理程序 :用于触发服务状态变化,比如重新启动或停止服务

Ansible provisionings使用写YAML ,一个简单的数据序列化语言。

任务

任务定义应由配置执行的单个步骤。 它通常涉及模块的使用或原始命令的执行(实际上,它只是创建用于处理原始命令的模块)。 这是一个任务看起来:

- name: This is a task
  apt: pkg=vim state=latest

name部分是可选的,但是推荐,因为在执行任务时,在配置的输出显示出来。 apt的部分是一个内置的Ansible模块抽象封装在基于Debian的发行管理。 这个任务告诉Ansible该包vim应具有其状态改变到latest ,这将导致包管理器安装该包的情况下,它尚未安装。

手册格式

Playbooks是Ansible配置的入口点。 它们包含有关应该执行设置的系统的信息,以及应执行的指令或步骤。 下面你可以找到执行两个任务的简单剧本的例子:更新apt缓存并安装vim算账:

---
- hosts: all
  become: true
  tasks:
     - name: Update apt-cache 
       apt: update_cache=yes

     - name: Install Vim
       apt: name=vim state=latest

YAML依赖于压痕序列化数据结构。 因为这个原因,当写剧本,特别是当复制的例子,你需要格外小心保持正确的缩进。

在本指南结束之前,我们将看到更多现实生活的剧本例子,详细解释。 下一节将概述可用于编写Ansible游戏的最重要的元素和功能。

写作剧本

使用变量

有不同的方法可以在Ansible中定义变量。 最简单的方法是通过使用vars一个剧本的部分。 下面的例子定义了一个变量package ,后来被一个任务内使用:

---
- hosts: all
  become: true
  vars:
     package: vim
  tasks:
     - name: Install Package
       apt: name={{ package }} state=latest

可变package可以从供应的任何一点进行访问,甚至包括文件和模板。

使用循环

循环通常用于使用不同的输入值重复任务。 例如,您可以创建单个任务,并使用循环来重复任务,以便安装所有不同的软件包,而不是创建10个任务来安装10个不同的软件包。

创建任务内的循环,包括选项with_items与值的阵列。 该内容可以通过循环变量来访问item ,如下面的例子:

- name: Install Packages
  apt: name={{ item }} state=latest
  with_items:
     - vim
     - git
     - curl  

你也可以使用一个数组变量来定义你的项目:

---
- hosts: all
  sudo: true
  vars:
     packages: [ 'vim', 'git', 'curl' ]
  tasks:
     - name: Install Package
       apt: name={{ item }} state=latest
       with_items: packages

使用条件

例如,条件可以用于基于变量或来自命令的输出来动态地决定是否应当执行任务。

下面是一个只在Debian系统上执行的任务示例:

- name: Shutdown Debian Based Systems
  command: /sbin/shutdown -t now
  when: ansible_os_family == "Debian"

有条件when作为参数接收到要计算的表达式。 该任务只有在情况下被执行表达式为true 在这种情况下,我们测试的事实看,如果系统是从Debian家族。

在IT自动化中,条件的一个常见用例是,任务的执行取决于命令的输出。 使用Ansible,我们实现这个方法是通过注册一个变量来保存结果一个命令执行,然后在后续任务中测试这个变量。 我们可以测试命令的退出状态(如果失败或成功)。 我们也可以检查输出中的特定内容,虽然这可能需要使用regex表达式和字符串解析命令。

下面的例子显示了基于从输出两项有条件的任务php -v命令。 我们将测试命令的退出状态,因为如果此服务器上未安装PHP,将无法执行。 ignore_errors任务的一部分是很重要的,以确保供应不断即使在命令失败的执行。

- name: Check if PHP is installed
  register: php_installed
  command: php -v
  ignore_errors: true

- name: This task is only executed if PHP is installed
  debug: var=php_install
  when: php_installed|success

- name: This task is only executed if PHP is NOT installed
  debug: msg='PHP is NOT installed'
  when: php_installed|failed

debug这里使用的模块为表示变量或调试消息的内容的有用模块。 它可以打印一个字符串(使用时msg参数)或(使用时,打印变量的内容var参数)。

使用模板

模板通常用于设置配置文件,允许使用变量和其他旨在使这些文件更通用和可重用的功能。 Ansible使用的Jinja2模板引擎。

下面是用于设置Apache虚拟主机的模板示例,使用变量设置此主机的文档根目录:

<VirtualHost *:80>
    ServerAdmin webmaster@localhost
    DocumentRoot {{ doc_root }}

    <Directory {{ doc_root }}>
        AllowOverride All
        Require all granted
    </Directory>
</VirtualHost>

内置模块template被用来从一个任务应用的模板。 如果上面的命名模板文件vhost.tpl ,你把它放在同一目录下你的剧本,这是你将如何应用模板替换默认的Apache虚拟主机:

- name: Change default Apache virtual host
  template: src=vhost.tpl dest=/etc/apache2/sites-available/000-default.conf

定义和触发处理程序

处理程序用于触发在服务,一状态改变,如重新启动停止 处理程序有一个行为非常相似的任务,在它们定义相同的顺序被执行一次,但是,如果预先从触发它们仅执行notify中的任务指令。 处理程序通常被定义为一个阵列handlers的剧本的部分。

让我们考虑我们以前的模板使用示例,其中我们设置一个Apache虚拟主机。 如果要确保在虚拟主机更改后重新启动Apache,您首先需要为Apache服务创建一个处理程序。 这是如何在playbook中定义处理程序:

handlers:
    - name: restart apache
      service: name=apache2 state=restarted

    - name: other handler
      service: name=other state=restarted

name ,因为这将是该处理的唯一标识符这里的指令是很重要的。 若要从一个任务触发此处理程序,你应该使用的notify选项:

- name: Change default Apache virtual host
  template: src=vhost.tpl dest=/etc/apache2/sites-available/000-default.conf
  notify: restart apache

Playbook示例

现在让我们看看一个剧本,它将在Ubuntu 14.04系统中自动安装Apache Web服务器,如本指南的介绍中所述。

完整的示例,包括设置Apache模板文件和一个HTML文件,由Web服务器提供服务,可以发现在Github上 该文件夹还包含一个Vagrantfile,可以让你在一个简化的安装测试剧本,利用管理的虚拟机放浪

下面你可以找到完整的剧本:

playbook.yml
---
- hosts: all
  become: true
  vars:
    doc_root: /var/www/example
  tasks:
    - 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
  handlers:
    - name: restart apache
      service: name=apache2 state=restarted

手册解释

hosts:all

PlayBook的说,它应该适用于开始all在您的库存(主机hosts: all )。 可以将剧本的执行限制到特定主机或一组主机。

变成:真

become: true部分告诉Ansible使用权限升级(Sudo),在这个剧本执行的所有任务。 此选项可以在逐个任务的基础上被覆盖。

vars

定义了一个变量, doc_root ,即稍后在一个任务使用。 此部分可以包含多个变量。

任务

定义实际任务的部分。 第一更新apt缓存,第二个任务安装包apache2

第三个任务使用内置的模块文件创建一个目录,作为我们的文档根目录。 此模块可用于管理文件和目录。

第四个任务使用的模块复制到本地文件复制到远程服务器。 我们正在复制一个简单的HTML文件,作为Apache托管的网站。

处理程序

最后,我们的handlers部分,其中服务声明。 我们定义了restart apache是从第四任务,其中应用了Apache模板通知处理程序。

结论

Ansible是一个最低限度的IT自动化工具,它具有较低的学习曲线,使用YAML其供应脚本。 它有大量的内置模块,可用于抽象任务,如安装软件包和使用模板。 其简化的基础架构要求和简单的语言可以很好地适合那些正在开始配置管理。 但是,它可能缺少一些高级功能,您可以使用更复杂的工具,如Puppet和Chef。

这一系列的下一部分 ,我们将看到Puppet,使用基于Ruby的表现力和强大的自定义DSL编写脚本供应一种流行和完善的配置管理工具的实用的概述。