Управление файлами: модули file, copy, fetch и stat

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

Управление файлами: модули file, copy, fetch и stat

Сообщение 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 и chmod, то на трёх машинах ещё терпимо, а на тридцати - уже боль и гарантированный человеческий косяк. Ansible решает это четырьмя рабочими лошадками: ansible.builtin.file управляет существованием и атрибутами, ansible.builtin.copy кладёт содержимое на узел, ansible.builtin.fetch тянет файл обратно на control node, а ansible.builtin.stat смотрит, что вообще лежит на диске, чтобы ты принимал решения по факту, а не наугад.

В этом уроке разберём механику каждого, общие параметры, идемпотентность и главную ловушку новичков - режим прав mode в восьмеричном виде. На экзамене EX294 задачи на file и copy встречаются буквально на каждом варианте, так что это не теория ради галочки, а твой хлеб.

Модуль ansible file: каталоги, симлинки и права

Модуль ansible file ничего не копирует. Он управляет состоянием объекта файловой системы, который уже есть или должен появиться: обычный файл, каталог, символическая или жёсткая ссылка. Ключевой параметр - state, и именно он определяет, что делает ansible file module:
  • directory - создать каталог (и родительские, как mkdir -p)
  • file - не создаёт файл, только проверяет наличие и правит атрибуты; если файла нет - ошибка
  • touch - создать пустой файл, если его нет, и/или обновить mtime
  • link и hard - символическая и жёсткая ссылка
  • absent - удалить (рекурсивно для каталогов)
Типовой пример - подготовить каталог под приложение с нужным владельцем и правами 0755:

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

- name: Каталог приложения
  ansible.builtin.file:
    path: /opt/myapp
    state: directory
    owner: appuser
    group: appuser
    mode: "0755"

- name: Симлинк на текущий релиз
  ansible.builtin.file:
    src: /opt/myapp/releases/2026-06-15
    dest: /opt/myapp/current
    state: link
Обрати внимание: для ссылки источник - это src, а место назначения - dest, не path. Это частая путаница.

Теперь про права. Когда брифы и инструкторы говорят "ansible file 754", имеется в виду режим 0754 (rwxr-xr--). И вот главная грабля: mode пиши строкой в кавычках - "0644", "0754". Если написать mode: 0644 без кавычек, YAML воспримет ведущий ноль как восьмеричный литерал и сконвертирует в десятичное число, а Ansible получит совсем не то, что ты задумал. Кавычки спасают всегда. Альтернатива - символьная запись, она тоже работает и иногда читается понятнее:

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

- name: Сделать скрипт исполняемым только владельцу
  ansible.builtin.file:
    path: /opt/myapp/run.sh
    mode: "u+x"
Изображение

Модуль ansible copy: содержимое, content и backup

Если file отвечает за состояние, то ansible copy кладёт данные. Это один из самых высокочастотных модулей вообще, поэтому ansible copy module стоит освоить до автоматизма. Он умеет два режима. Первый - копировать локальный файл с control node на узел через src. Второй - писать содержимое прямо из плейбука через content, без отдельного файла:

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

- name: Скопировать готовый конфиг
  ansible.builtin.copy:
    src: files/app.conf
    dest: /etc/myapp/app.conf
    owner: root
    group: root
    mode: "0644"
    backup: true

- name: Создать файл из строки прямо в задаче
  ansible.builtin.copy:
    content: |
      ENV=production
      WORKERS=4
    dest: /etc/myapp/env
    mode: "0640"
Параметр backup: true перед перезаписью делает резервную копию с таймстампом рядом с целевым файлом. На боевых конфигах это дешёвая страховка, советую держать привычку. Путь src в copy относительный ищется в каталоге files/ роли или плейбука - это соглашение Ansible, не магия.

Важно понимать границу: copy хорош для статики. Если в файле нужны переменные, циклы, условия - это уже работа модуля template с Jinja2, его разберём отдельно. И ещё: для больших бинарников copy не лучший выбор, проще скачать на узле через get_url. А вот для одиночных текстовых конфигов и небольших файлов copy - первый инструмент.

Идемпотентность тут встроена: Ansible считает контрольную сумму и, если содержимое и атрибуты совпадают, задача отрабатывает в состоянии ok, ничего не трогая. Меняешь content или права - получаешь changed. Прогон того же плейбука второй раз не должен давать изменений, и это ровно то, что проверяют на EX294.

Ansible fetch и stat: забрать файл и проверить факты

Иногда поток нужен в обратную сторону: собрать файлы с управляемых узлов на control node. Для этого есть ansible fetch. Классика - стянуть логи или конфиги для разбора. Модуль по умолчанию раскладывает добычу по подкаталогам с именем хоста, чтобы файлы с разных машин не перетёрли друг друга:

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

- name: Забрать лог приложения к себе
  ansible.builtin.fetch:
    src: /var/log/myapp/error.log
    dest: /tmp/collected/
    flat: false
При flat: false (по умолчанию) файл ляжет в /tmp/collected/web1/var/log/myapp/error.log. Это удобно при сборе с группы хостов.

