Настраивать сервер вручную — долго и утомительно. Рассказываем, как автоматизировать этот процесс с помощью Ansible. В статье всё от установки Ansible до создания базового Playbook’а для сервера с Ubuntu 24.04 + проверка результата.
Введение
Ручная настройка серверов — это медленно, неудобно и ненадёжно, а чем больше серверов нужно настроить — тем выше риск ошибок и сложнее повторять действия точно. Ansible позволяет описать желаемое состояние серверов в YAML-файле и автоматизировать его первичную настройку. Он не требует установки агентов, безопасен при повторных запусках и работает по SSH.
Рассказываем, как с помощью Ansible подготовить сервер Ubuntu 24.04: создать пользователя, настроить SSH и файрвол, обновить систему и установить нужные утилиты.
Почему именно Ansible
Ansible позволяет описать состояние сервера в виде Playbook — файла в формате YAML, где перечислены задачи, которые нужно выполнить. При этом Ansible работает идемпотентно: если вы примените один и тот же Playbook дважды, сервер не будет перенастроен заново — изменены будут только отличающиеся параметры. Это делает повторные запуски безопасными. Ansible подключается к серверам по SSH и не требует установки никаких агентов или демонов на управляемых хостах. Всё, что нужно — Python 3 на стороне сервера, а он по умолчанию есть в Ubuntu 24.04. Ещё одно ключевое преимущество — мы описываем не как достичь результата, а что должно быть в итоге. Это снижает количество ошибок и делает код читаемым даже для тех, кто не знаком с языками программирования.
Подготовка: устанавливаем Ansible на Control Node
Управляющая машина Ansible называется Control Node. Именно с неё запускаются все Playbook'и — сценарии, описывающие желаемое состояние серверов. В роли Control Node может выступать обычный ноутбук или рабочая станция с Linux, macOS или подсистема WSL2 на Windows (не всегда работает стабильно). Главное — наличие Python и SSH-клиента.
Рассмотрим установку Ansible на Ubuntu/Debian. Сначала убедимся, что система актуальна. Обновим кеш APT и уже установленные пакеты:
sudo apt update && sudo apt upgrade -y
Далее устанавливаем Ansible:
sudo apt install -y ansible
Пакет ansible включает всё необходимое: сам Ansible, его модули и зависимости.
Проверим, что всё установилось корректно:
ansible --version
Вывод будет примерно такой:
ansible [core 2.16.3]
config file = /etc/ansible/ansible.cfg
python version = 3.12.2 (default, ...)
Убедитесь, что используется Python 3.12 — именно он идёт по умолчанию в Ubuntu 24.04. Ansible полностью совместим с этой версией, так что дополнительно ничего настраивать не нужно.
Если вы работаете на macOS, установите Ansible через Homebrew:
brew install ansible
На WSL2 (например, Ubuntu внутри Windows) установка такая же, как в Linux — через apt.
На этом управляющая машина готова — можно переходить к настройке целевых хостов.
Настройка управления целевыми хостами (Managed Nodes)
Настраиваем целевой хост
Чтобы Ansible мог управлять сервером, на целевом хосте должны быть выполнены базовые требования:
- Установлен Python (в Ubuntu 24.04 он есть по умолчанию — Python 3.12).
- Запущен и доступен SSH-сервер (sshd).
- Есть пользователь с правами sudo, у которого настроен доступ по SSH-ключу от Control Node.
Если вы разворачиваете новый сервер, убедитесь, что установлен openssh-server. Для его установки:
sudo apt install -y openssh-server
Также пользователь, от имени которого Ansible будет выполнять задачи (например, deploy), должен быть добавлен в группу sudo:
sudo adduser deploy
sudo usermod -aG sudo deploy
Добавьте в ~/.ssh/authorized_keys пользователя deploy публичный ключ Control Node (~/.ssh/id_ed25519.pub или другой).
Inventory-файл: определяем хосты для управления
Ansible использует inventory-файл, чтобы знать, какими хостами управлять и как к ним подключаться. Это текстовый .ini-файл. Он может содержать группы, IP-адреса, имена хостов и переменные подключения.
Пример минимального inventory.ini с пояснениями:
[webservers]
server1 ansible_host=192.0.2.10 ansible_user=deploy ansible_ssh_private_key_file=~/.ssh/id_ed25519 ansible_python_interpreter=/usr/bin/python3
Разберём содержимое файла:
- [webservers] — имя группы. Можно использовать любую;
- server1 — условное имя хоста, также можно любое;
- ansible_host=192.0.2.10 — фактический IP-адрес или доменное имя сервера;
- ansible_user=deploy — пользователь, под которым Ansible подключается по SSH;
- ansible_ssh_private_key_file=~/.ssh/id_ed25519 — путь к приватному ключу на Control Node;
- ansible_python_interpreter=/usr/bin/python3 — явно указываем Python 3 на целевом хосте.
Проверка связи с хостом
После настройки inventory.ini проверим, что Ansible может подключиться к серверу:
ansible -i inventory.ini all -m ping
Разбор команды:
- -i inventory.ini — путь к инвентори-файлу.
- all — целевая группа хостов (в данном случае — все, что есть в inventory.ini).
- -m ping — модуль ping проверяет:
- доступность сервера по SSH,
- наличие и работоспособность Python на целевом хосте.
Если всё настроено правильно, вы увидите:
server1 | SUCCESS => {
"changed": false,
"ping": "pong"
}
Если возникают ошибки — например, Permission denied или Host unreachable — проверьте SSH-доступ, путь к ключу, пользователя и IP-адрес в inventory.ini.
Пишем первый Playbook: base_setup.yml
Playbook содержит последовательность задач, которые Ansible выполняет на целевых хостах. Создадим базовый Playbook, который подготовит сервер Ubuntu 24.04 для дальнейшей работы.
Структура base_setup.yml:
Начало файла
---
- name: Базовая настройка сервера Ubuntu 24.04
hosts: webservers
become: yes
tasks:
Здесь:
- --- — обозначает начало YAML-документа;
- - name: — заголовок плейбука;
- hosts: — группа из inventory.ini, к которой применяются задачи;
- become: yes — выполнение задач с привилегиями sudo (необходимо почти всегда);
- tasks: — список действий (задач), выполняемых на каждом хосте.
Задача 1: обновляем кеш apt
- name: Обновление списка пакетов
ansible.builtin.apt:
update_cache: yes
Задача 2: устанавливаем необходимые пакеты
- name: Установка базовых утилит
ansible.builtin.apt:
name:
- curl
- wget
- git
- ufw
- python3-pip
- software-properties-common
state: present
Здесь перечислены утилиты, которые будут установлены.
Задача 3: включаем и настраиваем UFW
- name: Разрешение SSH (порт 22)
ansible.builtin.ufw:
rule: allow
port: 22
proto: tcp
- name: Включение файрвола (UFW)
ansible.builtin.ufw:
state: enabled
policy: deny
- name: Разрешение HTTP и HTTPS
ansible.builtin.ufw:
rule: allow
port: "80,443"
proto: tcp
Задача 4: создаём пользователя deployer
Вариант 1. Генерация ключа на сервере (быстро, но не лучший по безопасности):
- name: Создание пользователя deployer
ansible.builtin.user:
name: deployer
groups: sudo
append: yes
shell: /bin/bash
password_lock: yes
generate_ssh_key: yes
ssh_key_file: /home/deployer/.ssh/id_ed25519
ssh_key_type: ed25519
state: present
Вариант 2. Копирование публичного ключа с Control Node (рекомендуется):
- name: Создание пользователя deployer
ansible.builtin.user:
name: deployer
groups: sudo
append: yes
shell: /bin/bash
password_lock: yes
state: present
- name: Добавление SSH-ключа для deployer
ansible.builtin.authorized_key:
user: deployer
state: present
key: "{{ lookup('file', '~/.ssh/id_ed25519.pub') }}"
Мы создали отдельного пользователя с минимальными админ-правами и входом только по ключу. Второй вариант с authorized_key безопаснее: вы контролируете ключи и не храните приватный на сервере.
Задача 5: повышаем безопасность SSH
- name: Запрет входа по паролю
ansible.builtin.lineinfile:
path: /etc/ssh/sshd_config
regexp: '^#?PasswordAuthentication'
line: 'PasswordAuthentication no'
- name: Запрещаем вход для root
ansible.builtin.lineinfile:
path: /etc/ssh/sshd_config
regexp: '^#?PermitRootLogin'
line: 'PermitRootLogin no'
- name: Меняем SSH-порт на 2222 (опционально)
ansible.builtin.lineinfile:
path: /etc/ssh/sshd_config
regexp: '^#?Port'
line: 'Port 2222'
Если вы меняете порт SSH:
- обновите UFW:
- name: Разрешаем новый порт SSH
ansible.builtin.ufw:
rule: allow
port: 2222
proto: tcp
- и добавьте в inventory.ini:
ansible_port=2222
Перезагружаем SSH:
- name: Перезагрузка SSH
ansible.builtin.service:
name: sshd
state: reloaded
Предпочтительно указывать reloaded, так как это не обрывает активные SSH-сессии. Не указывайте restarted, если работаете на продакшене, — вы можно потерять доступ.
Запуск Playbook и анализ результатов
Когда всё готово — inventory.ini настроен, base_setup.yml написан — запустите Playbook: Ansible применит все описанные задачи к целевым серверам.
Команда запуска:
ansible-playbook -i inventory.ini base_setup.yml
Здесь:
- -i inventory.ini — инвентори-файл с описанием управляемых хостов.
- base_setup.yml — сам Playbook.
Команда запускается с Control Node и все пути разрешаются относительно него.
Вы увидите подробный вывод в реальном времени. Ansible помечает каждую задачу одним из статусов:
- ok — задача успешно выполнена, изменений не потребовалось (состояние уже соответствует желаемому);
- changed — задача изменила состояние системы (например, установила пакет, отредактировала файл);
- failed — задача завершилась с ошибкой. Будет показано подробное сообщение об ошибке;
- skipped — задача была пропущена (например, из-за условия when:);
- unreachable — хост недоступен по SSH.
Одно из главных преимуществ Ansible — идемпотентность. Если вы запустите тот же Playbook второй раз, то большинство задач (например, создание пользователя, настройка SSH, установка UFW) получат статус ok. Это значит, что Ansible проверил текущее состояние и убедился, что ничего менять не нужно. Но есть и исключения — например, apt update всегда вызывает changed, потому что обновляется кеш пакетов.
Проверка результатов вручную:
- Подключитесь по SSH от имени нового пользователя:
ssh deployer@server_ip
- Проверьте, что пользователь создан и в нужных группах:
id deployer
- Проверьте права sudo:
sudo -l
- Посмотрите статус файрвола:
sudo ufw status
- Убедитесь в настройках SSH:
grep -iE 'password|root|port' /etc/ssh/sshd_config
Ожидаемые строки:
PasswordAuthentication no
PermitRootLogin no (или prohibit-password)
Port 22 (или 2222, если вы меняли порт)
Заключение
Ansible позволяет в считанные минуты привести сервер к желаемому состоянию, он даёт прозрачную обратную связь и гарантирует, что повторное применение не приведёт к неожиданным изменениям — всё это особенно важно при управлении десятками и сотнями серверов.
Читайте в блоге:
- Ubuntu 24.04 LTS против 22.04: стоит ли обновляться
- CI/CD на базе Ubuntu 24.04 LTS: GitHub Actions, Docker, NGINX
- Как использовать Snap и управлять Snap-приложениями в Ubuntu 24.04