Ansible для системного администратора

Ansible для системных администраторов: установка, inventory hosts, playbook, роли и модули. Автоматизация Linux, Docker и Windows серверов

У вас 30 серверов. На каждом нужно обновить конфиг nginx, перезапустить сервис и создать директорию для логов. Вы открываете терминал и начинаете ходить по SSH вручную. Через час пятый сервер отличается от первого, на восьмом вы сделали опечатку, а на четырнадцатом забыли перезапустить сервис. Классика жанра.

Ansible — это лекарство от ручного администрирования. Один YAML-файл, одна команда — и все 30 серверов настроены одинаково, воспроизводимо и без SSH-марафона. В этом гайде: установка Ansible с нуля, настройка inventory hosts, написание playbook, работа с модулями и ролями, управление Linux, Docker и Windows. Только практика, только рабочие конфиги.

Что такое Ansible и почему он завоевал мир DevOps

Ansible — система автоматизации и управления конфигурациями с открытым исходным кодом от Red Hat. Главное отличие от конкурентов (Chef, Puppet, SaltStack) — агентless-архитектура: на управляемых серверах не нужно ничего устанавливать. Ansible работает по SSH для Linux и WinRM для Windows. Всё.

Что делает Ansible в реальной жизни:

Ansible использует YAML playbook — человекочитаемые файлы-сценарии. Если вы умеете читать, вы уже почти умеете писать Ansible playbook. Это не преувеличение.

Установка Ansible: все способы

Ansible устанавливается только на управляющую машину (control node). Управляемые серверы не требуют никаких дополнительных пакетов — только SSH и Python (Python 3.8+ уже есть почти везде).

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

# Обновляем репозитории и устанавливаем
sudo apt update
sudo apt install ansible -y

# Для самой актуальной версии — через официальный PPA
sudo apt install software-properties-common -y
sudo add-apt-repository --yes --update ppa:ansible/ansible
sudo apt install ansible -y

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

# RHEL 8/9, CentOS Stream, Rocky Linux
sudo dnf install epel-release -y
sudo dnf install ansible -y

# Или напрямую через dnf (если репозиторий уже настроен)
sudo dnf install ansible-core -y

Установка через pip (универсальный способ)

# Установка последней версии через pip
pip install ansible

# Рекомендуется использовать virtualenv
python3 -m venv ansible-env
source ansible-env/bin/activate
pip install ansible

# Установка дополнительных коллекций
ansible-galaxy collection install community.general
ansible-galaxy collection install community.docker

Проверка установки

# Версия Ansible
ansible --version

# Пример вывода:
# ansible [core 2.16.0]
#   python version = 3.11.4
#   jinja version = 3.1.2

# Список установленных коллекций
ansible-galaxy collection list

Совет: используйте ansible-core + отдельные коллекции через ansible-galaxy вместо монолитного пакета ansible. Это даёт контроль над версиями и меньший размер установки.

Настройка SSH: основа всего

Ansible использует SSH для управления Linux-серверами. Настройка ключей — не опция, а необходимость. Вводить пароль при каждом запуске playbook на 50 серверах — это уже не автоматизация.

Генерация и распространение SSH-ключей

# Генерируем ключ на управляющей машине (если ещё нет)
ssh-keygen -t ed25519 -C "ansible-control" -f ~/.ssh/ansible_key

# Копируем публичный ключ на каждый управляемый сервер
ssh-copy-id -i ~/.ssh/ansible_key.pub user@192.168.1.10
ssh-copy-id -i ~/.ssh/ansible_key.pub user@192.168.1.11
ssh-copy-id -i ~/.ssh/ansible_key.pub user@192.168.1.20

# Проверяем подключение без пароля
ssh -i ~/.ssh/ansible_key user@192.168.1.10

Конфигурация Ansible для использования ключа

# Файл: ansible.cfg (в директории проекта или /etc/ansible/ansible.cfg)
[defaults]
inventory = ./inventory/hosts
remote_user = ansible
private_key_file = ~/.ssh/ansible_key
host_key_checking = False
retry_files_enabled = False
stdout_callback = yaml

