Архивы и сборка файлов: archive, unarchive, assemble

Рейтинг: 59.6% · 10 голосов
Подробный курс по Ansible с прицелом на экзамен RHCE EX294: установка и инвентарь, плейбуки, переменные и факты, Vault, циклы и условия, шаблоны Jinja2, роли и коллекции, Execution Environments и ansible-navigator, управление системами (диски, LVM, cron, SELinux, firewalld). Примеры на RHEL/Fedora. Актуально на 2026.
Ответить
Аватара пользователя
Maksim_DevOps
Сообщения: 47
Зарегистрирован: 11 май 2026, 05:31

Архивы и сборка файлов: archive, unarchive, assemble

Сообщение Maksim_DevOps »

Оглавление курса (47)
  1. Что такое Ansible и зачем он нужен: автоматизация без агентов
  2. Сертификация RHCE и экзамен EX294: что внутри и как готовиться
  3. Архитектура Ansible: control node, узлы, модули и плагины
  4. Установка Ansible на control node: dnf, pip и версии ansible-core
  5. Подготовка управляемых узлов: SSH, пользователь и sudo
  6. Инвентарь Ansible: hosts, группы и переменные
  7. Настройка Ansible: файл ansible.cfg и приоритеты конфигурации
  8. Host patterns и инструменты командной строки Ansible
  9. Ad hoc команды Ansible: быстрые задачи без плейбука
  10. Ansible playbook: что это такое и как устроен
  11. Структура плейбука: play, task, модули и переменные
  12. Запуск плейбуков: проверка, теги, ограничения и отладка
  13. Параллелизм и порядок выполнения: forks, serial, strategy
  14. Факты Ansible: сбор информации об узлах
  15. Переменные Ansible: типы, объявление и приоритет
  16. Регистрация результатов и специальные переменные
  17. Ansible Vault: шифрование паролей и секретов
  18. Организация инвентаря: group_vars, host_vars и вложенные группы
  19. Динамический инвентарь и инвентарные плагины
  20. Циклы в Ansible: loop, списки и словари
  21. Повтор задачи до условия: until, retries и delay
  22. Условия в Ansible: директива when и логика
  23. Jinja2 в Ansible: выражения, фильтры и подстановки
  24. Обработчики Ansible: handlers, notify и flush_handlers
  25. Обработка ошибок: failed_when, changed_when и ignore_errors
  26. Блоки в Ansible: block, rescue и always
  27. Управление файлами: модули file, copy, fetch и stat
  28. Архивы и сборка файлов: archive, unarchive, assemble (вы здесь)
  29. Точечное редактирование файлов: lineinfile и blockinfile
  30. Шаблоны Jinja2: модуль template и динамические конфиги
  31. Jinja2 продвинуто: фильтры, циклы, макросы и lookup
  32. Модули Ansible: ansible-doc и поиск нужного модуля
  33. Разработка собственного модуля Ansible на Python
  34. Роли Ansible и Ansible Galaxy: переиспользование
  35. Разработка роли Ansible: создание с нуля
  36. Зависимости ролей и requirements.yml
  37. Коллекции Ansible: ansible.posix, community и своя коллекция
  38. Execution Environments: контейнеры для запуска Ansible
  39. Сборка Execution Environment с ansible-builder
  40. ansible-navigator: запуск плейбуков в Execution Environment
  41. Управление SSH-ключами через Ansible: authorized_key
  42. Управление дисками: filesystem, mount и parted
  43. LVM через Ansible: тома, группы и расширение
  44. Планировщик задач: cron и systemd timers через Ansible
  45. Безопасность: hardening SSH и репозитории dnf/yum
  46. SELinux через Ansible: булевы, контексты и порты
  47. Сквозной проект и подготовка к экзамену EX294
Рано или поздно ты упрёшься в задачу, которую руками решают через scp и tar: разложить релиз приложения по серверам, выкатить дистрибутив, собрать большой конфиг из кучи мелких кусков. Делать это вручную - боль: забыл флаг, распаковал не туда, прогнал второй раз и затёр свежие данные. В Ansible под это есть три рабочие лошадки - archive, unarchive и assemble. Разберём, чем они отличаются, как заставить их быть идемпотентными и где на этом срезаются на RHCE.

Сразу важная деталь, на которой спотыкаются почти все. Модуль для распаковки - это ansible.builtin.unarchive, он встроенный. А вот модуль для упаковки - community.general.archive, он живёт в коллекции community.general, а не в builtin. Если напишешь ansible.builtin.archive, получишь ошибку "couldn't resolve module". Проверь, что коллекция стоит:

Код: Выделить всё

