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 пропускается.