Добавить в корзинуПозвонить
Найти в Дзене
Yodo чат-бот учитель

Развертывание статического веб-сайта с помощью Ansible

Развертывание статического веб-сайта с помощью Ansible Один из лучших способов начать работу с новым инструментом автоматизации — использовать его для упрощения того, что вы уже делаете. У многих системных администраторов есть свои личные веб-сайты. Управление развертыванием статического веб-сайта — это отличный способ войти в мир Ansible и автоматизированной, воспроизводимой инфраструктуры. В этой статье я расскажу вам о развертывании простого веб-сайта на NGINX с помощью Ansible. Хотя может возникнуть соблазн использовать для этого официальный шаблон NGINX Ansible, я рекомендую вам сначала сделать это самостоятельно. Это отличный способ обучения, и вы будете чувствовать себя более уверенно в работе с Ansible после самостоятельного решения некоторых проблем, прежде чем использовать другие инструменты. Установка. Как подготовиться к развертыванию веб-сайта Прежде чем начать, позвольте мне представить обзор среды, используемую для этой статьи. Я использую стандартную настройк
Оглавление

Развертывание статического веб-сайта с помощью Ansible

Один из лучших способов начать работу с новым инструментом автоматизации — использовать его для упрощения того, что вы уже делаете. У многих системных администраторов есть свои личные веб-сайты. Управление развертыванием статического веб-сайта — это отличный способ войти в мир Ansible и автоматизированной, воспроизводимой инфраструктуры. В этой статье я расскажу вам о развертывании простого веб-сайта на NGINX с помощью Ansible.

Хотя может возникнуть соблазн использовать для этого официальный шаблон NGINX Ansible, я рекомендую вам сначала сделать это самостоятельно. Это отличный способ обучения, и вы будете чувствовать себя более уверенно в работе с Ansible после самостоятельного решения некоторых проблем, прежде чем использовать другие инструменты.

Установка. Как подготовиться к развертыванию веб-сайта

Прежде чем начать, позвольте мне представить обзор среды, используемую для этой статьи. Я использую стандартную настройку ролей Ansible и расположение каталогов, как описано в документации.

$ ls
group_vars/ inventory.ini
roles/ site.yml

Мой файл инвентаризации содержит один хост в группе под названием «webservers», и этой группе назначена одна роль в файле site.yml:

$ cat inventory.ini
[webservers]
nyc-webserver-1.example.com

$ cat site.yml
- hosts: webservers
roles:
- webserver

В этой статье рассматривается создание роли веб-сервера. Прежде чем садиться за написание любого инструмента, полезно обдумать общие цели. В данном случае я хочу написать роль, которая:

  1. Устанавливает и обеспечивает базовую конфигурацию веб-сервера (NGINX).
  2. Позволяет мне быстро предоставить конфигурацию веб-сервера для одного или нескольких веб-сайтов без необходимости копаться в коде
  3. Развертывает фактический веб-сайт на веб-сервере. Я начну с простого развертывания на основе файлов, а затем перейду к модели, использующей Git для получения последней версии сайта.

Давайте начнем!

Установка и настройка веб-сервера

Первое, что должна сделать автоматизация, — это установить и настроить NGINX, выбранный мной веб-сервер. Файл roles/webserver/tasks/main.yml, показанный ниже, является простым способом выполнения этой задачи:

---
- name: Install packages
package:
name: "{{ webserver_packages }}"
state: latest

- name: Add base NGINX configuration file
copy:
dest: /etc/nginx/nginx.conf
src: etc/nginx/nginx.conf
owner: root
group: root
mode: 0644
notify: Reload NGINX

Обратите внимание, что я использую переменную webserver_packages для установки пакетов, вместо того чтобы явно указывать NGINX и другое программное обеспечение. Эта переменная облегчает добавление или удаление пакетов из моей роли без необходимости редактировать фактический код. Переменная webserver_packages определена в файле roles/webserver/vars/main.yml:

---

webserver_packages:
- nginx

Вторая задача копирует на место конфигурацию NGINX по умолчанию. Источником этой конфигурации является файл roles/webserver/files/etc/nginx/nginx.conf, который выглядит как стандартный файл конфигурации NGINX с некоторыми незначительными изменениями, например, отключением серверных токенов:

user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log;
pid /run/nginx.pid;