[privilege_escalation]
become = True
become_method = sudo
become_user = root

Inventory hosts: реестр вашей инфраструктуры

Inventory — это список серверов, которыми управляет Ansible. Без него никуда. Файл по умолчанию: /etc/ansible/hosts, но правильный подход — держать inventory в директории проекта.

Базовый inventory в INI-формате

# Файл: inventory/hosts

[web]
192.168.1.10
192.168.1.11
web03.example.com

[db]
192.168.1.20
192.168.1.21

[monitoring]
192.168.1.30

# Группа, включающая другие группы
[production:children]
web
db
monitoring

# Переменные для группы
[web:vars]
http_port=80
nginx_worker_processes=4

[all:vars]
ansible_user=ansible
ansible_python_interpreter=/usr/bin/python3

Inventory в YAML-формате (рекомендуется для сложных проектов)

# Файл: inventory/hosts.yml
all:
  children:
    web:
      hosts:
        web01:
          ansible_host: 192.168.1.10
          nginx_port: 80
        web02:
          ansible_host: 192.168.1.11
          nginx_port: 8080
      vars:
        nginx_worker_processes: 4

    db:
      hosts:
        db01:
          ansible_host: 192.168.1.20
          postgres_version: "15"
        db02:
          ansible_host: 192.168.1.21
          postgres_version: "15"

    windows:
      hosts:
        win01:
          ansible_host: 192.168.1.50
          ansible_user: Administrator
          ansible_password: "{{ vault_win_password }}"
          ansible_connection: winrm
          ansible_winrm_transport: ntlm

Проверка inventory и связи с серверами

# Список всех хостов
ansible all --list-hosts

# Пинг всех серверов (модуль ping проверяет SSH + Python)
ansible all -m ping

# Пинг конкретной группы
ansible web -m ping

# Пинг с указанием конкретного inventory файла
ansible all -m ping -i inventory/hosts.yml

# Получить факты об одном сервере
ansible web01 -m gather_facts

Если ansible all -m ping возвращает SUCCESS для всех хостов — фундамент заложен. Можно строить дальше.

Основные Ansible модули (ansible.builtin)

Модули — это строительные блоки Ansible. Каждый модуль выполняет конкретную задачу: установить пакет, создать файл, управлять сервисом. Коллекция ansible.builtin содержит всё необходимое для повседневной работы.

Модуль Назначение Пример использования
apt / dnf / yum Управление пакетами Установка nginx, curl, git
copy Копирование файлов Деплой конфигов
template Шаблоны Jinja2 Динамические конфиги
file Управление файлами/директориями Создание папок, chmod
service Управление сервисами Start/stop/restart
command / shell Выполнение команд Произвольные команды
user / group Управление пользователями Создание системных пользователей
lineinfile Редактирование файлов Добавить строку в конфиг
git Работа с репозиториями Клонирование, обновление
uri HTTP-запросы Проверка API, вебхуки

Запуск модулей в режиме ad-hoc

# Выполнить команду на всех серверах
ansible all -a "uptime"
ansible web -a "df -h"

# Установить пакет
ansible web -m apt -a "name=curl state=present" --become

# Перезапустить сервис
ansible web -m service -a "name=nginx state=restarted" --become

# Скопировать файл
ansible web -m copy -a "src=/local/file.conf dest=/etc/nginx/file.conf" --become

# Получить информацию о файле
ansible all -m stat -a "path=/etc/passwd"

Ansible Playbook: сердце автоматизации

Ad-hoc команды хороши для разовых задач. Playbook — это когда вам нужно воспроизводимо настроить всё с нуля. Один файл, вся инфраструктура.

Структура playbook

