Ansible с нуля: inventory, первый playbook и идемпотентная настройка Linux-серверов

Ansible playbook централизованно настраивает группу Linux-серверов

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

Среда: управляющая Ubuntu 24.04 и новая учебная Ubuntu VM с SSH и sudo. Конфигурация Nginx на VM будет заменена учебной: не выполняйте этот playbook на сервере с существующими сайтами. Используйте собственную VM в частной сети. Адрес 192.0.2.20 в примере заменяется её настоящим IP.

1. Проверьте транспорт до Ansible

На управляющей машине:

sudo apt update
sudo apt install ansible openssh-client
ansible --version
ssh deploy@192.0.2.20
sudo -v
exit

Пользователь deploy должен существовать на VM. Проверка sudo -v выполняется внутри SSH-сеанса и подтверждает возможность повышения прав. При первом подключении проверьте отпечаток ключа хоста через консоль VM. Если SSH вручную не работает, запуск Ansible не исправит сеть, пользователя или ключ.

Где разместить проект

Для сайтов, ботов и pet-проектов можно использовать Beget: виртуальный хостинг от 420 ₽/мес., VPS от 330 ₽/мес. и тестовый период.

Перейти на Beget →

Пароль sudo можно запрашивать интерактивно через --ask-become-pass. Не записывайте его в inventory. В лаборатории допустим обычный пользователь с sudo; в команде границы прав и способ их предоставления согласуются отдельно.

2. Создайте структуру и inventory

ansible-lab/
  inventory.ini
  site.yml
  templates/
    nginx.conf.j2
    index.html.j2

Файл inventory.ini:

[web]
lab-web ansible_host=192.0.2.20 ansible_user=deploy

[web:vars]
ansible_python_interpreter=/usr/bin/python3

lab-web — логическое имя узла, ansible_host — реальный адрес. Выполните из каталога проекта:

ansible-inventory -i inventory.ini --graph
ansible web -i inventory.ini -m ansible.builtin.ping

Ожидайте группу web и ответ pong. Это проверка SSH и исполнения Python-модуля, не ICMP. Для обычного Ubuntu образа Python 3 уже установлен; если его нет, установите через консоль VM до упражнений с модулями.

3. Подготовьте реальный конфигурационный шаблон

Файл templates/nginx.conf.j2 содержит весь учебный конфиг, поэтому команда проверки может проверить его независимо от текущего файла:

user www-data;
worker_processes auto;
pid /run/nginx.pid;
error_log /var/log/nginx/error.log;
events { worker_connections 256; }
http {
    include /etc/nginx/mime.types;
    default_type application/octet-stream;
    server {
        listen {{ http_port }};
        server_name _;
        root /var/www/devops-lab;
        location / { try_files $uri $uri/ =404; }
    }
}

Файл templates/index.html.j2:

<!doctype html>
<html lang="ru">
<meta charset="utf-8">
<title>Ansible lab</title>
<h1>{{ site_message }}</h1>
<p>Host: {{ inventory_hostname }}</p>
</html>

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

4. Напишите playbook с проверкой результата

Полный site.yml:

---
- name: Configure an isolated Nginx lab
  hosts: web
  become: true
  serial: 1
  vars:
    http_port: 8081
    site_message: 'Hello from Ansible'
  tasks:
    - name: Install Nginx
      ansible.builtin.apt:
        name: nginx
        state: present
        update_cache: true
        cache_valid_time: 3600
    - name: Create document root
      ansible.builtin.file:
        path: /var/www/devops-lab
        state: directory
        owner: www-data
        group: www-data
        mode: '0755'
    - name: Render page
      ansible.builtin.template:
        src: templates/index.html.j2
        dest: /var/www/devops-lab/index.html
        owner: www-data
        group: www-data
        mode: '0644'
    - name: Validate and install Nginx configuration
      ansible.builtin.template:
        src: templates/nginx.conf.j2
        dest: /etc/nginx/nginx.conf
        owner: root
        group: root
        mode: '0644'
        backup: true
        validate: '/usr/sbin/nginx -t -c %s'
      notify: Reload Nginx
    - name: Ensure Nginx is running
      ansible.builtin.service:
        name: nginx
        enabled: true
        state: started
    - name: Apply pending configuration before verification
      ansible.builtin.meta: flush_handlers
    - name: Read page from the managed host
      ansible.builtin.uri:
        url: 'http://127.0.0.1:{{ http_port }}/'
        return_content: true
        status_code: 200
      register: page
      when: not ansible_check_mode
    - name: Verify expected page text
      ansible.builtin.assert:
        that:
          - site_message in page.content
      when: not ansible_check_mode
  handlers:
    - name: Reload Nginx
      ansible.builtin.service:
        name: nginx
        state: reloaded

