pre-commit & hooks для Ansible и YAML в GitLab

19 October 2025

Настройка 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 и корпоративного контура.

Leave a comment

Popular Posts

Advertisement

Headlines