# Файл: deploy-web.yml
---
- name: Настройка веб-серверов                  # Имя play
  hosts: web                                      # Целевая группа
  become: yes                                     # Использовать sudo
  gather_facts: yes                               # Собрать системные факты

  vars:                                           # Переменные
    nginx_version: "1.24"
    app_port: 8080
    app_dir: /opt/myapp

  pre_tasks:                                      # Задачи до основных
    - name: Обновить кеш пакетов
      apt:
        update_cache: yes
        cache_valid_time: 3600

  tasks:                                          # Основные задачи
    - name: Установить nginx
      apt:
        name: nginx
        state: present

    - name: Создать директорию приложения
      file:
        path: "{{ app_dir }}"
        state: directory
        owner: www-data
        group: www-data
        mode: '0755'

    - name: Скопировать конфиг nginx
      template:
        src: templates/nginx.conf.j2
        dest: /etc/nginx/sites-available/myapp.conf
      notify: Перезапустить nginx             # Триггер handler

    - name: Включить сайт
      file:
        src: /etc/nginx/sites-available/myapp.conf
        dest: /etc/nginx/sites-enabled/myapp.conf
        state: link
      notify: Перезапустить nginx

    - name: Убедиться, что nginx запущен и включён в автозагрузку
      service:
        name: nginx
        state: started
        enabled: yes

  handlers:                                       # Обработчики событий
    - name: Перезапустить nginx
      service:
        name: nginx
        state: restarted

  post_tasks:                                     # Задачи после основных
    - name: Проверить доступность nginx
      uri:
        url: "http://localhost:{{ app_port }}"
        status_code: 200
      ignore_errors: yes

Запуск playbook

# Базовый запуск
ansible-playbook deploy-web.yml

# Проверка синтаксиса без выполнения
ansible-playbook deploy-web.yml --syntax-check

# Dry-run: показать что изменится, но не применять
ansible-playbook deploy-web.yml --check

# Запуск с подробным выводом
ansible-playbook deploy-web.yml -v      # verbose
ansible-playbook deploy-web.yml -vvv    # очень подробно

# Запустить только на конкретном хосте из группы
ansible-playbook deploy-web.yml --limit web01

# Запустить начиная с определённой задачи
ansible-playbook deploy-web.yml --start-at-task "Скопировать конфиг nginx"

# Запустить только задачи с тегом
ansible-playbook deploy-web.yml --tags "nginx,config"

Переменные (vars) в Ansible: управление конфигурацией

Жёсткие значения в playbook — признак плохого кода. Ansible vars позволяют сделать playbook универсальным: одни задачи, разные окружения (dev/staging/prod).

Уровни приоритета переменных (от низшего к высшему)

# 1. Переменные в inventory
# inventory/hosts.yml
all:
  vars:
    env: production

# 2. Групповые переменные
# inventory/group_vars/web.yml
nginx_port: 80
nginx_worker_processes: 4

# 3. Хостовые переменные
# inventory/host_vars/web01.yml
nginx_port: 8080    # переопределяет групповую переменную

# 4. Переменные в playbook
vars:
  app_name: myapp

# 5. Внешние файлы переменных
vars_files:
  - vars/common.yml
  - vars/secrets.yml    # зашифрованный через ansible-vault

# 6. Переменные командной строки (наивысший приоритет)
ansible-playbook playbook.yml -e "env=staging app_version=2.1"

Ansible Vault: секреты под замком

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

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

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

# Запуск playbook с vault-паролем
ansible-playbook playbook.yml --ask-vault-pass
ansible-playbook playbook.yml --vault-password-file ~/.vault_pass

Никогда не храните пароли, токены и ключи в открытых YAML-файлах. Ansible Vault + Git — правильная связка. Файл .vault_pass добавляйте в .gitignore.

Модуль file: управление файлами и директориями

# Файл: tasks/files.yml
---
- name: Создать директорию для логов
  file:
    path: /var/log/myapp
    state: directory
    owner: www-data
    group: www-data
    mode: '0750'
    recurse: yes

- name: Создать пустой файл
  file:
    path: /opt/myapp/.env
    state: touch
    mode: '0600'

- name: Создать символическую ссылку
  file:
    src: /opt/myapp/current
    dest: /var/www/html
    state: link

- name: Удалить временные файлы (старше 7 дней)
  find:
    paths: /tmp/myapp
    age: 7d
    recurse: yes
  register: old_files

