Ansible для начинающих: автоматизация серверов с нуля

Linux 24.03.2026 ~12 мин чтения Автор: АйТи Фреш
\"Ansible

Ansible — инструмент автоматизации, который позволяет управлять десятками и сотнями серверов из одной точки. В отличие от Chef и Puppet, Ansible не требует установки агентов на управляемые хосты — всё работает через SSH. В этом руководстве разберём Ansible с нуля: от установки до написания полноценных плейбуков и ролей.

Зачем сисадмину Ansible

Если вы до сих пор настраиваете серверы вручную, подключаясь к каждому по SSH, Ansible изменит ваш рабочий процесс кардинально:

Совет: Начните с автоматизации рутинных задач: обновление пакетов, создание пользователей, настройка SSH. Даже простой плейбук из 10 строк сэкономит часы работы при управлении 5+ серверами.

Установка Ansible

Ansible устанавливается только на управляющую машину (control node). На целевые серверы ничего ставить не нужно — только Python 3 и SSH-доступ.

Установка на Ubuntu/Debian

# Установка через apt (стабильная версия)
sudo apt update
sudo apt install -y ansible

# Или через pip (последняя версия)
pip3 install ansible

# Проверка версии
ansible --version

Установка на CentOS/RHEL

# RHEL/CentOS 8+
sudo dnf install -y epel-release
sudo dnf install -y ansible-core

# Или через pip
pip3 install ansible

Настройка SSH-ключей

Ansible подключается к серверам по SSH. Настроим ключевую аутентификацию:

# Генерация SSH-ключа (если ещё нет)
ssh-keygen -t ed25519 -C "ansible-control"

# Копирование ключа на управляемые серверы
ssh-copy-id user@server1.example.com
ssh-copy-id user@server2.example.com

# Проверка подключения
ssh user@server1.example.com hostname

Инвентарь (Inventory) — список серверов

Инвентарь — файл, описывающий серверы, которыми управляет Ansible. Это первое, что нужно создать.

Формат INI (классический)

# inventory/hosts.ini

# Веб-серверы
[web]
web1 ansible_host=192.168.1.10
web2 ansible_host=192.168.1.11

# Серверы баз данных
[db]
db1 ansible_host=192.168.1.20

# Мониторинг
[monitoring]
mon1 ansible_host=192.168.1.30

# Переменные для всех хостов
[all:vars]
ansible_user=deploy
ansible_python_interpreter=/usr/bin/python3

# Группа «production» объединяет web и db
[production:children]
web
db

Формат YAML (современный)

# inventory/hosts.yml
all:
  vars:
    ansible_user: deploy
    ansible_python_interpreter: /usr/bin/python3
  children:
    web:
      hosts:
        web1:
          ansible_host: 192.168.1.10
        web2:
          ansible_host: 192.168.1.11
    db:
      hosts:
        db1:
          ansible_host: 192.168.1.20
    monitoring:
      hosts:
        mon1:
          ansible_host: 192.168.1.30

Ad-hoc команды — быстрое выполнение

Прежде чем писать плейбуки, познакомимся с ad-hoc командами — одноразовыми операциями через командную строку:

# Проверка доступности всех серверов
ansible all -i inventory/hosts.ini -m ping

# Выполнить команду на группе web
ansible web -i inventory/hosts.ini -m shell -a "uptime"

# Узнать версию ОС
ansible all -i inventory/hosts.ini -m shell -a "cat /etc/os-release | head -3"

# Скопировать файл на все серверы
ansible all -i inventory/hosts.ini -m copy -a "src=./motd.txt dest=/etc/motd"

# Установить пакет на группу web
ansible web -i inventory/hosts.ini -m apt -a "name=nginx state=present" --become
Совет: Флаг --become (или -b) выполняет команду с правами sudo. Если нужен пароль sudo, добавьте --ask-become-pass.

Основные модули Ansible

Модули — это строительные блоки Ansible. Каждый модуль отвечает за конкретную задачу:

Управление пакетами

# apt — для Debian/Ubuntu
- name: Установить nginx
  apt:
    name: nginx
    state: present
    update_cache: yes

# dnf/yum — для RHEL/CentOS
- name: Установить httpd
  dnf:
    name: httpd
    state: present

# package — универсальный (определяет менеджер автоматически)
- name: Установить git
  package:
    name: git
    state: present

Управление файлами

# copy — копирование файлов
- name: Скопировать конфигурацию nginx
  copy:
    src: files/nginx.conf
    dest: /etc/nginx/nginx.conf
    owner: root
    group: root
    mode: '0644'

