fbpx
devopslinux
103

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

5
(1)

Развертывание статического веб-сайта с помощью 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

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

Насколько публикация полезна?

Нажмите на звезду, чтобы оценить!

Средняя оценка 5 / 5. Количество оценок: 1

Оценок пока нет. Поставьте оценку первым.

Сожалеем, что вы поставили низкую оценку!

Позвольте нам стать лучше!

Расскажите, как нам стать лучше?

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

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Заполните поле
Заполните поле
Пожалуйста, введите корректный адрес email.
Вы должны согласиться с условиями для продолжения

Tags: , ,
Читают сейчас
Меню

Чат-бот, который учит Linux и DevOPS