- name: Удалить найденные файлы
  file:
    path: "{{ item.path }}"
    state: absent
  loop: "{{ old_files.files }}"

Ansible Roles: структура для серьёзных проектов

Когда playbook разрастается до 300 строк — пора использовать roles. Роль — это стандартная структура директорий, которая делает код переиспользуемым и понятным любому члену команды.

Создание структуры роли

# Автоматически создать структуру роли
ansible-galaxy role init roles/nginx

# Созданная структура:
roles/
  nginx/
    tasks/          # основные задачи
      main.yml
    handlers/       # обработчики событий
      main.yml
    templates/      # шаблоны Jinja2 (.j2)
      nginx.conf.j2
    files/          # статические файлы
    vars/           # переменные роли (не переопределяются)
      main.yml
    defaults/       # переменные по умолчанию (переопределяются)
      main.yml
    meta/           # метаданные и зависимости
      main.yml
    README.md

Пример роли для установки и настройки nginx

# roles/nginx/defaults/main.yml
---
nginx_port: 80
nginx_worker_processes: auto
nginx_worker_connections: 1024
nginx_server_name: "{{ ansible_hostname }}"
nginx_root: /var/www/html
# roles/nginx/tasks/main.yml
---
- name: Установить nginx
  apt:
    name: nginx
    state: present
    update_cache: yes
  tags: [nginx, install]

- name: Настроить nginx из шаблона
  template:
    src: nginx.conf.j2
    dest: /etc/nginx/nginx.conf
    <a class="wpil_keyword_link" href="https://it-apteka.com/category/rezervnoe-kopirovanie/" target="_blank"  rel="noopener" title="Резервное копирование" data-wpil-keyword-link="linked"  data-wpil-monitor-id="820">backup</a>: yes
  notify: Reload nginx
  tags: [nginx, config]

- name: Настроить виртуальный хост
  template:
    src: vhost.conf.j2
    dest: &quot;/etc/nginx/sites-available/{{ nginx_server_name }}.conf&quot;
  notify: Reload nginx
  tags: [nginx, config]

- name: Включить виртуальный хост
  file:
    src: &quot;/etc/nginx/sites-available/{{ nginx_server_name }}.conf&quot;
    dest: &quot;/etc/nginx/sites-enabled/{{ nginx_server_name }}.conf&quot;
    state: link
  notify: Reload nginx

- name: Запустить nginx
  service:
    name: nginx
    state: started
    enabled: yes
  tags: [nginx, service]
# roles/nginx/handlers/main.yml
---
- name: Reload nginx
  service:
    name: nginx
    state: reloaded

- name: Restart nginx
  service:
    name: nginx
    state: restarted
# Использование роли в playbook: site.yml
---
- name: Настройка веб-серверов
  hosts: web
  become: yes

  roles:
    - role: nginx
      vars:
        nginx_port: 443
        nginx_server_name: api.example.com

    - role: certbot           # Роль для SSL
    - role: monitoring_agent  # Роль для мониторинга

Готовые роли из Ansible Galaxy

# Поиск ролей в галерее
ansible-galaxy search nginx

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

# Установка из requirements.yml (правильный путь)
# requirements.yml:
# roles:
#   - name: geerlingguy.nginx
#     version: "3.2.0"
#   - name: geerlingguy.docker
#     version: "6.4.0"

ansible-galaxy install -r requirements.yml

Jeff Geerling (geerlingguy) создал золотой стандарт Ansible-ролей. Его коллекция на Galaxy — первое место, куда стоит заглянуть перед написанием своей роли с нуля.

Ansible и Docker: управление контейнерами

Ansible отлично интегрируется с Docker через коллекцию community.docker. Это удобно, когда нужно управлять контейнерами в рамках общей инфраструктурной автоматизации.

Установка Docker через Ansible

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

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

- name: Добавить репозиторий Docker
  apt_repository:
    repo: "deb [arch=amd64] https://download.docker.com/linux/ubuntu {{ ansible_distribution_release }} stable"
    state: present

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

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

- name: Запустить и включить Docker
  service:
    name: docker
    state: started
    enabled: yes