# template — файл с переменными Jinja2
- name: Настроить виртуальный хост
  template:
    src: templates/vhost.conf.j2
    dest: /etc/nginx/sites-available/mysite.conf

# file — создание директорий и симлинков
- name: Создать директорию для логов
  file:
    path: /var/log/myapp
    state: directory
    owner: www-data
    mode: '0755'

Управление сервисами

# systemd/service — управление демонами
- name: Запустить и включить nginx
  systemd:
    name: nginx
    state: started
    enabled: yes

- name: Перезагрузить nginx
  systemd:
    name: nginx
    state: reloaded

Управление пользователями

# user — создание и настройка пользователей
- name: Создать пользователя deploy
  user:
    name: deploy
    groups: sudo,docker
    shell: /bin/bash
    create_home: yes
    generate_ssh_key: yes

# authorized_key — SSH-ключи
- name: Добавить SSH-ключ
  authorized_key:
    user: deploy
    key: "{{ lookup('file', 'files/deploy.pub') }}"

Плейбуки (Playbooks) — сценарии автоматизации

Плейбук — YAML-файл с набором задач, выполняемых на определённых хостах. Это основной инструмент работы с Ansible.

Первый плейбук: настройка веб-сервера

# playbooks/webserver.yml
---
- name: Настройка веб-серверов
  hosts: web
  become: yes

  vars:
    http_port: 80
    server_name: example.com

  tasks:
    - name: Обновить кэш пакетов
      apt:
        update_cache: yes
        cache_valid_time: 3600

    - name: Установить необходимые пакеты
      apt:
        name:
          - nginx
          - curl
          - htop
          - ufw
        state: present

    - name: Скопировать конфигурацию nginx
      template:
        src: templates/nginx-site.conf.j2
        dest: /etc/nginx/sites-available/default
      notify: restart nginx

    - name: Настроить firewall
      ufw:
        rule: allow
        port: "{{ item }}"
        proto: tcp
      loop:
        - "22"
        - "80"
        - "443"

    - name: Включить firewall
      ufw:
        state: enabled
        policy: deny

  handlers:
    - name: restart nginx
      systemd:
        name: nginx
        state: restarted

Запуск плейбука:

# Запуск
ansible-playbook -i inventory/hosts.ini playbooks/webserver.yml

# Проверка без применения (dry-run)
ansible-playbook -i inventory/hosts.ini playbooks/webserver.yml --check

# С подробным выводом
ansible-playbook -i inventory/hosts.ini playbooks/webserver.yml -v

Переменные и шаблоны Jinja2

Сила Ansible — в системе переменных и шаблонизации. Вместо статических конфигов вы генерируете их динамически.

Иерархия переменных

# Структура каталогов для переменных
project/
├── inventory/
│   ├── hosts.ini
│   ├── group_vars/
│   │   ├── all.yml      # переменные для всех хостов
│   │   ├── web.yml      # переменные для группы web
│   │   └── db.yml       # переменные для группы db
│   └── host_vars/
│       ├── web1.yml     # переменные для конкретного хоста
│       └── db1.yml
└── playbooks/
# inventory/group_vars/web.yml
---
nginx_worker_processes: auto
nginx_worker_connections: 1024
app_port: 8080
ssl_enabled: true

Шаблоны Jinja2

Шаблоны позволяют генерировать конфигурационные файлы с учётом переменных хоста:

# templates/nginx-site.conf.j2
server {
    listen {{ http_port }};
    server_name {{ server_name }};

    worker_processes {{ nginx_worker_processes }};

    location / {
        proxy_pass http://127.0.0.1:{{ app_port }};
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
    }

{% if ssl_enabled %}
    listen 443 ssl;
    ssl_certificate /etc/letsencrypt/live/{{ server_name }}/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/{{ server_name }}/privkey.pem;
{% endif %}
}
Совет: Используйте ansible_hostname, ansible_default_ipv4.address и другие факты (facts) в шаблонах. Полный список фактов: ansible all -m setup.

Роли (Roles) — переиспользуемые модули

Роли — способ организации плейбуков в переиспользуемые компоненты. Каждая роль отвечает за одну задачу (nginx, postgresql, docker и т.д.).

Структура роли

# Создание роли через команду
ansible-galaxy init roles/nginx

# Результат:
roles/nginx/
├── defaults/
│   └── main.yml       # переменные по умолчанию (легко переопределить)
├── files/             # статические файлы
├── handlers/
│   └── main.yml       # обработчики (restart, reload)
├── meta/
│   └── main.yml       # зависимости от других ролей
├── tasks/
│   └── main.yml       # основные задачи
├── templates/         # Jinja2-шаблоны
└── vars/
    └── main.yml       # переменные (высокий приоритет)

