# ansible-roles Канон общих Ansible-ролей для изолированных серверных репозиториев (`pet-project-server`, `buckland`, …). Это **рабочая директория-канон**, а не сервис. Серверные репозитории держат закоммиченные копии ролей в своём `roles/` и синхронизируются с этим каноном через invoke-задачи (rsync, git здесь не участвует): - `inv roles-pull [-- ]` — канон → репозиторий; - `inv roles-push [-- ]` — репозиторий → канон (с подтверждением при расхождении); - `inv roles-status` — сравнить подписанные роли с каноном. Каждый репозиторий объявляет подписку в своём `tasks.py` (`SYNCED_ROLES`). «Пином версии» служит сама закоммиченная копия в репозитории: деплоится ровно то, что лежит в его git. Git в этой директории — опциональный бэкап истории канона, он не стоит в рабочей петле синхронизации. Спецификация подхода: `pet-project-server/docs/drafts/shared-roles-sync.md`. ## Роли - `eget` — установка утилиты [eget](https://github.com/zyedidia/eget). - `app_image` — локальная сборка docker-образа приложения и доставка его на сервер через `docker save`/`load` (без registry; тулчейн сборки на сервере не нужен). Подробности и переменные — в `roles/app_image/README.md`. ### Контракт для приложения (app_image) Чтобы приложение можно было деплоить этой ролью, в его рабочей директории должна быть **команда сборки образа** (по умолчанию `task image`). Роль — инициатор: она вызывает команду и передаёт ей случайный `BUILD_ID` через окружение. Команда обязана собрать **полный** образ и затегать его `:$BUILD_ID`. Пример реализации на Taskfile (тег из `$BUILD_ID`, по умолчанию `dev` для локальной работы): ```yaml image: desc: 'Полный docker-образ. Тег из $BUILD_ID (по умолчанию dev).' deps: [build] cmds: - docker build -t {{.BINARY}}:${BUILD_ID:-dev} . ``` Вызов роли в плейбуке: ```yaml - name: 'Build and deliver application image' ansible.builtin.import_role: name: app_image vars: app_image_name: 'myapp' app_image_src_dir: '{{ (playbook_dir, "..", "myapp") | path_join }}' # роль выставляет факт app_image_tag для рендера compose ```