Написание рецептов Chef

В предыдущем руководстве речь шла о том, что такое управление конфигурацией и как внедрить эту технологию в свою инфраструктуру.

Примечание: Руководство выполнено на Ubuntu 14.04 и Apache.

Данное руководство поможет подготовить автоматизированную оркестровку сервера с помощью инструмента конфигурационного управления Chef. Вы ознакомитесь с основными терминами, синтаксисом и функциями Chef. В результате вы получите полностью автоматизированное простое развёртывание, которое состоит из таких этапов:

  • Обновление индекса пакетов.
  • Установка Apache.
  • Создание пользовательского каталога document root.
  • Создание в нём файла index.html.
  • Применение шаблона для установки пользовательского виртуального хоста.
  • Перезапуск Apache.

Примечание: Данное руководство сосредоточено на создании рецептов Chef для автоматизации настройки. Больше о конфигурациях Chef можно прочитать в статье Анализ настроек Chef.

Начало работы

Прежде чем приступить к разработке рецепта, нужно ознакомиться с основными терминами Chef.

Терминология Chef

  • Сервер Chef: центральный сервер, управляющий оркестровкой нод.
  • Нода Chef: индивидуальный сервер, который подчиняется серверу Chef.
  • Рабочая станция Chef: машина, на которой создаётся оркестровка и откуда она загружается на сервер Chef.
  • Рецепт: файл, в котором хранится набор инструкций (ресурсов) по оркестровке. Рецепты нужно помещать в кукбуки.
  • Ресурс: фрагмент кода, который определяет необходимые системе изменения.
  • Кукбук: набор рецептов и других файлов, организованный заранее определенным образом, который облегчает совместное и повторное использование отдельных частей оркестровки.
  • Атрибуты: подробности о конкретной ноде. Атрибуты бывают автоматическими и могут присутствовать в рецепте.
  • Автоматические атрибуты: : глобальные переменные системы.
  • Сервисы: изменяют статус системного сервиса (запуск, остановка и т.д.).

Формат рецепта

Рецепты Chef пишутся в Ruby. Рецепт – это файл, в котором хранится определение ресурсов оркестровки. Рецепты можно совмещать с кодом Ruby.

Ниже приведён простой пример рецепта, который запустит apt-get update и устанавливает vim:

execute "apt-get update" do

command "apt-get update"

end
apt_package "vim" do

action :install

end

Написание рецептов

Переменные

Локальные переменные определяются внутри обычной локальной переменной Ruby. Приведённый ниже код покажет, как создать локальную переменную, которую можно использовать в определении ресурса:

package  = "vim"
apt_package package do

action :install

end

Эти переменные имеют ограниченную область применения: они действительны только внутри файла, в котором они были определены. Если вы хотите создать переменную и сделать её общедоступной (иметь возможность использовать её в других кукбуках или рецептах), нужно определить пользовательский атрибут.

Атрибуты

Атрибуты представляют данные о ноде. Chef предоставляет автоматические атрибуты – это атрибуты системы, собранные инструментом Ohai (они включают в себя платформу, имя хоста, IP-адрес по умолчанию). Но при этом вы можете создавать пользовательские атрибуты.

Атрибуты имеют различные уровни приоритета, которые определяются типом. Наиболее распространенными являются атрибуты default, так как при необходимости их можно перезаписывать другими типами атрибутов.

Если в предыдущем примере вместо локальной переменной создать атрибут default, он буде иметь такой вид:

node.default['main']['package'] = "vim"
apt_package node['main']['package'] do

action :install

end

При определении атрибута используется node.default, но далее используется node. Значение node.default определяет тип атрибута (default). Это значение можно переопределить другим типом с более высоким приоритетом (например, normal или override).

Рассмотрим такой пример:

node.normal['main']['package']  = "vim"
node.override['main']['package'] = "git"
node.default['main']['package'] = "curl"
apt_package node['main']['package'] do

action :install

end

Независимо от порядка определения атрибутов установится пакет с наивысшим приоритетом – git.

Циклы

Циклы, как правило, используются для повторения задачи с помощью различных входных значений. То есть, вместо того чтобы создавать 10 задач для установки 10 различных пакетов, вы можете создать одну задачу и использовать цикл, чтобы  повторить задачу для установки любых пакетов.

Chef поддерживает все структуры циклов Ruby для создания циклов внутри рецептов. Обычно для этого используется each.

['vim', 'git', 'curl'].each do |package|

apt_package package do

action :install

end

end

Вместо встроенного массива вы можете также создать переменную или атрибут для определения параметров, которые вы хотите использовать внутри цикла. Ниже приведён тот же самый пример кода, но теперь в нём используется локальная переменная для определения пакетов, которые должны быть установлены:

packages = ['vim', 'git', 'curl'] packages.each do |package|

apt_package package do

action :install

end

end

Использование условных выражений

Условные выражения можно использовать для динамической настройки (например, когда на основе переменной или вывода команды нужно решить, следует ли выполнять задачу).

Рецепты Chef поддерживают все условные выражения Ruby. Кроме того, все типы ресурсов поддерживают два специальных свойства, которые будут оценивать выражение, прежде чем решить, выполнять задачу или нет: это if_only и not_if

Ниже приведён пример кода, который будет проверять наличие php, прежде чем приступать к установке php-pear. Команда which проверяет, установлена ли в системе переменная php. Если which php возвращает false, эта задача не будет выполнена:

