GitLab CI для infra-репозитория: lint, валидация и flux reconcile

Published: 2026-04-03

.gitlab-ci.yml infra-репозитория содержит по одному джобу на каждый вид возможной проблемы: синтаксические ошибки YAML, сбои рендеринга Kustomize, ошибки Terraform plan и расхождение между git и работающим кластером.


Стадии пайплайна

validate:yaml        ← yamllint для fluxcd/ и ansible/
validate:kustomize   ← kubectl kustomize для каждого env
validate:terraform   ← terraform validate для каждого env
validate:security    ← Trivy SARIF + SonarQube (ручной запуск)
reconcile:flux       ← flux reconcile source git (авто, только main)
reconcile:envs       ← reconcile Kustomization по окружениям (ручной)
notify               ← вебхук Telegram + Mattermost

YAML lint

yamlvalidate:yaml:
  stage: validate:yaml
  image: registry.example.com/pipelinecomponents/yamllint:latest
  script:
    - yamllint -c .yamllint.yaml fluxcd/ ansible/

.yamllint.yaml:

yamlextends: default
rules:
  line-length:
    max: 200      # длинные base64-значения SealedSecret
  truthy:
    allowed-values: ['true', 'false']   # запрет yes/no
  comments:
    min-spaces-from-content: 1
  document-start: disable

Джоб падает быстро, ещё до валидации Kubernetes-манифестов.


Валидация Kustomize

По одному джобу на окружение:

yamlkustomize-validate-dev:
  stage: validate:kustomize
  image: registry.example.com/bitnami/kubectl:latest
  script:
    - kubectl kustomize fluxcd/projects/dev/kustomization/hub/
    - kubectl kustomize fluxcd/projects/dev/kustomization/spoke/
    - kubectl kustomize fluxcd/projects/dev/kustomization/routes/
    - kubectl kustomize fluxcd/projects/dev/kustomization/spoke/monitoring/

Ловит:

  • Отсутствующие файлы kustomization.yaml
  • Некорректные ссылки в resources:
  • Несоответствие селекторов патчей
  • Невалидный YAML в values HelmRelease

Terraform validate

yamlterraform-validate-dev:
  stage: validate:terraform
  image: registry.example.com/hashicorp/terraform:1.x
  script:
    - cd terraform/dev
    - terraform init -backend=false
    - terraform validate

-backend=false — без подключения к бэкенду состояния: проверяются только синтаксис и схема провайдера.


Flux reconcile (авто на main)

yamlflux-sync:
  stage: reconcile:flux
  image: registry.example.com/fluxcd/flux-cli:v2.8.3
  interruptible: false
  script:
    - flux reconcile source git flux-system -n flux-system --context=infra-k8s
  rules:
    - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH

Только при пушах в main. KUBECONFIG указывает на .kubeconfigs/infra.yaml в репозитории (только endpoint hub-кластера, кластер за VPN).


Ручной reconcile по окружениям

yamlreconcile-dev:
  stage: reconcile:envs
  when: manual
  image: registry.example.com/fluxcd/flux-cli:v2.8.3
  script:
    - flux reconcile ks dev-apps             -n dev --context=infra-k8s --timeout=5m
    - flux reconcile ks dev-spoke            -n dev --context=infra-k8s --timeout=5m
    - flux reconcile ks dev-monitoring-spoke -n dev --context=infra-k8s --timeout=5m
    - flux reconcile ks dev-routes           -n dev --context=infra-k8s --timeout=5m

Полезно после большой пачки изменений, когда не хочется ждать минутный интервал Flux.


Правила workflow

yamlworkflow:
  auto_cancel:
    on_new_commit: interruptible
  rules:
    - if: $CI_MERGE_REQUEST_ID
    - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
    - when: never

auto_cancel: on_new_commit: interruptible — lint и kustomize-validate отменяются при новом коммите. flux-sync — не отменяется.


Уведомления

yamlnotify:success:
  stage: notify
  when: on_success
  variables:
    STATUS_ICON: "✅"
    STATUS_LABEL: SUCCESS

notify:failure:
  stage: notify
  when: on_failure
  variables:
    STATUS_ICON: "❌"
    STATUS_LABEL: FAILED

Оба наследуют .notify — он отправляет сообщения в Telegram и Mattermost. Telegram — через HTTP-прокси: у on-prem раннера нет прямого доступа к api.telegram.org.


Настройка runner

Все джобы используют тег office-dind — on-prem GitLab Runner с Docker-in-Docker. Образы из внутреннего Artifactory.

GIT_DEPTH: "1" для большинства джобов. SonarQube переопределяет на GIT_DEPTH: "0" для git blame.


Граф зависимостей джобов

yamllint
  └─> kustomize-validate-*
        └─> flux-sync (авто)
              └─> reconcile-* (ручной)
                    └─> notify

Если yamllint падает, валидация Kustomize пропускается.