ansible-galaxy collection list | grep community.general
В RHEL-сборке ansible-core коллекцию часто надо доставить отдельно:

Код: Выделить всё

ansible-galaxy collection install community.general
Ansible unarchive: распаковать архив на узел

Начнём с того, что встречается чаще всего, в том числе на экзамене - деплой артефакта. Запрос "ansible распаковать архив" почти всегда приводит именно к unarchive. У модуля две принципиально разные модели работы, и путаница между ними - источник половины проблем.

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

Код: Выделить всё

- name: Выкатить дистрибутив приложения с control-ноды
  ansible.builtin.unarchive:
    src: files/myapp-1.4.0.tar.gz
    dest: /opt/myapp
    owner: appuser
    group: appuser
    creates: /opt/myapp/bin/myapp
Модель вторая, remote_src: yes: архив уже находится на самом узле (например, ты его туда скачал) либо доступен по URL, и Ansible не тащит ничего с control-ноды.

Код: Выделить всё

- name: Скачать и распаковать дистрибутив прямо на узле
  ansible.builtin.unarchive:
    src: https://repo.example.com/releases/myapp-1.4.0.tar.gz
    dest: /opt/myapp
    remote_src: yes
    creates: /opt/myapp/bin/myapp
Запомни простое правило: remote_src: no (по умолчанию) - источник на control-ноде, remote_src: yes - источник на целевом узле или по URL. Скачивание по http/https работает только при remote_src: yes.

Теперь про идемпотентность - это то, ради чего мы вообще в Ansible. Сам по себе unarchive не самый умный: при remote_src он по умолчанию каждый прогон сверяет содержимое архива с файлами на диске. Но самый надёжный и предсказуемый способ сделать задачу идемпотентной - параметр creates. Указываешь путь к файлу или каталогу, который появляется после распаковки; если он уже есть - модуль пропускает шаг и рапортует ok вместо changed. Без creates ты рискуешь либо лишними changed на каждом прогоне, либо тем, что распаковка затрёт уже изменённые на месте файлы. На EX294 именно creates показывает, что ты понимаешь идемпотентность, а не просто "лишь бы отработало".

Изображение

Ansible archive: создать tar/gz/zip из файлов узла

Обратная операция - ansible archive - упаковывает файлы, которые лежат на самом узле, в один архив. Типичные сценарии: снять бэкап конфигов перед изменениями, собрать логи для выгрузки, заархивировать каталог приложения перед обновлением.

Код: Выделить всё

- name: Заархивировать конфиги перед правкой
  community.general.archive:
    path:
      - /etc/myapp/myapp.conf
      - /etc/myapp/conf.d/
    dest: /var/backups/myapp-conf-{{ ansible_date_time.date }}.tar.gz
    format: gz
    owner: root
    mode: '0600'
Параметр format принимает gz, bz2, xz, zip, tar. По умолчанию gz. В path можно передать список путей или маску. Полезный нюанс: если в path один каталог, по умолчанию архив создастся "поверх" структуры; поведением управляет параметр remove (удалять ли исходники после упаковки - по умолчанию no, и слава богу). Идемпотентность тут условная: archive каждый раз пересоздаёт архив, поэтому если важно не дёргать его без нужды, оборачивай в when или используй creates на уровне другой задачи. Для бэкапов с датой в имени это обычно и не нужно.

Ansible assemble: собрать один файл из фрагментов каталога

Третий модуль решает совсем другую боль. Представь конфиг, который удобно держать по кускам: основной блок, блок для каждого виртуального хоста, блок с лимитами. Многие демоны умеют читать каталог conf.d целиком, но не все - sysctl, некоторые старые сервисы, кастомные приложения хотят один монолитный файл. Вот тут и нужен ansible assemble: он берёт все фрагменты из каталога, склеивает их по алфавиту имён в один файл и кладёт в нужное место.

Код: Выделить всё

- name: Собрать sshd_config из фрагментов
  ansible.builtin.assemble:
    src: /etc/ssh/sshd_config.d/
    dest: /etc/ssh/sshd_config
    owner: root
    group: root
    mode: '0600'
    delimiter: "\n# --- fragment ---\n"
    regexp: '^[0-9]+-.*\.conf$'
    validate: '/usr/sbin/sshd -t -f %s'
  notify: Restart sshd
Что тут происходит. src - каталог с кусками, dest - итоговый файл. delimiter вставляется между фрагментами (удобно для читаемости). regexp фильтрует, какие файлы из каталога брать - например, только вида 10-base.conf, 20-limits.conf, чтобы временные и бэкапные файлы не попали в сборку. И самое ценное для боевых конфигов - validate: модуль соберёт файл во временное место, прогонит твою команду проверки (%s заменяется на путь к временному файлу) и только при успехе положит результат в dest. Если проверка не прошла - dest не тронут, сервис не сломается. Порядок склейки - по сортировке имён файлов, поэтому и принят префикс с цифрами.