# Load dynamic modules. See /usr/share/doc/nginx/README.dynamic.
include /usr/share/nginx/modules/*.conf;

events {
worker_connections 1024;
}

http {
log_format main
'$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
server_tokens off;
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 2048;

include /etc/nginx/mime.types;
default_type application/octet-stream;
# Load modular configuration files from the /etc/nginx/conf.d directory.
# See http://nginx.org/en/docs/ngx_core_module.html#include
# for more information.

include /etc/nginx/conf.d/*.conf;
}

Обратите внимание, что я не просто поместил этот файл в roles/webserver/files/nginx.conf. Вместо этого я сопоставил путь источника с путем назначения на сервере: roles/webserver/files/etc/nginx/nginx.conf. Хотя это немного увеличивает дерево каталогов, это отличный способ убедиться в том, что вы знаете, куда отправятся ваши файлы и шаблоны на целевом хосте. За годы работы я убедился, что это очень полезная организационная тактика.

Наконец, вы можете видеть, что задача конфигурации уведомляет обработчик Restart NGINX, который находится в roles/webserver/handlers/main.yml

- name: Reload NGINX
service:
name: nginx
state: reloaded

Запуск этого плейбука (с помощью ansible-playbook -i inventory.ini site.yml) развертывает очень базовую конфигурацию NGINX, но мой сервер пока не делает ничего полезного. Следующим шагом будет настройка блоков сервера для обслуживания каждого моих веб-сайтов.

Развертывание серверных блоков

NGINX использует серверные блоки для настройки отдельных именованных сайтов. Серверные блоки аналогичны виртуальным хостам в веб-сервере Apache. Чтобы сделать мои сайты доступными, мне нужен серверный блок для каждого сайта. Может возникнуть соблазн установить отдельную задачу для развертывания каждого блока, например, так:

- name: Add server block for site1.example.com
copy:
src: etc/nginx/conf.d/site1.example.com
dest: /etc/nginx/conf.d/site1.example.com.conf

- name: Add server block for site2.example.com
copy:
src: etc/nginx/conf.d/site2.example.com
dest: /etc/nginx/conf.d/site2.example.com.conf

Однако это требует внесения изменений в фактический код Ansible каждый раз, когда вы хотите добавить сайт. Это также зависит от отдельных статических конфигурационных файлов для каждого блока сервера. Это кажется чрезмерным и не совсем соответствует духу написания многократно используемых компонентов, которые можно легко использовать в других проектах.

Шаблоны и циклы Ansible предоставляют отличный способ многоразового использования. Вместо того чтобы определять отдельную задачу для конфигурации каждого сайта, я могу просмотреть содержимое переменной и создать шаблон конфигурационного файла для каждого блока сервера:

- name: Add static site config files
template:
src: etc/nginx/conf.d/site.conf.j2
dest: "/etc/nginx/conf.d/{{ item.name }}.conf"
owner: root
group: root
mode: 0644
with_items: "{{ webserver_static_sites }}"
notify: Reload NGINX

Эта задача использует модуль шаблонов для создания отдельных конфигурационных файлов для каждого сайта, определенного в переменной webserver_static_sites. Эта переменная определена в групповых переменных для группы webserver в group_vars/webservers.yml

webserver_static_sites:
- name: site1.example.com
root: /usr/share/nginx/site1.example.com

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

roles/webserver/templates/etc/nginx/conf.d/site.conf.j2:

server {
listen 80;
listen [::]:80;

server_name {{ item.name }};
root {{ item.root }};
index index.html
server_tokens off;
charset utf-8;

location / {
# First attempt to serve request as file, then
# as directory, then fall back to displaying a 404.
try_files $uri $uri/ =404;
}
}

На основе этого шаблона видно, что задача перебирает каждую запись в переменной webserver_static_sites. Затем задача создает конфигурационный файл для каждого из них с соответствующими директивами (имя_сервера и root).

В данном случае у меня есть только один сайт (site1.example.com). Запуск Ansible с этой установкой создает единственный файл /etc/nginx/conf.d/site1.example.com.conf, который выглядит следующим образом (обратите внимание, что имя_сервера и root были заполнены из шаблона):

server {
listen 80;
listen [::]:80;
server_name site1.example.com;
root /usr/share/nginx/site1.example.com;
index index.html
server_tokens off;
charset utf-8;
location / {
# First attempt to serve request as file, then
# as directory, then fall back to displaying a 404.
try_files $uri $uri/ =404;
}
}

Кажется, что это очень много работы для одного сайта! Однако настоящая сила этого многоразового подхода проявляется, когда я хочу добавить несколько сайтов. Например, рассмотрим измененный файл group_vars/webserver.yml ниже:

webserver_static_sites:
- name: site1.example.com
root: /usr/share/nginx/site1.example.com

- name: site2.example.com
root: /usr/share/nginx/site2.example.com

- name: site3.example.com
root: /usr/share/nginx/site3.example.com

Не внося никаких изменений в свой код, я добавляю новые сайты на свой веб-сервер, просто добавляя записи в переменную webserver_static_sites. Последующие запуски Ansible развертывают всю конфигурацию, необходимую для размещения этих сайтов, и теперь я могу повторно использовать эту роль веб-сервера в других проектах.

Вы заметите, что я использовал очень простой конфигурационный файл NGINX для каждого сайта. Однако этот шаблон может быть легко расширен для добавления дополнительных директив конфигурации. Попробуйте сделать это с некоторыми из наиболее распространенных, которые вы можете использовать в конфигурации веб-сайта!

Развертывание кода

Если вы следовали за нами до этого момента, у вас есть роль Ansible. Она устанавливает и настраивает NGINX с базовым конфигом и серверными блоками. Это замечательно, но никто не захочет посещать ваш сайт, если на нем нет никакого содержимого. Далее я расскажу о двух различных способах развертывания содержимого на вашем сайте.

Первый способ развертывания содержимого сайта заключается в простом копировании ресурсов с локальной машины на веб-сервер с помощью модуля copy:

- name: Copy site contents
copy:
dest: "{{ item.root }}/"
src: "usr/share/nginx/{{ item.name }}/"
owner: root
group: root
mode: 0755
with_items: "{{ webserver_static_sites }}"

Приведенная выше задача выполняет итерации по каждому сайту, определенному в переменной webserver_static_sites. Затем копирует содержимое сайта в roles/webserver/files/usr/share/nginx/{{ item.name }} в место назначения на удаленном сервере. Если вы только начинаете идти по этому пути, это хорошее начало. Однако в этом случае код вашего приложения (содержимое вашего веб-сайта) переплетается с системой управления конфигурацией (репозиторием Ansible). Хотя вы можете переместить путь к источнику за пределы дерева каталогов роли Ansible, этот подход также предполагает, что весь код вашего веб-сайта доступен (и актуален).

Лучше хранить веб-код в системе управления исходным кодом, например, Git, и поручить Ansible развертывать код из этого хранилища. Такое хранение гарантирует, что код на вашем веб-сервере всегда актуален. И полностью отделяет управление конфигурацией от кода и ресурсов веб-сайта. Во-первых, Git должен быть установлен на веб-сервере. Установка проста благодаря разделению пакетов на переменные в файле roles/webserver/vars/main.yml:

webserver_packages:
- nginx
- git

Далее замените задачу copy из предыдущего примера на задачу, приведенную ниже. Как видим, эта задача использует модуль Ansible Git для проверки кода из репозитория. Затем помещает его в соответствующий каталог назначения на веб-сервере:

- name: Clone git repositories
git:
repo: "{{ item.repository}}"
dest: "{{ item.root }}"
force: yes
with_items: "{{ webserver_static_sites }}"

Этот шаг создает дополнительный ключ (репозиторий) в словаре для каждого веб-сайта. Файл group_vars/webserver.yml может быть обновлен этим ключом, что позволяет Ansible извлекать код из удаленного Git-репозитория:

webserver_static_sites:
- name: site1.example.com
root: /usr/share/nginx/site1.example.com
repository: https://github.com/acritelli/example-static-site.git

Обратите внимание, что если вы уже развернули код, используя пример с копированием модуля, вам придется удалить каталог на веб-сервере. Это необходимо сделать, потому что Git не будет клонировать в непустой каталог.

Заключительные мысли

Итак, развертывание простого статического веб-сайта — это отличный способ окунуться в Ansible и увидеть немедленные результаты. Некоторые системные администраторы воспринимают эту задачу как должное. В конце концов, многие из нас размещают частные веб-серверы и сайты. Однако потратить время на написание собственной роли Ansible, позволяющей быстро развернуть веб-сервер, — задача, которую стоит выполнить. Это поможет вам отточить навыки работы с Ansible, сократит время развертывания сервера, когда придет время неизбежного обновления ОС. Также позволит вам написать многократно используемую роль, которую можно использовать в других частях вашей инфраструктуры.

Код для этой статьи доступен на GitHub.

Попробовали сделать по этой инструкции? Получилось развертывание веб-сайта?

Подробнее об Ansible читай в предыдущей статье

Попробуй бесплатно наши курсы по Linux и devOPS на:yodo.im/start

Оригинал статьи тут