Массовая настройка серверов вручную или через bash-скрипты на каждом отдельном хосте — это потеря времени и риск ошибки. Оркестрация через Ansible позволяет развернуть десятки VPS одной командой с локального компьютера.
Этот подход важен при масштабировании PBN, массовом подъеме дроп-доменов и развертывании арбитражных сеток, когда вам нужно быстро связать десятки дешевых серверов от разных хостинг-провайдеров в единую инфраструктуру.
Базовые туториалы из сети не подходят для SEO-сеток. Они устанавливают стандартный LEMP-стек, который отдает страницу «Welcome to Nginx» любому боту при обращении по IP-адресу. Ниже приведен плейбук, который устанавливает необходимое ПО и обрывает соединения при прямом запросе к серверу.
Этот скрипт разрабатывался для быстрого разворачивания окружения, описанного в нашей статье по архитектуре хостинга для PBN.
Инвентарь: подготовка списка серверов
Перед запуском плейбука укажите Ansible целевые IP-адреса. Создайте файл hosts.ini:
[webservers] 192.168.1.10 ansible_user=root domain=site1.com 192.168.1.11 ansible_user=root domain=site2.com 192.168.1.12 ansible_user=root domain=site3.com
Через переменную domain передается имя сайта. Конфигурация Nginx и Let’s Encrypt автоматически подхватит его на каждом хосте.
Готовый Playbook: LEMP, Drop connection и динамический PHP
Создайте файл deploy.yml. Этот сценарий обновляет систему, устанавливает Nginx, PHP-FPM, MariaDB, настраивает фаервол, конфигурирует виртуальный хост и отключает дефолтные ответы сервера.
Защита от краша: Скрипт не фиксирует жестко версию PHP (например, 8.1), а определяет её динамически на целевом сервере. Это гарантирует, что Nginx не остановится с ошибкой при развертывании на разных версиях ОС (Ubuntu 20.04, 22.04 или 24.04).
---
- name: Hardened LEMP Deployment
hosts: webservers
become: yes
tasks:
- name: Обновление кэша apt и системы
apt:
update_cache: yes
upgrade: dist
- name: Установка Nginx, PHP, MySQL и Certbot
apt:
name:
- nginx
- mariadb-server
- php-fpm
- php-mysql
- certbot
- python3-certbot-nginx
- ufw
state: present
- name: Определение версии PHP "на лету"
shell: php -r "echo PHP_MAJOR_VERSION.'.'.PHP_MINOR_VERSION;"
register: php_version_output
changed_when: false
- name: Блокировка прямого обращения по IP (Drop Connection)
copy:
dest: /etc/nginx/sites-available/default
content: |
server {
listen 80 default_server;
listen [::]:80 default_server;
server_name _;
return 444; # Сброс соединения без ответа
}
notify: Reload Nginx
- name: Создание конфига Nginx для домена
copy:
dest: "/etc/nginx/sites-available/{{ domain }}"
content: |
server {
listen 80;
server_name {{ domain }} www.{{ domain }};
root /var/www/{{ domain }};
index index.php index.html;
location / {
try_files $uri $uri/ /index.php?$args;
}
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/var/run/php/php{{ php_version_output.stdout }}-fpm.sock;
}
}
notify: Reload Nginx
- name: Активация домена и создание директории
file:
src: "/etc/nginx/sites-available/{{ domain }}"
dest: "/etc/nginx/sites-enabled/{{ domain }}"
state: link
- name: Создание корневой папки сайта
file:
path: "/var/www/{{ domain }}"
state: directory
owner: www-data
group: www-data
- name: Настройка фаервола UFW
ufw:
rule: allow
port: "{{ item }}"
proto: tcp
loop:
- '22'
- '80'
- '443'
- name: Выпуск SSL Let's Encrypt (Только если DNS обновлен)
command: certbot --nginx -d {{ domain }} -d www.{{ domain }} --non-interactive --agree-tos -m admin@{{ domain }}
ignore_errors: yes
handlers:
- name: Reload Nginx
service:
name: nginx
state: reloaded
Команда для запуска:
ansible-playbook -i hosts.ini deploy.yml
Модели сбоя: узлы отказа при массовом развертывании
Рассинхронизация DNS (Фатальная ошибка SSL) В задаче выпуска SSL-сертификата намеренно установлен флаг ignore_errors: yes. Если вы привязали A-записи для 50 доменов и сразу запустили плейбук, глобальный DNS не успеет обновиться. Certbot выдаст ошибку. Без этого флага плейбук завершится аварийно на первом же недоступном домене и прервет настройку остальных серверов.
Сценарий работы: Сначала разверните инфраструктуру. Дождитесь обновления DNS (обычно 2–4 часа), затем запустите плейбук повторно, используя тег для триггера исключительно задачи с Certbot.
Лимиты Let’s Encrypt API При единовременном запросе 50 сертификатов с одного управляющего IP (вашего локального ПК) Let’s Encrypt может временно заблокировать запросы за флуд. Для крупных партий разбивайте инвентарь на группы по 10–15 серверов или добавьте параметр serial: 10 в заголовок плейбука.