Управление контейнерами через Ansible

# tasks/containers.yml
---
- name: Запустить nginx контейнер
  community.docker.docker_container:
    name: nginx
    image: nginx:1.25-alpine
    state: started
    restart_policy: unless-stopped
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - /opt/nginx/conf:/etc/nginx/conf.d:ro
      - /opt/nginx/html:/usr/share/nginx/html:ro
    env:
      NGINX_HOST: "{{ ansible_hostname }}"
    labels:
      traefik.enable: "true"

- name: Запустить стек через docker-compose
  community.docker.docker_compose_v2:
    project_src: /opt/myapp
    state: present
    pull: always

- name: Убедиться, что образ актуален
  community.docker.docker_image:
    name: myapp
    tag: latest
    source: pull
    force_source: yes

- name: Удалить неиспользуемые образы
  community.docker.docker_prune:
    images: yes
    images_filters:
      dangling: true

⚡ Где запускать Ansible control node?

Для production-среды Ansible control node должен быть на отдельном стабильном сервере — не на вашем ноутбуке, который периодически уходит в спячку. Сравнение актуальных VPS-провайдеров для инфраструктурных задач:

Провайдер Тариф для DevOps CPU / RAM SLA Особенности
Timeweb Cloud от 299 руб/мес 1 vCPU / 1 GB 99.95% Готовые образы Ubuntu/Debian
Selectel от 320 руб/мес 1 vCPU / 1 GB 99.95% Быстрые NVMe диски
Cloud.ru от 250 руб/мес 1 vCPU / 1 GB 99.95% Российская инфраструктура
Reg.ru от 199 руб/мес 1 vCPU / 512 MB 99.9% Простая панель управления

Для Ansible control node достаточно 1 vCPU и 1 GB RAM. Ключевые параметры: стабильный uptime, быстрая сеть до управляемых серверов, возможность создания SSH-ключей через API.


Ansible и Windows: управление через WinRM

Да, Ansible умеет управлять Windows. Вместо SSH используется WinRM (Windows Remote Management). Функциональность немного уже, чем для Linux, но для большинства задач хватает.

Настройка WinRM на Windows-сервере

# Выполнить на Windows (PowerShell от имени администратора):
# Скачать и запустить <a class="wpil_keyword_link" href="https://it-apteka.com/category/scripts/" target="_blank"  rel="noopener" title="Скрипты" data-wpil-keyword-link="linked"  data-wpil-monitor-id="819">скрипт</a> настройки WinRM
$url = &quot;https://raw.githubusercontent.com/ansible/ansible/devel/examples/scripts/ConfigureRemotingForAnsible.ps1&quot;
$file = &quot;$env:temp\ConfigureRemotingForAnsible.ps1&quot;
(New-Object -TypeName System.Net.WebClient).DownloadFile($url, $file)
powershell.exe -ExecutionPolicy ByPass -File $file

# Или вручную:
winrm quickconfig -q
winrm set winrm/config/service &#039;@{AllowUnencrypted=&quot;true&quot;}&#039;
winrm set winrm/config/service/auth &#039;@{Basic=&quot;true&quot;}&#039;

Inventory для Windows хостов

# inventory/group_vars/windows.yml
ansible_connection: winrm
ansible_winrm_transport: ntlm
ansible_winrm_server_cert_validation: ignore
ansible_port: 5985
ansible_user: Administrator
ansible_password: "{{ vault_windows_password }}"

Playbook для Windows

# windows-setup.yml
---
- name: Настройка Windows серверов
  hosts: windows
  gather_facts: yes

  tasks:
    - name: Проверить связь (Windows ping)
      ansible.windows.win_ping:

    - name: Установить программу через Chocolatey
      chocolatey.chocolatey.win_chocolatey:
        name:
          - notepadplusplus
          - 7zip
          - git
        state: present

    - name: Создать директорию
      ansible.windows.win_file:
        path: C:\Scripts\Ansible
        state: directory

    - name: Скопировать файл на Windows
      ansible.windows.win_copy:
        src: files/config.xml
        dest: C:\Scripts\Ansible\config.xml

    - name: Запустить PowerShell скрипт
      ansible.windows.win_shell: |
        Set-ExecutionPolicy RemoteSigned -Force
        C:\Scripts\setup.ps1

    - name: Управление Windows-службой
      ansible.windows.win_service:
        name: Spooler
        state: started
        start_mode: auto

    - name: Установить обновления Windows
      ansible.windows.win_updates:
        category_names:
          - SecurityUpdates
          - CriticalUpdates
        reboot: yes
        reboot_timeout: 600

