Добрый день.
Не так давно я начал разбираться с замечательным инструментом для любого DevOps — Ansible. Сегодня хочу представить на ваш взыскательный суд небольшую вводную статью по использованию этого, во многом прекрасного, инструмента. Итак, начнем.
Что такое Ansible
Ansible — это инструмент для автоматизации задач системного администратора и не только. Если своими словами — это та штука, которая позволяет автоматически настраивать сервера пачками.
Кто-то скажет, что он не нужен, т.к. есть Chef, Puppet, etc. Я с этими людьми абсолютно соглашусь. Если вы можете использовать эти инструменты — отлично. Я же пишу эту статью для тех, кто хочет немного понять как работает Ansible и как с его помощью можно многое автоматизировать.
Если вы до этого не сталкивались с Ansible вообще, то советую почитать статью компании Селектел. Отличная статья.
Максимум автоматизации
Давайте определимся, что нам нужно, чтоб запустить WordPress на
- Nginx
- Mysql
- PHP5
- Memcached для использования W3Total Cache плагина
- WordPress
Вот в таком порядке мы и будем писать роли для настройки сервера.
Структура каталогов для нашей задачи будет такая:
Nginx
В каталоге roles/nginx/tasks создаем main.yml со следующим содержимым:
- name: Add nginx repository
apt_repository: repo='ppa:nginx/stable'
- name: Install nginx
action: apt pkg=nginx-extras state=installed update_cache=true
- name: Disable default site
file:
path: /etc/nginx/sites-enabled/default
state: absent
Все, что начинается с новой строки как "- name" — это отдельная задача для Ansible. Разбираем то, что написано по шагам:
- Добавляем репозиторий nginx (ppa:nginx/stable)
- Устанавливаем nginx-extras (При необходимости он содержит SPDY модуль и его можно включить в конфиге)
- Удаляем симлинк на конфиг по умолчанию
В каталоге roles/nginx/handlers создаем файл main.yml со следующим содержимым:
- name: restart nginx
service:
name: nginx
state: restarted
Это описание сервиса для перезагрузки Nginx'а. Он нам понадобится после установки конфига для нашего WordPress'а.
На этом с Nginx'ом все. Два простых файла нам позволят установить репозиторий в систему, установить вебсервер, убрать его настройки по умолчанию и определить сервис для его перезагруки.
Идем далее.
MySQL
Я привык ставить Percona MySQL server. Лучше он или хуже — можно долго спорить. Я привык и использую его.
Принцип абсолютно тот же. Файл roles/percona-mysql/tasks/main.yml:
- name: Add GPG key for repository
command: apt-key adv --keyserver keyserver.ubuntu.com --recv CD2EFD2A
- name: Add Percona repository
shell:
echo "deb http://repo.percona.com/apt {{ ansible_lsb['codename'] }} main" | tee /etc/apt/sources.list.d/percona.list
creates=/etc/apt/sources.list.d/percona.list
- name: Install Percona MySQL server
apt:
pkg: "{{ item }}"
update_cache: true
with_items:
- percona-server-server-5.5
- percona-server-client-5.5
- python-mysqldb
- name: Change root password (fail is not a problem)
mysql_user:
name: root
password: "{{ mysql_root_password}}"
ignore_errors: yes
Теперь по шагам:
- Добавляем ключ репозитория
- Добавляем сам репозиторий с проверкой, что файл /etc/apt/sources.list.d/percona.list создался
- Устанавливаем три пакета:
- percona-server-server-5.5
- percona-server-client-5.5
- python-mysqldb (нужен для управления mysql сервером из ansible)
- Меняем пароль рута на указанный в переменных (см. ниже)
Переменные мы укажем в основном yml файле ниже. Там же будут указаны имя базы, пользователь с паролем и т.п.
PHP5
Поскольку мы не используем Apache, то и php мы будем использовать с php-fpm. Для этого в файл roles/php5/handlers/main.yml описываем сервис php5-fpm:
- name: restart php5-fpm
service:
name: php5-fpm
state: restarted
Его мы вызовем после конфигурирования php5-fpm, чтоб перезапустить демон.
Содержимое roles/php5/tasks/main.yml:
- name: install php5
apt: pkg={{ item }}
with_items:
- php5
- php5-cgi
- php5-fpm
- php5-memcache
- php5-memcached
- php5-mcrypt
- php5-mysql
- php5-gd
- php5-curl
- php5-xmlrpc
- name: change listen socket
lineinfile:
dest: '/etc/php5/fpm/pool.d/www.conf'
insertafter: 'listen = 127.0.0.1:9000'
line: 'listen = /var/run/fpm.socket'
notify: restart php5-fpm
Первым шагом мы устанавливаем необходимые пакеты. Здесь все просто.
А вот второй шаг более интересен. Разберемся подробнее. В Nginx мы будем использовать общение с php5-fmp через unix-соккет. Для этого нам надо в конфиге пула www демона php5-fpm указать, чтоб он слушал соккет по нужному нам пути. Модуль lineinfile позволяет нам это сделать:
- «dest» — это путь, где нужно внести правки.
- «insertafter» — найти в указанном файле строку «listen = 127.0.0.1:9000» и вставить после нее указанное в «line»
- «notify» — Послать уведомление сервису «restart php5-fpm» (вот зачем нужно было описание сервиса php5-fpm)
Memcached
С этим сервисом все очень просто. Нужно установить его и все. Содержимое roles/memcached/tasks/main.yml:
- name: install memcached server
apt:
pkg: memcached
WordPress
Вот тут мы и установим автоматически WordPress, создадим для него базу данных и конфигурацию nginx. Почему именно здесь? Все просто. Вы можете взять любую роль и использовать ее в других своих ansible проектах. Или создать еще одну роль и развернуть не wordpress, а свой какой-то проект рядом с wordpress'ом. Т.е. это сделано для банального удобства.
Итак, roles/wordpress/tasks/main.yml:
- name: creating database
mysql_db:
name: "{{ db_name }}"
state: "present"
login_user: "root"
login_password: "{{ mysql_root_password }}"
- name: creating database user
mysql_user:
name: "{{ db_user }}"
password: "{{ db_password }}"
priv: "{{ db_name }}.*:ALL"
state: "present"
login_user: "root"
login_password: "{{ mysql_root_password }}"
- name: install nginx configuration
template:
src: wordpress.conf
dest: /etc/nginx/sites-available/wordpress.conf
notify: restart nginx
- name: activate site configuration
file:
src: '/etc/nginx/sites-available/wordpress.conf'
dest: '/etc/nginx/sites-enabled/wordpress.conf'
state: 'link'
- name: download WordPress
get_url:
url: "{{ download_url }}"
dest: "/tmp/latest.tar.gz"
- name: creating directory for WordPress
file:
path: "{{ wpdirectory }}"
state: "directory"
owner: "www-data"
group: "www-data"
- name: unpack WordPress installation
shell: "tar xvfz /tmp/latest.tar.gz -C {{ wpdirectory }} && chown -R www-data:www-data {{ wpdirectory }}"
А теперь пройдем по каждому пункту:
- Создаем базу данных, указав параметры подключения (логин root и его пароль)
- Создаем пользователя базы данных с паролем, указав при этом его права на только что созданную базу
- Создаем конфигурацию сервера в Nginx, используя заранее заготовленный шаблон (см. ниже) и посылаем сигнал на рестарт сервиса Nginx
- Активируем сервер в Nginx, создав симлинк
- Скачиваем, указанную в переменных, версию WordPress
- Создаем каталог для WordPress
- Распаковываем скачанный архив и устанавливаем необходимые права на файлы и каталоги
Теперь шаблон конфигурации сервера Nginx roles/wordpress/templates/wordpress.conf:
server {
listen 80 default_server;
root {{ wpdirectory }}/wordpress;
index index.php index.html index.htm;
server_name {{ domain }};
location / {
try_files $uri $uri/ /index.php?q=$uri&$args;
}
error_page 404 /404.html;
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/www;
}
# pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
location ~ .php$ {
try_files $uri =404;
fastcgi_pass unix:/var/run/php5-fpm.sock;
fastcgi_index index.php;
include fastcgi_params;
}
}
server {
listen 80;
server_name www.{{ domain }};
location / {
return 301 http://{{ domain }};
}
}
Описывать принципы конфигурации Nginx — это тема для отдельной статьи и даже не одной. Оставим это дело для домашнего задания.
Сборка воедино и запуск установки
Для того, чтоб Ansible знал, что и как запускать, нам надо написать playbook wordpress.yml:
- hosts: appservers-php
sudo: yes
vars:
- mysql_root_password: "SuperP@S$w0rd"
- domain: "example.com"
- download_url: "http://wordpress.org/latest.tar.gz"
- wpdirectory: "/var/www"
- db_name: "wordpress"
- db_user: "wordpress"
- db_password: "wordpress"
roles:
- { role: nginx }
- { role: percona-mysql }
- { role: memcached }
- { role: php5 }
- { role: wordpress }
Этот файл указывает Ansible что, на каких серверах, в какой последовательности и с какими правами выполнять.
- hosts — это список хостов из файла hosts (см.ниже), на которых должны быть произведены все действия;
- sudo — выполнять ли все действия из под sudo;
- vars — переменные, которые используются в ролях:
- mysql_root_password — какой пароль установить пользователю root в MySQL
- domain — домен сайта, который указывается в конфигурации nginx
- wpdirectory — в какой каталог установить WordPress
- db_* — соответствующие параметры для MySQL
- roles — выполняемые задачи (роли)
И осталось нам описать только список серверов для установки всего в файле hosts:
[appservers-php]
example.com ansible_ssh_host=10.0.0.2 ansible_ssh_user=ubuntu
Блок в первой строке обозначает на список хостов, который указан в wordress.yml. Дальше собственно каждый сервер с новой строки.
Первым указывается домен сервера.
Вторым указывает IP адрес сервера, куда должен идти Ansible по ssh. Этот параметр не обязательный, если у вас домен уже сконфигурирован на нужный сервер.
Третьим параметром идет имя пользователя, с которым Ansible будет заходить на сервер через ssh.
Теперь можно запускать установку:
ansible-playbook -i hosts wordpress.yml -kK
- k — запросить ssh пароль.
- K — запросить sudo пароль
После окончания работы можно заходить на сервер по HTTP и сконфигурировать WordPress для работы.
Готовый рецепт можно взять на github.
Надеюсь, что это немного поможет вам автоматизировать рутину на работе (и дома). Спасибо, что читали.
Автор: dmitriylyalyuev