validate подставляет временный файл на место %s. При ошибке синтаксиса новый конфиг не заменит действующий. backup: true сохраняет предыдущий файл при изменении, но не создаёт полноценную процедуру восстановления всего сервера.

Handler вызывается только после изменения конфигурации. flush_handlers запускает его до HTTP-проверки; иначе проверка могла бы проверить старую конфигурацию, а reload выполнился бы только в конце play. uri работает на управляемом узле, поэтому loopback относится к VM, не к вашему ноутбуку.

5. Запустите по этапам

ansible-playbook -i inventory.ini site.yml --syntax-check
ansible-playbook -i inventory.ini site.yml --check --diff --ask-become-pass
ansible-playbook -i inventory.ini site.yml --limit lab-web --ask-become-pass
ansible-playbook -i inventory.ini site.yml --limit lab-web --ask-become-pass

Первый реальный запуск установит пакет и файлы. Второй при неизменной среде должен завершиться без failed/unreachable и обычно с changed=0. Проверяйте конкретные tasks, если значение другое: например, истёк период cache или изменился шаблон.

Check mode на совершенно пустой VM не всегда сможет пройти шаг template: пакет Nginx ещё не установлен фактически и команда nginx -t может отсутствовать. Это ограничение предварительного моделирования зависимых шагов, а не основание отключать проверку в реальном запуске. Отдельно проверяйте diff без секретных значений.

6. Измените и намеренно сломайте конфигурацию

Замените site_message на другой текст и запустите playbook. Изменится только страница; reload для такого изменения не нужен. Затем добавьте неизвестную директиву в шаблон Nginx. Запуск должен остановиться на validate, а прежняя страница останется доступна. Уберите директиву и повторите проверку.

Так вы проверяете не только «один раз получилось», но и границу отказа. При подключении нескольких VM параметр serial: 1 обрабатывает их по одной. Сам по себе он не обеспечивает zero downtime: это зависит от балансировки, готовности приложения и того, какие изменения выполняются.

Как разбирать ошибки

  • UNREACHABLE: проверьте адрес, SSH-порт, пользователя, ключ и known_hosts обычной командой ssh.
  • Missing sudo password: используйте интерактивный --ask-become-pass либо согласованный механизм sudo.
  • Port already in use: на VM выполните sudo ss -lntp и выберите свободный учебный порт.
  • HTTP 403: проверьте права document root, наличие index.html и итоговый конфиг через sudo nginx -T.

Задание: добавьте второй учебный узел с другим site_message через host vars и докажите, что оба узла воспроизводимы. Готовая работа включает inventory без паролей, все шаблоны, вывод успешной проверки и объяснение второго запуска.

Официальные детали: template и validate, handlers, check mode.

Хотите системно изучить программирование?

Подборка онлайн-курсов для разработчиков — Python, Java, веб и DevOps.

Смотреть курсы →

Бесплатные инструменты

Калькулятор подсетей · SSH-конфиг · Nginx · Docker Compose

Бесплатное руководство «Безопасный Linux/VPS»

14 практических страниц: SSH, firewall, обновления, резервные копии, WordPress, Docker и действия при признаках взлома.

Получить PDF →

Нужен аудит или безопасная настройка Linux/VPS?

Проверим SSH, firewall, обновления, резервные копии, Docker и журналы. Аудит — от 9 900 ₽.

Узнать состав и стоимость → 8 918 532 81 08

Статья может содержать партнёрские ссылки. Это не влияет на стоимость для вас, но помогает развивать блог.