Обработка ошибок в Ansible: модуль fail и другие инструменты

Хороший playbook не просто выполняет задачи — он знает, когда остановиться и почему. Вот инструментарий для грамотной обработки ошибок.

# tasks/error-handling.yml
---
# Зарегистрировать результат команды
- name: Проверить статус сервиса
  command: systemctl is-active nginx
  register: nginx_status
  ignore_errors: yes    # Не падать при ошибке

# Завершить playbook с сообщением при условии
- name: Остановить если nginx не работает
  fail:
    msg: "КРИТИЧНО: Nginx не запущен! Статус: {{ nginx_status.stdout }}"
  when: nginx_status.rc != 0

# Блок try-catch в Ansible
- name: Попытаться выполнить рискованную операцию
  block:
    - name: Основная задача
      command: /opt/scripts/deploy.sh

    - name: Проверка результата
      uri:
        url: http://localhost/health
        status_code: 200

  rescue:
    - name: Откатить изменения при ошибке
      command: /opt/scripts/rollback.sh

    - name: Уведомить о сбое
      uri:
        url: "{{ slack_webhook_url }}"
        method: POST
        body_format: json
        body:
          text: "Деплой на {{ inventory_hostname }} завершился ошибкой!"

  always:
    - name: Записать в лог в любом случае
      lineinfile:
        path: /var/log/ansible-deploy.log
        line: "{{ ansible_date_time.iso8601 }} - Деплой завершён на {{ inventory_hostname }}"

# Проверка переменной перед выполнением
- name: Проверить обязательную переменную
  fail:
    msg: "Переменная 'app_version' не задана!"
  when: app_version is not defined or app_version | length == 0

Полезные команды Ansible: шпаргалка на каждый день

# ===== INVENTORY =====
ansible all --list-hosts                          # Список всех хостов
ansible web --list-hosts                          # Хосты группы
ansible-inventory --list                          # Полный inventory в JSON
ansible-inventory --graph                         # Дерево групп

# ===== PING И ФАКТЫ =====
ansible all -m ping                               # Проверить связь
ansible web -m gather_facts                       # Собрать факты
ansible all -m setup -a "filter=ansible_os*"     # Конкретные факты

# ===== AD-HOC КОМАНДЫ =====
ansible web -a "uptime"                           # Uptime серверов
ansible web -a "df -h"                            # Дисковое пространство
ansible all -a "free -m"                          # Оперативная память
ansible web -m apt -a "upgrade=dist" --become     # Обновить все пакеты

# ===== PLAYBOOK =====
ansible-playbook playbook.yml                     # Запуск
ansible-playbook playbook.yml --check            # Dry-run
ansible-playbook playbook.yml --diff             # Показать изменения файлов
ansible-playbook playbook.yml --limit web01      # Только один хост
ansible-playbook playbook.yml --tags deploy      # Только задачи с тегом
ansible-playbook playbook.yml --skip-tags tests  # Пропустить задачи с тегом
ansible-playbook playbook.yml -e "version=2.1"   # Передать переменную

# ===== VAULT =====
ansible-vault create secrets.yml                 # Создать зашифрованный файл
ansible-vault edit secrets.yml                   # Редактировать
ansible-vault view secrets.yml                   # Просмотреть
ansible-vault encrypt_string 'MyPassword' --name 'db_password'  # Зашифровать строку

# ===== GALAXY =====
ansible-galaxy role install geerlingguy.nginx    # Установить роль
ansible-galaxy collection install community.docker  # Установить коллекцию
ansible-galaxy role list                         # Список установленных ролей

