16 мая 2014

Автоматизированная установка WordPress на VPS с помощью Ansible

WordPress
Tutorial
Recovery mode
Добрый день, Хабр.

Не так давно я начал разбираться с замечательным инструментом для любого DevOps — Ansible. Сегодня хочу представить на ваш взыскательный суд небольшую вводную статью по использованию этого, во многом прекрасного, инструмента. Итак, начнем.

Что такое Ansible


Ansible — это инструмент для автоматизации задач системного администратора и не только. Если своими словами — это та штука, которая позволяет автоматически настраивать сервера пачками.

Кто-то скажет, что он не нужен, т.к. есть Chef, Puppet, etc. Я с этими людьми абсолютно соглашусь. Если вы можете использовать эти инструменты — отлично. Я же пишу эту статью для тех, кто хочет немного понять как работает Ansible и как с его помощью можно многое автоматизировать.

Если вы до этого не сталкивались с Ansible вообще, то советую почитать статью компании Селектел. Отличная статья.

Максимум автоматизации


Давайте определимся, что нам нужно, чтоб запустить Wordpress на VPS сервере с установленной Ubuntu:
  • Nginx
  • Mysql
  • PHP5
  • Memcached для использования W3Total Cache плагина
  • Wordpress

Вот в таком порядке мы и будем писать роли для настройки сервера.

Структура каталогов для нашей задачи будет такая:
image

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. Разбираем то, что написано по шагам:
  1. Добавляем репозиторий nginx (ppa:nginx/stable)
  2. Устанавливаем nginx-extras (При необходимости он содержит SPDY модуль и его можно включить в конфиге)
  3. Удаляем симлинк на конфиг по умолчанию

В каталоге 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


Теперь по шагам:
  1. Добавляем ключ репозитория
  2. Добавляем сам репозиторий с проверкой, что файл /etc/apt/sources.list.d/percona.list создался
  3. Устанавливаем три пакета:
    • percona-server-server-5.5
    • percona-server-client-5.5
    • python-mysqldb (нужен для управления mysql сервером из ansible)
  4. Меняем пароль рута на указанный в переменных (см. ниже)

Переменные мы укажем в основном 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 }}"

А теперь пройдем по каждому пункту:
  1. Создаем базу данных, указав параметры подключения (логин root и его пароль)
  2. Создаем пользователя базы данных с паролем, указав при этом его права на только что созданную базу
  3. Создаем конфигурацию сервера в Nginx, используя заранее заготовленный шаблон (см. ниже) и посылаем сигнал на рестарт сервиса Nginx
  4. Активируем сервер в Nginx, создав симлинк
  5. Скачиваем, указанную в переменных, версию Wordpress
  6. Создаем каталог для Wordpress
  7. Распаковываем скачанный архив и устанавливаем необходимые права на файлы и каталоги

Теперь шаблон конфигурации сервера 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.

Надеюсь, что это немного поможет вам автоматизировать рутину на работе (и дома). Спасибо, что читали.
Только зарегистрированные пользователи могут участвовать в опросе. Войдите, пожалуйста.
Чем вы пользуетесь для автоматизации рутинных задач по настройке серверов?
47.58% Ansible 59
14.52% Chef 18
12.1% Puppet 15
33.06% Самописные скрипты 41
11.29% Другое (укажите в комментариях) 14
Проголосовали 124 пользователя. Воздержались 54 пользователя.
Теги:ansiblewordpressvpssystem administration
Хабы: WordPress
+3
12,3k 68
Комментарии 3
Лучшие публикации за сутки