Хочешь собрать конфиг из частей, что лежат на control-ноде, а не на узле? Добавь remote_src: no (по умолчанию yes для assemble в новых версиях - перепроверь поведение под свою версию, тут исторически были разночтения), либо просто сначала разложи фрагменты на узел через copy/template, а потом собери assemble с источником на узле. Второй путь надёжнее и понятнее.

Типичные грабли
  • Пишут ansible.builtin.archive - такого нет. Упаковка только через community.general.archive.
  • Путают remote_src. URL качается только при remote_src: yes. С control-ноды копируется только при remote_src: no.
  • Забывают creates у unarchive - получают вечный changed или затирают данные на узле при каждом прогоне.
  • На узле нет утилиты для распаковки. unarchive под капотом зовёт tar/gunzip/unzip. Для zip часто нужен пакет unzip: поставь его задачей ansible.builtin.dnf (или apt в Debian/Ubuntu, в RED OS и Astra - тоже apt/dnf по семейству).
  • SELinux и права. После распаковки контекст файлов может быть неверным; не забывай про restorecon или модуль ansible.builtin.sefcontext, если демон не видит файлы.
  • assemble без validate на критичном конфиге. Один битый фрагмент - и sshd не стартует. validate спасает.
Мини-лаба

Прогони руками на тестовой RHEL/Fedora-машине:
  • Создай локально tar.gz с парой файлов, распакуй его на узел через unarchive с remote_src: no и creates. Запусти плейбук дважды - убедись, что второй прогон ok, а не changed.
  • Скачай публичный архив по URL с remote_src: yes прямо на узел и распакуй в /opt. Проверь, что без unzip zip-архив не распакуется, и почини это задачей dnf.
  • Сделай каталог /etc/myapp/conf.d с файлами 10-main.conf и 20-extra.conf, собери из них один /etc/myapp/myapp.conf через assemble с delimiter и regexp. Добавь битый фрагмент и проверь, как validate не даёт сломать файл.
  • Заархивируй /etc/myapp через community.general.archive в /var/backups с датой в имени.
Контрольные вопросы
  • В какой коллекции живёт модуль для создания архива и почему ansible.builtin.archive не сработает?
  • Чем отличается поведение unarchive при remote_src: yes и remote_src: no, и когда качается URL?
  • Зачем нужен параметр creates в unarchive и как он влияет на идемпотентность?
  • Что делает validate в assemble и почему без него опасно собирать боевой конфиг?
Итог

Три модуля - три задачи. unarchive распаковывает (и даже качает по URL), archive из community.general упаковывает файлы на узле, assemble клеит монолитный конфиг из фрагментов. Ключ к чистым прогонам - remote_src правильно выбран, creates на месте, а validate бережёт от битых конфигов. На EX294 чаще всего попросят именно деплой артефакта через unarchive - отработай его до автоматизма.
👍4 ❤️ 🔥1 😄 🤔
Аватара пользователя
torchandy
Сообщения: 1
Зарегистрирован: 15 май 2026, 00:07

Re: Архивы и сборка файлов: archive, unarchive, assemble

Сообщение torchandy »

Спасибо, наконец дошло почему archive не из builtin - полчаса вчера ловил couldn not resolve module, оказалось коллекцию надо доставить. Теперь работает.
👍1 ❤️1 🔥 😄 🤔
Аватара пользователя
SparkLover
Сообщения: 1
Зарегистрирован: 11 май 2026, 23:39

Re: Архивы и сборка файлов: archive, unarchive, assemble

Сообщение SparkLover »

А подскажите, если unarchive с remote_src yes и creates указан на каталог, который уже частично распакован - он дораспакует или совсем пропустит? У меня релиз иногда падает на середине.
👍 ❤️ 🔥2 😄 🤔
Ответить
← Предыдущая глава
Управление файлами: модули file, copy, fetch и stat
Следующая глава →
Точечное редактирование файлов: lineinfile и blockinfile

Все главы курса «Ansible: автоматизация и подготовка к RHCE (EX294)»

Поделиться темой: ✈ Telegram VK
  • Похожие темы
Похожие запросы: webhook от github в jenkins как настроить триггер сборкипараметры и параллельные стейджи в jenkins pipeline

Вернуться в «Ansible: автоматизация и подготовка к RHCE (EX294)»

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и 1 гость