Структура production Ansible-проекта

Хаотичный набор playbook-файлов в одной папке — это технический долг, который придётся возвращать. Вот структура, проверенная в боевых условиях:

ansible-project/
├── ansible.cfg                    # Конфигурация Ansible
├── requirements.yml               # Зависимости (роли и коллекции)
├── site.yml                       # Главный playbook (точка входа)
├── deploy.yml                     # Playbook деплоя
├── maintenance.yml                # Playbook обслуживания
│
├── inventory/
│   ├── production/
│   │   ├── hosts.yml              # Хосты production
│   │   ├── group_vars/
│   │   │   ├── all.yml
│   │   │   ├── web.yml
│   │   │   └── db.yml
│   │   └── host_vars/
│   │       └── web01.yml
│   └── staging/
│       └── hosts.yml
│
├── roles/
│   ├── common/                    # Базовая <a title="Сервер активации Windows: подключение, настройка и решение ошибок KMS" href="https://it-apteka.com/server-aktivacii-windows-podkljuchenie-nastrojka-i-reshenie-oshibok-kms/" target="_blank" rel="noopener" data-wpil-monitor-id="814">настройка всех серверов</a>
│   ├── nginx/                     # Веб-сервер
│   ├── postgresql/                # БД
│   └── docker/                    # Docker Engine
│
├── playbooks/
│   ├── setup-web.yml
│   ├── setup-db.yml
│   └── deploy-app.yml
│
├── files/                         # Статические файлы
├── templates/                     # Шаблоны Jinja2
└── vars/
    ├── common.yml
    └── secrets.yml                # Зашифровано через ansible-vault

Типичные ошибки и их лечение

«UNREACHABLE: Failed to connect to the host via ssh»

# Проверить SSH-подключение вручную
ssh -i ~/.ssh/ansible_key user@192.168.1.10

# Проверить, что хост доступен
ping 192.168.1.10

# Отладить подключение Ansible
ansible web01 -m ping -vvv

# Если проблема с known_hosts — добавить хост или отключить проверку
ssh-keyscan 192.168.1.10 >> ~/.ssh/known_hosts
# или в ansible.cfg: host_key_checking = False

«sudo: a password is required» при become

# Настроить sudo без пароля для пользователя ansible на серверах
# Добавить в /etc/sudoers на управляемом сервере:
echo "ansible ALL=(ALL) NOPASSWD: ALL" | sudo tee /etc/sudoers.d/ansible

# Или передать пароль sudo при запуске
ansible-playbook playbook.yml --ask-become-pass

«The task includes an option with an undefined variable»

# Проверить определена ли переменная
ansible web -m debug -a "var=my_variable"

# Задать значение по умолчанию в шаблоне
"{{ my_variable | default('default_value') }}"

# Проверить inventory на наличие переменной
ansible-inventory --host web01

«MODULE FAILURE: MODULE_STDERR: Traceback (most recent call last)»

# Обычно проблема с версией Python на управляемом сервере
# Указать явно в inventory или playbook:
ansible_python_interpreter: /usr/bin/python3

# Или определить автоматически:
ansible_python_interpreter: auto_silent

Итог: Ansible в вашем арсенале

Мы прошли путь от установки до production-структуры. Теперь у вас есть всё, чтобы начать автоматизировать инфраструктуру по-взрослому:

  • Ansible установлен и настроен для работы по SSH
  • Inventory организован по группам и окружениям
  • Playbook написан с использованием vars, handlers и тегов
  • Роли структурированы и переиспользуются
  • Секреты зашифрованы через Vault
  • Docker и Windows под контролем
  • Ошибки обрабатываются через block/rescue/fail

Если что-то пошло не так или хотите разобрать конкретный сценарий автоматизации — пишите в комментарии. Подпишитесь на Telegram-канал, чтобы не пропустить новые гайды из IT-аптеки.

Оставайтесь на связи

Рецепты от IT-боли. Без воды, без рекламы, без маркетинговой шелухи.

Подписаться на IT-Аптеку →
Поделитесь:

Оставьте комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Прокрутить вверх