Пример роли: установка Docker

# roles/docker/tasks/main.yml
---
- name: Установить зависимости
  apt:
    name:
      - apt-transport-https
      - ca-certificates
      - curl
      - gnupg
    state: present

- name: Добавить GPG-ключ Docker
  apt_key:
    url: https://download.docker.com/linux/{{ ansible_distribution | lower }}/gpg
    state: present

- name: Добавить репозиторий Docker
  apt_repository:
    repo: "deb https://download.docker.com/linux/{{ ansible_distribution | lower }} {{ ansible_distribution_release }} stable"
    state: present

- name: Установить Docker
  apt:
    name:
      - docker-ce
      - docker-ce-cli
      - containerd.io
      - docker-compose-plugin
    state: present
    update_cache: yes

- name: Добавить пользователя в группу docker
  user:
    name: "{{ ansible_user }}"
    groups: docker
    append: yes

- name: Запустить Docker
  systemd:
    name: docker
    state: started
    enabled: yes

Использование ролей в плейбуке

# playbooks/setup-servers.yml
---
- name: Базовая настройка всех серверов
  hosts: all
  become: yes
  roles:
    - common
    - docker
    - monitoring

- name: Настройка веб-серверов
  hosts: web
  become: yes
  roles:
    - nginx
    - certbot

Ansible Galaxy — готовые роли

Ansible Galaxy — реестр готовых ролей от сообщества. Зачем писать с нуля, если можно использовать проверенные решения:

# Установка роли из Galaxy
ansible-galaxy install geerlingguy.docker
ansible-galaxy install geerlingguy.nginx
ansible-galaxy install geerlingguy.postgresql

# Установка из файла requirements
# requirements.yml
---
roles:
  - name: geerlingguy.docker
    version: "6.1.0"
  - name: geerlingguy.nginx
  - name: geerlingguy.certbot

ansible-galaxy install -r requirements.yml

Обработка ошибок и условия

Условное выполнение (when)

- name: Установить пакет только на Ubuntu
  apt:
    name: ubuntu-specific-package
  when: ansible_distribution == "Ubuntu"

- name: Перезагрузить если ядро обновилось
  reboot:
    msg: "Kernel updated, rebooting"
  when: reboot_required.stat.exists

Обработка ошибок

- name: Проверить доступность сервиса
  uri:
    url: http://localhost:8080/health
  register: health_check
  ignore_errors: yes

- name: Откатить если сервис недоступен
  shell: /opt/app/rollback.sh
  when: health_check.failed

Блоки с обработкой ошибок

- name: Обновление приложения
  block:
    - name: Скачать новую версию
      get_url:
        url: "https://releases.example.com/app-{{ app_version }}.tar.gz"
        dest: /tmp/app.tar.gz

    - name: Развернуть
      unarchive:
        src: /tmp/app.tar.gz
        dest: /opt/app/
        remote_src: yes

  rescue:
    - name: Откатить при ошибке
      shell: /opt/app/rollback.sh

    - name: Отправить уведомление
      mail:
        to: admin@example.com
        subject: "Deploy failed on {{ inventory_hostname }}"
        body: "Deployment of version {{ app_version }} failed"

  always:
    - name: Очистить tmp
      file:
        path: /tmp/app.tar.gz
        state: absent

Ansible Vault — шифрование секретов

Пароли и ключи не должны храниться в открытом виде. Ansible Vault шифрует файлы и переменные:

# Создать зашифрованный файл
ansible-vault create secrets.yml

# Зашифровать существующий файл
ansible-vault encrypt group_vars/db.yml

# Редактировать зашифрованный файл
ansible-vault edit secrets.yml

# Запуск плейбука с vault
ansible-playbook site.yml --ask-vault-pass

# Или с файлом пароля
ansible-playbook site.yml --vault-password-file ~/.vault_pass
Важно: Файл .vault_pass обязательно добавьте в .gitignore! Никогда не коммитьте пароль от Vault в репозиторий.

Практический пример: полная настройка сервера

Соберём всё вместе в реальном сценарии — настройка нового Debian-сервера с нуля:

