Настройка pre-commit и оффлайн-хуков для Ansible и YAML в GitLab
Автор: Владыка @ devopz.tech
⚡ Тема: как заставить pre-commit проверять ваши YAML и Ansible плейбуки — даже в оффлайне, внутри интрасети.
Корпоративный pre-commit в GitLab: DevSecOps в каждый коммит
Зачем оно надо и что такое pre-commit?
pre-commit — это фреймворк, который запускает проверки перед коммитом. Он предотвращает пуш невалидных YAML, неотформатированных файлов и грязных плейбуков Ansible.
При каждом git commit он прогоняет хуки (hooks), которые проверяют, форматируют и валидируют код.
Чтобы код попадал в репозиторий уже проверенным, а не «потом кто-нибудь поправит». Автопроверки перед каждым коммитом:
- ✅ уменьшают баги и кринж
- ✅ снижают атакующую поверхность и утечки секретов
- ✅ стандартизируют код между командами
- ✅ помогают пройти аудит и ISO-боссов ?
Pre-commit = дешёвая DevSecOps-магия прямо у тебя под руками.
Что проверяем
В этой статье покажем, как настроить pre-commit для Ansible-проектов в условиях корпоративного контура, чтобы:
- Автоматически проверять YAML, Jinja2, Python и коммиты.
- Игнорировать Ansible Vault и шаблоны
.j2. - Не ругаться на отсутствующие
---в ролях. - Быть совместимым с air-gap средой и CI/CD.
Зачем нужен pre-commit
Pre-commit — это хук Git, который запускает линтеры и фиксаторы перед коммитом.
Преимущества:
- Чистый код в репозитории
- Меньше ошибок в CI/CD
- Автоматическое исправление пробелов, EOF и других мелочей
- Совместимость с корпоративными требованиями к безопасности
Структура проекта
ansible/
├── group_vars/
│ └── all/
│ └── vault.yml
├── roles/
│ ├── install_gitlab_rnr/
│ │ ├── tasks/
│ │ ├── handlers/
│ │ └── defaults/
│ └── ...
├── playbooks/
│ └── install_gitlab_runner.yml
├── .pre-commit-config.yaml
└── .yamllint-config.yaml
Конфигурация pre-commit
Создаём .pre-commit-config.yaml:
---
default_language_version:
python: python3
repos:
# Базовые хуки (пробелы, EOF, приватные ключи, конфликты)
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.5.0
hooks:
- id: trailing-whitespace
- id: end-of-file-fixer
- id: check-added-large-files
- id: detect-private-key
- id: check-merge-conflict
- id: check-yaml
name: Validate YAML files
exclude: |
(?x)^(
.*vault\.yml| # Игнорируем Ansible Vault
roles/.*/templates/.*\.j2 # Игнорируем шаблоны
)$
# Линтер YAML
- repo: https://github.com/adrienverge/yamllint.git
rev: v1.26.2
hooks:
- id: yamllint
name: Validate YAML with yamllint
args: [ "-c", ".yamllint-config.yaml" ]
# Линтер Jinja2 шаблонов
- repo: https://github.com/thibaudcolas/curlylint
rev: v0.13.1
hooks:
- id: curlylint
name: Lint Jinja2 templates
files: \.j2$
# Проверка коммитов
- repo: https://github.com/jorisroovers/gitlint
rev: v0.14.0
hooks:
- id: gitlint
name: Validate commit messages
args: [ -v, --ignore=body-is-missing, --msg-filename ]
# Проверка Python (например, module_utils)
- repo: https://github.com/pycqa/flake8
rev: 7.1.1
hooks:
- id: flake8
name: Python syntax & style check
args: [ "--max-line-length=120" ]
exclude: |
(?x)^(
roles/.*/templates/.*\.j2 |
tests/.*
)$
Конфиг yamllint
---
yaml-files:
- '*.yaml'
- '*.yml'
rules:
braces:
max-spaces-inside: 1
level: error
brackets:
max-spaces-inside: 1
level: error
colons:
max-spaces-after: -1
level: error
commas:
max-spaces-after: -1
level: error
comments: disable
document-start:
level: warning
present: false # разрешаем отсутствие '---' в ролях
empty-lines:
max: 1
level: error
hyphens:
level: error
indentation: enable
key-duplicates: enable
line-length: disable
new-line-at-end-of-file: enable
new-lines:
type: unix
trailing-spaces: enable
truthy: disable
ignore: |
.git/
files/
templates/
tests/
roles/.*/tasks/.*\.yml
roles/.*/handlers/.*\.yml
roles/.*/defaults/.*\.yml
roles/.*/vars/.*\.yml
roles/.*/meta/.*\.yml
Git ignore
.gitignore
# Ansible
*.retry
.ansible/
__pycache__/
# Pre-commit & Python cache
.pre-commit/
.pre-commit-config.yaml~
.secrets.baseline
*.pyc
# Logs & temp
*.log
*.tmp
Установка и запуск
# Установить pre-commit
pip install pre-commit
# Подключить хуки к репозиторию
pre-commit install
# Обновить хуки
pre-commit autoupdate
# Запуск всех хуков на всех файлах
pre-commit run -a
Для air-gap среды можно перенести кэш:
tar czf pre-commit-cache.tar.gz ~/.cache/pre-commit
Результат
- Пробелы, EOF, большие файлы и приватные ключи — исправляются автоматически
- YAML проверяется, но роли не требуют
--- - Jinja2 шаблоны проверяются без ошибок
- Коммиты проверяются по правилам
- Python код внутри ролей проверяется flake8
✅ Чистый код, готовый для CI/CD и корпоративного контура.
