Урок 6 из 8 · 20 мин · обновлено

Инфраструктура как код: Ansible

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

Серверы-снежинки

Сервер «Чайной лавки» настраивали три года разные люди: кто-то поставил пакет, кто-то поменял настройку, кто-то «временно» отключил проверку. Никто не помнит, что там точно сделано. Если сервер сломается, повторить его будет очень трудно — как снежинку, которая существует в единственном экземпляре.

Инфраструктура как код (Infrastructure as Code, IaC) решает это: всё, что нужно серверу, описывается в файлах. Файлы хранятся в Git, изменения проходят проверку, как обычный код, а новый сервер настраивается по описанию за минуты.

Ansible

Ansible — один из самых популярных инструментов для настройки серверов. Он подключается к ним по SSH и приводит к описанному состоянию. Ставить на серверы ничего не нужно.

Сначала описывают, какие серверы есть, — в файле инвентаря:

YAML
all:
  children:
    web:
      hosts:
        shop-1:
          ansible_host: 203.0.113.25
        shop-2:
          ansible_host: 203.0.113.26

Затем — что на них должно быть, в плейбуке:

YAML
- name: Настроить веб-серверы «Чайной лавки»
  hosts: web
  become: true
  tasks:
    - name: Установить nginx и Docker
      ansible.builtin.apt:
        name:
          - nginx
          - docker.io
        state: present
        update_cache: true

    - name: Скопировать настройки сайта
      ansible.builtin.copy:
        src: files/shop.conf
        dest: /etc/nginx/sites-enabled/shop.conf
      notify: Перезапустить nginx

    - name: Запретить вход по паролю
      ansible.builtin.lineinfile:
        path: /etc/ssh/sshd_config
        regexp: '^#?PasswordAuthentication'
        line: 'PasswordAuthentication no'
      notify: Перезапустить ssh

  handlers:
    - name: Перезапустить nginx
      ansible.builtin.service:
        name: nginx
        state: restarted

    - name: Перезапустить ssh
      ansible.builtin.service:
        name: ssh
        state: restarted

Запуск:

Терминал
ansible-playbook -i inventory.yaml site.yaml
Результат
PLAY RECAP
shop-1  : ok=4  changed=3  unreachable=0  failed=0
shop-2  : ok=4  changed=3  unreachable=0  failed=0

Оба сервера настроены одинаково. Обратите внимание: в плейбуке написано не «выполни команду установки», а «nginx должен быть установлен» (state: present). Ansible сам проверит, нужно ли что-то делать.

Идемпотентность

Если запустить тот же плейбук ещё раз, результат будет таким:

Результат
shop-1  : ok=4  changed=0  unreachable=0  failed=0

changed=0 — ничего не поменялось, потому что всё уже в нужном состоянии. Это свойство называют идемпотентностью: повторный запуск безопасен. Поэтому плейбук можно запускать регулярно — он вернёт на место всё, что кто-то поменял руками.

Создание серверов

Ansible настраивает уже существующие серверы. Создавать сами серверы, сети и базы данных в облаке удобнее другими инструментами — например, Terraform или его открытым аналогом OpenTofu. Принцип тот же: описание в файлах, история в Git, повторяемость. Часто их используют вместе: один создаёт серверы, другой настраивает.

Попробуйте сами. Добавьте в плейбук «Чайной лавки» задачу, которая создаёт на всех веб-серверах пользователя deploy для автоматической выкладки. Подсказка: модуль называется ansible.builtin.user.

Пример ответа
YAML
    - name: Создать пользователя для выкладки
      ansible.builtin.user:
        name: deploy
        shell: /bin/bash
        groups: docker
        append: true
        state: present

groups: docker даёт пользователю право запускать контейнеры, а append: true добавляет группу, не удаляя другие. Повторный запуск не создаст второго пользователя — задача идемпотентна.

Мини-тест · 4 вопроса

Проверьте себя

Выберите вариант, который кажется вам правильным. В конце вы увидите свой результат и объяснение к каждому вопросу.

  1. Что такое инфраструктура как код?

  2. Чем опасен сервер, который годами настраивали вручную?

  3. Что значит «задача идемпотентна»?

  4. Как Ansible подключается к серверам?