# playbooks/initial-setup.yml
---
- name: Первичная настройка Debian-сервера
  hosts: new_servers
  become: yes

  vars:
    admin_user: deploy
    ssh_port: 22
    allowed_ssh_keys:
      - "ssh-ed25519 AAAAC3... admin@workstation"

  tasks:
    - name: Обновить все пакеты
      apt:
        upgrade: dist
        update_cache: yes

    - name: Установить базовые утилиты
      apt:
        name:
          - vim
          - htop
          - tmux
          - curl
          - wget
          - git
          - ufw
          - fail2ban
          - unattended-upgrades
        state: present

    - name: Создать пользователя admin
      user:
        name: "{{ admin_user }}"
        groups: sudo
        shell: /bin/bash
        create_home: yes

    - name: Настроить SSH-ключи
      authorized_key:
        user: "{{ admin_user }}"
        key: "{{ item }}"
      loop: "{{ allowed_ssh_keys }}"

    - name: Запретить вход root по SSH
      lineinfile:
        path: /etc/ssh/sshd_config
        regexp: '^PermitRootLogin'
        line: 'PermitRootLogin no'
      notify: restart sshd

    - name: Запретить вход по паролю
      lineinfile:
        path: /etc/ssh/sshd_config
        regexp: '^PasswordAuthentication'
        line: 'PasswordAuthentication no'
      notify: restart sshd

    - name: Настроить UFW — SSH
      ufw:
        rule: allow
        port: "{{ ssh_port }}"
        proto: tcp

    - name: Включить UFW
      ufw:
        state: enabled
        policy: deny

    - name: Настроить автообновления безопасности
      copy:
        dest: /etc/apt/apt.conf.d/50unattended-upgrades
        content: |
          Unattended-Upgrade::Allowed-Origins {
              "${distro_id}:${distro_codename}-security";
          };
          Unattended-Upgrade::AutoFixInterruptedDpkg "true";
          Unattended-Upgrade::Remove-Unused-Dependencies "true";

    - name: Настроить часовой пояс
      timezone:
        name: Europe/Moscow

  handlers:
    - name: restart sshd
      systemd:
        name: sshd
        state: restarted

Полезные команды и приёмы

# Список всех хостов в инвентаре
ansible-inventory -i inventory/hosts.ini --list

# Собрать факты о конкретном хосте
ansible web1 -i inventory/hosts.ini -m setup

# Запустить плейбук на конкретном хосте
ansible-playbook site.yml --limit web1

# Запустить с определённого таска
ansible-playbook site.yml --start-at-task="Установить nginx"

# Показать список тасков без выполнения
ansible-playbook site.yml --list-tasks

# Проверка синтаксиса
ansible-playbook site.yml --syntax-check

# Ansible lint — проверка стиля
pip install ansible-lint
ansible-lint playbooks/

Итоги

Ansible — незаменимый инструмент для системного администратора, управляющего более чем одним сервером. Мы разобрали все ключевые компоненты: инвентарь, модули, плейбуки, роли, шаблоны и Vault.

Рекомендации для старта:

Часто задаваемые вопросы (FAQ)

Нужно ли устанавливать агент Ansible на серверы?

Нет, Ansible работает без агентов (agentless). Управление происходит через SSH. На целевых серверах нужны только Python 3 и SSH-доступ, которые есть в любом Linux-дистрибутиве по умолчанию.

Чем Ansible отличается от Chef и Puppet?

Ansible не требует агентов, использует простой YAML-синтаксис и работает по модели push (запускается с управляющей машины). Chef и Puppet используют pull-модель с агентами и более сложные DSL. Ansible проще в освоении.

Можно ли управлять Windows-серверами через Ansible?

Да, Ansible поддерживает Windows через WinRM или SSH. Для Windows есть модули win_package, win_service, win_feature и другие. Управляющая машина должна быть Linux или macOS.

Как тестировать плейбуки Ansible?

Используйте Molecule для модульного тестирования ролей, Vagrant для создания тестовых ВМ, флаг --check для dry-run, и ansible-lint для проверки стиля и best practices.

Сколько серверов может управлять Ansible?

Ansible может управлять тысячами серверов. Для ускорения используйте параллельное выполнение (forks), pipelining и strategy=free. Для очень больших инфраструктур есть Ansible AWX/Tower.

Как хранить пароли и секреты в Ansible?

Используйте Ansible Vault для шифрования файлов с секретами. Vault использует AES-256 шифрование. Файл с паролем Vault никогда не коммитится в Git — добавьте его в .gitignore.

IT-аутсорсинг для бизнеса

Нужна помощь с настройкой серверов и IT-инфраструктуры?

Компания АйТи Фреш — профессиональный IT-аутсорсинг в Москве и регионах. Настроим, защитим и будем поддерживать вашу инфраструктуру 24/7.

10+лет опыта
500+клиентов
24/7поддержка