Теперь ansible.builtin.stat - твой способ узнать факты о файле до того, как что-то делать. Он не меняет систему, только читает метаданные: существует ли путь, режим, владелец, контрольная сумма, это файл или каталог. Результат регистрируешь через register и принимаешь решение через when. Это и есть связка stat плюс when, которую любят давать на собеседованиях и экзамене:

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

- name: Проверить наличие конфига
  ansible.builtin.stat:
    path: /etc/myapp/app.conf
  register: cfg

- name: Развернуть дефолт, только если конфига ещё нет
  ansible.builtin.copy:
    src: files/app.conf.default
    dest: /etc/myapp/app.conf
    mode: "0644"
  when: not cfg.stat.exists
Полезные поля результата: cfg.stat.exists (булево), cfg.stat.mode (строка восьмеричных прав, например "0644"), cfg.stat.checksum (sha1 по умолчанию), cfg.stat.isdir, cfg.stat.pw_name (имя владельца). Тонкость: к mode и checksum можно обращаться, только когда exists истинно, иначе этих ключей в словаре не будет и задача упадёт. Поэтому условие почти всегда начинается с проверки exists.

Общие параметры и типичные грабли

file, copy, fetch и большинство файловых модулей делят общий набор атрибутов: owner, group, mode, а на RHEL/Fedora ещё и setype, seuser, serole, selevel для контекста SELinux. Это важно: скопировал файл в /var/www, права верные, а Apache его не отдаёт - смотри SELinux-контекст, а не только chmod. По умолчанию copy старается выставить разумный контекст, но в нестандартных каталогах задавай setype явно или применяй restorecon.

Грабли, на которых горят чаще всего:
  • mode без кавычек. Ведущий ноль ломает восьмеричную интерпретацию. Всегда "0644", не 0644.
  • state: file вместо touch. state: file не создаёт файл, только правит атрибуты существующего. Чтобы создать пустой - state: touch.
  • Путаница src/dest/path. У file для ссылок - src и dest, для обычного объекта - path. У copy и fetch - src и dest, но направление противоположное: copy кладёт на узел, fetch тянет на control node.
  • Забыли про идемпотентность. state: touch при каждом прогоне обновляет mtime и даёт changed. Если это нежелательно, добавь параметры modification_time: preserve и access_time: preserve.
На Ubuntu и Debian всё это работает один в один (apt вместо dnf на установку пакетов роли роли не касается - файловые модули кросс-платформенные), отличие лишь в том, что SELinux там обычно не используется, зато может быть AppArmor. В RED OS и Astra Linux поведение ближе к RHEL: dnf или apt в зависимости от сборки, systemd и нередко включённый SELinux.

Мини-лаба: повтори руками

Собери короткий плейбук и прогони его дважды, добиваясь нуля изменений на втором прогоне:
  • Создай каталог /opt/lab с владельцем root и правами "0755" через ansible.builtin.file.
  • Положи туда файл config.ini из content с правами "0640" и backup: true. Поменяй одну строку в content и прогони ещё раз - убедись, что появился changed и резервная копия.
  • Сделай симлинк /opt/lab/current на /opt/lab через state: link.
  • Через stat проверь существование /opt/lab/config.ini, зарегистрируй результат и выведи debug-сообщение с его mode и checksum.
  • Забери /opt/lab/config.ini на control node через fetch с flat: false и посмотри структуру каталогов.
Контрольные вопросы:
  • Почему mode нужно писать в кавычках и что произойдёт с mode: 0644 без них?
  • Чем отличаются state: file и state: touch в модуле file?
  • Как с помощью stat и when развернуть файл только при его отсутствии и почему важно сначала проверять stat.exists?
  • В какую сторону работают copy и fetch и куда fetch складывает файлы при flat: false?
Итог. file управляет состоянием и атрибутами объектов файловой системы, copy кладёт содержимое (файл или content) на узел, fetch тянет файлы обратно на control node, stat читает метаданные для условной логики. Держи в голове кавычки вокруг mode, направление src/dest и проверку exists перед обращением к остальным полям stat - этого набора хватает, чтобы уверенно закрывать файловые задачи и на проде, и на EX294.
👍2 ❤️2 🔥 😄 🤔
Аватара пользователя
sukifan
Сообщения: 1
Зарегистрирован: 12 май 2026, 06:39

Re: Управление файлами: модули file, copy, fetch и stat

Сообщение sukifan »

Спасибо, наконец дошло почему mode у меня вело себя странно. Реально писал 0644 без кавычек и права получались левые, поправил на 0640 в кавычках - всё встало.
👍1 ❤️ 🔥 😄 🤔1
Аватара пользователя
tommykm
Сообщения: 1
Зарегистрирован: 26 май 2026, 18:34

Re: Управление файлами: модули file, copy, fetch и stat

Сообщение tommykm »

Вопрос по stat: а если надо сравнить содержимое а не просто наличие, можно через stat.checksum двух файлов? Или для этого лучше сразу copy с его проверкой суммы и смотреть на changed?
👍3 ❤️1 🔥 😄 🤔
Ответить
← Предыдущая глава
Блоки в Ansible: block, rescue и always
Следующая глава →
Архивы и сборка файлов: archive, unarchive, assemble

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

Поделиться темой: ✈ Telegram VK
Похожие запросы: как создать роль ansible с нуля и структура каталогов

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

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

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