Автоматизация 50+ VPS за 10 минут: Ansible-playbook без следов

Автоматизация VPS Хостинги

Массовая настройка серверов вручную или через 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 в заголовок плейбука.

Оцените статью
autoparse.tech
Добавить комментарий