Как развернуть HTML-сайт на Nginx через Ansible

Ansible – это современный инструмент управления конфигурацией. Для связи и выполнения команд на управляемых серверах (нодах) он использует только SSH и Python – то есть вам не нужно устанавливать агентское программное обеспечение на удаленные ноды. В этой серии мануалов вы познакомитесь с основными функциями Ansible, которые можно использовать для написания сценариев автоматизации серверов. В конце серии вы найдете практический пример плейбука для автоматизации настройки удаленного веб-сервера Nginx и развертывания на нем статического HTML-сайта.

Примечание: Этот мануал является частью серии по работе с Ansible. Другие мануалы из этой серии вы найдете по тегу ansible-practice. Весь код можно найти в этом репозитории.

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

Давайте подготовим рабочую среду. Начнем с создания нового каталога на главной ноде Ansible (в этом каталоге вы настроите файлы Ansible и наш тестовый статический HTML-сайт, который мы позже развернем на удаленном сервере). Это может быть любое место в вашей домашней папке. В нашем примере мы будем использовать ~/ansible-nginx-demo.

mkdir ~/ansible-nginx-demo
cd ~/ansible-nginx-demo

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

cp ~/ansible-practice/inventory .

Это скопирует файл по имени inventory из папки ansible-practice и сохранит его в текущем каталоге.

Создание тестового веб-сайта

В качестве демонстрации мы будем использовать статический веб-сайт HTML, который мы создали в серии статей Создание сайта на HTML. Чтобы загрузить файлы этого сайта, выполните следующую команду:

curl -L https://github.com/do-community/html_demo_site/archive/refs/heads/main.zip -o html_demo.zip

Затем вам нужно будет распаковать содержимое этого архива. Чтобы убедиться, что инструмент unzip установлен, запустите:

sudo apt install unzip

Затем распакуйте файлы тестового веб-сайта с помощью такой команды:

unzip html_demo.zip

Это создаст в вашем текущем рабочем каталоге новый каталог html_demo_site-main. Вы можете проверить содержимое каталога с помощью команды ls -la:

ls -la html_demo_site-main

Результат будет выглядеть так:

total 28
drwxrwxr-x 3 8host 8host 4096 sep 18  2020 .
drwxrwxr-x 5 8host 8host 4096 mrt 25 15:03 ..
-rw-rw-r-- 1 8host 8host 1289 sep 18  2020 about.html
drwxrwxr-x 2 8host 8host 4096 sep 18  2020 images
-rw-rw-r-- 1 8host 8host 2455 sep 18  2020 index.html
-rw-rw-r-- 1 8host 8host 1079 sep 18  2020 LICENSE
-rw-rw-r-- 1 8host 8host  675 sep 18  2020 README.md

Создание шаблона для конфигурации Nginx

Пора создать шаблон Nginx, необходимый для настройки удаленного веб-сервера. Создайте в каталоге ansible-demo новую папку для хранения файлов, не относящихся к плейбуку:

mkdir files

Затем откройте новый файл nginx.conf.j2:

nano files/nginx.conf.j2

Этот файл шаблона содержит конфигурацию блока server Nginx для нашего статического HTML-сайта. Он использует три переменные: document_root, app_root и server_name. Мы определим эти переменные позже, при создании плейбука. Скопируйте и вставьте в файл шаблона следующее содержимое:

server {
  listen 80;

  root {{ document_root }}/{{ app_root }};
  index index.html index.htm;

  server_name {{ server_name }};

  location / {
   default_type "text/html";
   try_files $uri.html $uri $uri/ =404;
  }
}

Сохраните и закройте файл.

Создание нового плейбука Ansible

Затем мы создадим новый плейбук Ansible и настроим переменные, которые мы использовали в предыдущем разделе этого руководства. Откройте новый файл playbook.yml:

nano playbook.yml

Эта книга начинается с определения hosts со значением all и директивы become, которая сообщает Ansible по умолчанию запускать все задачи от имени пользователя root (то же самое, что и вручную запускать команды через sudo). В разделе var этого сценария мы создадим три переменные: server_name, document_root и app_root. Эти переменные используются в шаблоне конфигурации Nginx для настройки домена или IP-адреса, на который будет отвечать этот веб-сервер, а также для указания полного пути к расположению файлов сайта на сервере. В этом примере мы будем использовать переменную ansible_default_ipv4.address, потому что она содержит общедоступный IP-адрес удаленного сервера (но вы, конечно, можете заменить это значение именем хоста вашего сервера, если у него есть доменное имя, правильно настроенное в DNS):

---
- hosts: all
  become: yes
  vars:
    server_name: "{{ ansible_default_ipv4.address }}"
    document_root: /var/www/html
    app_root: html_demo_site-main
  tasks:

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

Установка необходимых пакетов

Следующая задача обновит кеш apt, а затем установит пакет nginx на удаленные ноды:

. . .
    - name: Update apt cache and install Nginx
      apt:
        name: nginx
        state: latest
        update_cache: yes

Выгрузка файлов веб-сайта на удаленные ноды

Следующая задача будет использовать встроенный модуль copy для загрузки файлов веб-сайта в корневой каталог удаленных нод. Мы будем использовать переменную document_root, чтобы установить на сервере место назначения, где должна быть создана папка для приложения.

. . .
    - name: Copy website files to the server's document root
      copy:
        src: "{{ app_root }}"
        dest: "{{ document_root }}"
        mode: preserve

Включение пользовательской конфигурации Nginx

Теперь давайте применим шаблон Nginx, который настроит веб-сервер для обслуживания вашего статического HTML-файла. После того, как конфигурационный файл будет установлен в каталог etc/nginx/sites-available, мы создадим символическую ссылку на этот файл внутри /etc/nginx-sites-enabled и уведомим сервис Nginx о последующем перезапуске. Для всего процесса потребуются две отдельные задачи. Вот как они выглядят:

. . .
    - name: Apply Nginx template
      template:
        src: files/nginx.conf.j2
        dest: /etc/nginx/sites-available/default
      notify: Restart Nginx

    - name: Enable new site
      file:
        src: /etc/nginx/sites-available/default
        dest: /etc/nginx/sites-enabled/default
        state: link
      notify: Restart Nginx

Открытие порта 80 в брандмауэре UFW

Затем включите задачу, которая открывает доступ TCP через порт 80:

. . .
    - name: Allow all access to tcp port 80
      ufw:
        rule: allow
        port: '80'
        proto: tcp
. . .

Создание обработчика для сервиса Nginx

Нам осталось только настроить обработчик Restart Nginx:

. . .
  handlers:
    - name: Restart Nginx
      service:
        name: nginx
        state: restarted

Запуск готового плейбука

Когда вы запишете все необходимые задачи в файл плейбука, он будет выглядеть так:

---
- hosts: all
  become: yes
  vars:
    server_name: "{{ ansible_default_ipv4.address }}"
    document_root: /var/www
    app_root: html_demo_site-main
  tasks:
    - name: Update apt cache and install Nginx
      apt:
        name: nginx
        state: latest
        update_cache: yes

    - name: Copy website files to the server's document root
      copy:
        src: "{{ app_root }}"
        dest: "{{ document_root }}"
        mode: preserve

    - name: Apply Nginx template
      template:
        src: files/nginx.conf.j2
        dest: /etc/nginx/sites-available/default
      notify: Restart Nginx

    - name: Enable new site
      file:
        src: /etc/nginx/sites-available/default
        dest: /etc/nginx/sites-enabled/default
        state: link
      notify: Restart Nginx

    - name: Allow all access to tcp port 80
      ufw:
        rule: allow
        port: '80'
        proto: tcp

  handlers:
    - name: Restart Nginx
      service:
        name: nginx
        state: restarted

Чтобы выполнить этот плейбук на серверах, которые вы настроили в файле инвентаря, запустите команду ansible-playbook с теми же аргументами подключения, которые вы использовали при запуске тестового подключения (в начале этой серии). Здесь для подключения к удаленному серверу мы будем использовать файл инвентаризации по имени inventory и пользователя 8host. Поскольку для запуска плейбука требуется команда sudo, мы также включим аргумент –K. Вот команда, которую нужно запустить:

ansible-playbook -i inventory playbook.yml -u 8host -K

Вы увидите такой результат:

BECOME password:

PLAY [all] **********************************************************************************************

TASK [Gathering Facts] **********************************************************************************
ok: [203.0.113.10]

TASK [Update apt cache and install Nginx] ***************************************************************
ok: [203.0.113.10]

TASK [Copy website files to the server's document root] *************************************************
changed: [203.0.113.10]

TASK [Apply Nginx template] *****************************************************************************
changed: [203.0.113.10]

TASK [Enable new site] **********************************************************************************
ok: [203.0.113.10]

TASK [Allow all access to tcp port 80] ******************************************************************
ok: [203.0.113.10]

RUNNING HANDLER [Restart Nginx] *************************************************************************
changed: [203.0.113.10]

PLAY RECAP **********************************************************************************************
203.0.113.10                : ok=7    changed=3    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

Когда плейбук будет выполнен, откройте браузер и запросите имя хоста или IP-адрес вашего сервера. На странице появится ваш простой сайт.

Поздравляем, вы успешно автоматизировали развертывание статического веб-сайта HTML на удаленном сервере Nginx с помощью Ansible.

Если вы внесете изменения в любой из файлов тестового веб-сайта, попробуйте перезапустить плейбук: задача copy отразит любые изменения файлов на удаленном хосте. Поскольку Ansible имеет идемпотентное поведение, многократный запуск плейбука не вызовет никаких изменений, если все они уже были внесены в систему ранее.

Tags: , ,

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