apt_package "php-pear" do

action :install
only_if "which php"

end

Условное выражение not_if работает наоборот: оно выполняет команду всегда, кроме тех случаев, когда выражение истинно. Такой код установит php5 в любую систему, кроме CentOS.

apt_package "php5" do

action :install
not_if { node['platform'] == 'centos' }

end

Чтобы выполнить более сложные вычисления или запустить несколько задач при определенном условии, можно использовать любое из стандартных условных выражений Ruby. Например, чтобы выполнить apt-get update в Debian или Ubuntu:

if node['platform'] == 'debian' || node['platform'] == 'ubuntu'

execute "apt-get update" do

command "apt-get update"

end

end

Примечание: node[‘platform’] – это автоматический атрибут Chef. Последний пример демонстрирует более сложную условную конструкцию; её можно упростить с помощью атрибута node[‘platform_family’], который возвращает debian для систем Debian и Ubuntu.

Использование шаблонов

Шаблоны обычно используются в конфигурационных файлах и позволяют добавлять переменные и другие функции, которые делают эти файлы более универсальными и обеспечивают их повторное выполнение. Chef использует шаблоны Embedded Ruby (ERB), которые поддерживают условные выражения, циклы и другие функции Ruby.

Ниже приведён пример шаблона ERB, который создаст виртуальный хост Apache, в котором используется переменная для создания корневого каталога этого хоста:

<VirtualHost *:80>
ServerAdmin webmaster@localhost
DocumentRoot <%= @doc_root %>
<Directory <%= @doc_root %>>
AllowOverride All
Require all granted
</Directory>
</VirtualHost>

Чтобы применить шаблон, нужно создать ресурс template. Чтобы заменить виртуальный хост Apache по умолчанию, используйте такой шаблон:

template "/etc/apache2/sites-available/000-default.conf" do

source "vhost.erb"
variables({ :doc_root => node['main']['doc_root'] })
action :create

end

В данном случае Chef будет искать шаблон vhost.tpl в каталоге templates в кукбуке, в котором хранится этот рецепт.

В отличие от других популярных инструментов управления конфигурациями, Chef строже относится к переменным. Например, определяя ресурс template, вы должны явно задать все переменные. В данном примере атрибут doc_root шаблона виртуального хоста определяется с помощью метода variables.

Определение сервисов

Ресурсы сервисов изменяют состояние системного сервиса (например, останавливают или перезапускают его).

Рассмотрим предыдущий пример шаблона, который предназначен для создания виртуального хоста Apache. Чтобы обеспечить перезагрузку Apache после изменения виртуального хоста, нужно создать ресурс сервиса. Это делается так:

service "apache2" do

action [ :enable, :start ]

end

Теперь, определив ресурс template, нужно добавить опцию notify, чтобы добавить перезагрузку:

template "/etc/apache2/sites-available/000-default.conf" do

source "vhost.erb"
variables({ :doc_root => node['main']['doc_root'] })
action :create
notifies :restart, resources(:service => "apache2")

end

Пример рецепта

Теперь можно собрать весь код данного руководства в один рецепт, который будет автоматизировать установку Apache в Ubuntu 14.04.

Примечание: Дополненный вариант рецепта можно найти на Github. Также эта папка содержит файл Vagrant, который позволяет протестировать плейбук на упрощённой установке с помощью виртуальной машины Vagrant.

node.default['main']['doc_root'] = "/vagrant/web"
execute "apt-get update" do

command "apt-get update"

end
apt_package "apache2" do

action :install

end
service "apache2" do

action [ :enable, :start ]

end
directory node['main']['doc_root'] do

owner 'www-data'
group 'www-data'
mode '0644'
action :create

end
cookbook_file "#{node['main']['doc_root']}/index.html" do

source 'index.html'
owner 'www-data'
group 'www-data'
action :create

end
template "/etc/apache2/sites-available/000-default.conf" do

source "vhost.erb"
variables({ :doc_root => node['main']['doc_root'] })
action :create
notifies :restart, resources(:service => "apache2")

end

  • Строка 1: определение атрибута node[‘main’][‘doc_root’]. Здесь можно использовать и простую локальную переменную, но в большинстве сценариев рецептам необходимы глобальные переменные из других рецептов или файлов. В данном случае вместо локальной переменной нужно создать атрибут.
  • Строки 3-5: ресурс execute запускает apt-get update.
  • Строки 7-10: ресурс apt_package устанавливает apache2.
  • Строки 12-15: ресурс service запускает apache2. Позже нужно добавить опцию notify, чтобы сервис перезагружался. Определение сервиса обязательно должно идти перед опцией notify, иначе вы получите ошибку.
  • Строки 17-22: ресурс directory использует значение, определённое пользовательским атрибутом node[‘main’][‘doc_root’], чтобы создать корневой каталог.
  • Строки 24-29: ресурс cookbook_file копирует локальный файл (index.html) на удалённый сервер и помещает его в корневой каталог.
  • Строки 311-36: ресурс template применяет шаблон виртуального хоста Apache и перезапускает apache2.

Заключение

Chef – производительный инструмент управления конфигурацией, который автоматизирует оркестровку и развёртывание с помощью Ruby. Chef позволяет использовать стандартные функции языка для достижения максимальной гибкости, а также предлагает DSL для некоторых ресурсов.

Tags: , ,

Добавить комментарий