Проблема з "робимо DevOps"
Кожна інженерна організація, до якої ми заходимо, каже те саме: "ми робимо DevOps". Потім ми дивимось на пайплайн і знаходимо 14 manual approval gates, Jenkins-машину, якою ніхто не володіє, і скрипт deploy.sh із TODO з 2022 року. DevOps — це не команда, інструмент чи посада. Це набір інженерних практик, що скорочують feedback loop між написанням коду і його роботою у продакшні — безпечно, повторювано і без героїзму.
Цей посібник для команд, які переросли стадію "script-and-pray", але ще не збудували delivery pipeline, якому довіряють. Ми пропустимо маніфест і перейдемо до того, що вам реально треба збудувати, у якому порядку і з якими інструментами. Стек, на який ми посилаємось, актуальний на початок 2026 року.
Чому це все ще має значення у 2026
Звіт DORA 2025 знову показав той самий патерн: elite performers деплоять кілька разів на день, відновлюються після інцидентів менше ніж за годину і мають change failure rate нижче 5%. Low performers деплоять щомісяця, відновлюються днями і провалюються у третині випадків. Розрив між ними не має нічого спільного з розміром команди чи вибором технології. Він корелює майже повністю з чотирма метриками:
- Deployment frequency — як часто ви відправляєте код у продакшн
- Lead time for changes — тривалість від коміту до продакшну
- Change failure rate — відсоток деплоїв, що спричиняють інциденти
- Mean time to recovery (MTTR) — скільки часу до повернення в зелене
Якщо ви нічого іншого не вимірюєте, виміряйте ці чотири. Вони — north star. Усе в цій статті або рухає одну з них, або сходить з дороги.
Чотири capability loops
Думайте про DevOps як про чотири вкладені loops, кожен достатньо короткий, щоб feedback-сигнал повернувся до того, як ви забули, навіщо почали.
| Loop | Тривалість | Що ви дізнаєтесь |
|---|---|---|
| Local dev | секунди | Чи компілюється мій код і чи проходить unit-тести? |
| CI | хвилини | Чи інтегрується з main? Є регрес? |
| Pre-prod | десятки хвилин | Чи проходить інтеграційні та security-тести? |
| Production | години-дні | Чи тримається під реальним трафіком? |
Здорова організація інвестує в усі чотири. Зламана організація має десятихвилинний local loop, сорокахвилинний CI, ніякого pre-prod і страшний прод-деплой. Виправляйте найгірший першим.
Capability 1: Source control та trunk-based development
Почніть з нудного. Якщо у вас довгоживучі feature-гілки, що сидять тижнями до мерджу, нічого downstream вас не врятує. Trunk-based development з короткими гілками (< 24 години) і feature flags — єдиний патерн, який ми рекомендуємо командам більше ніж п'яти людей.
Правила бранчів, які ми примушуємо в кожного клієнта:
mainзавжди деплойний. Якщо ні — зупиніть лінію.- PR мерджаться менше ніж за день. Якщо PR сидить тиждень — розділіть його.
- Ніяких прямих пушів у
main. Усе через review і CI. - Feature flags (LaunchDarkly, Unleash або OpenFeature) розв'язують deploy і release.
Capability 2: Continuous Integration
CI — перше місце, де більшість команд помиляються. Вони або причіплюють одну "run tests" роботу, або будують workflow на 2000 рядків, якого ніхто не розуміє. Націлюйтесь на середину.
Ось мінімальний, але production-ready пайплайн GitHub Actions для Node.js сервісу. Він кешує залежності, запускає type checks, unit-тести, security scans, будує контейнер і пушить у registry:
name: CI
on:
push:
branches: [main]
pull_request:
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
test:
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: "20"
cache: "pnpm"
- run: corepack enable
- run: pnpm install --frozen-lockfile
- run: pnpm run lint
- run: pnpm run typecheck
- run: pnpm run test --coverage
- uses: codecov/codecov-action@v4
security:
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v4
- uses: aquasecurity/[email protected]
with:
scan-type: fs
severity: HIGH,CRITICAL
exit-code: "1"
build:
needs: [test, security]
if: github.ref == 'refs/heads/main'
runs-on: ubuntu-24.04
permissions:
id-token: write
contents: read
steps:
- uses: actions/checkout@v4
- uses: docker/setup-buildx-action@v3
- uses: aws-actions/configure-aws-credentials@v4
with:
role-to-assume: arn:aws:iam::123456789012:role/github-actions-ci
aws-region: eu-west-1
- uses: aws-actions/amazon-ecr-login@v2
id: ecr
- uses: docker/build-push-action@v6
with:
push: true
tags: |
${{ steps.ecr.outputs.registry }}/api:${{ github.sha }}
${{ steps.ecr.outputs.registry }}/api:latest
cache-from: type=gha
cache-to: type=gha,mode=max
Дві речі, що не обговорюються. По-перше, OIDC-based AWS auth — ніяких довгоживучих access keys у secrets. По-друге, concurrency скасовує застарілі runs, щоб зайнятий PR не з'їв ваш бюджет на runners.
Capability 3: Continuous Delivery та Deployment
CD — це там, де "ми автоматизували білд" перетворюється на "ми автоматизували бізнес-ризик". Різниця важлива. Continuous delivery означає, що кожен зелений коміт міг би піти у продакшн. Continuous deployment означає, що кожен зелений коміт іде у продакшн. Починайте з першого і випускайтесь у друге, щойно довіряєте сигналу.
Виберіть модель деплою
Три моделі домінують у 2026:
- GitOps з ArgoCD або Flux — декларативний стан у Git, реконсильований контролером. Наш дефолт для Kubernetes.
- Push-based CI/CD — пайплайн викликає
kubectl applyчи подібне. Простіше, але auditability страждає. - PaaS абстракції — Cloud Run, Fly.io, Render. Чудово для малих команд, що хочуть лишитись поза YAML-бізнесом.
GitOps виграє, коли у вас кілька кластерів, жорсткий контроль змін або аудитор, який хоче бачити, хто що і коли змінив.
Progressive delivery за замовчуванням
Відправляйте за стратегією canary чи blue-green з першого дня. Rolling update — це дефолт у Kubernetes, але він майже не дає безпеки. З Argo Rollouts ви отримуєте декларативний canary у кілька рядків:
apiVersion: argoproj.io/v1alpha1
kind: Rollout
metadata:
name: api
spec:
replicas: 6
strategy:
canary:
canaryService: api-canary
stableService: api-stable
trafficRouting:
istio:
virtualService:
name: api
routes: [primary]
steps:
- setWeight: 10
- pause: { duration: 2m }
- analysis:
templates:
- templateName: success-rate
- setWeight: 50
- pause: { duration: 5m }
Крок analysis запитує Prometheus і автоматично перериває rollout, якщо error rate зростає. Це найвисоковажіль зміна, яку може зробити більшість команд: припиніть ставитись до rollback як до manual escalation і дозвольте пайплайну робити це за вас.
Capability 4: Infrastructure as Code
Якщо ваше продакшн-середовище не може бути відтворене з Git-репозиторію, у вас немає інфраструктури — у вас є артефакт. IaC — це лінія між цими двома. Ми використовуємо Terraform для 90% проєктів, OpenTofu для клієнтів, яких турбує fork, і Pulumi для шопів, які дійсно віддають перевагу мовам програмування.
Мінімальна життєздатна розкладка IaC для малої команди:
infra/
├── modules/
│ ├── network/
│ ├── eks/
│ └── rds/
├── envs/
│ ├── dev/
│ ├── staging/
│ └── prod/
└── .github/workflows/terraform.yaml
А ось невеликий модуль, що створює S3 бакет з розумними дефолтами. Зверніть увагу на validation, versioning, public-access block і tags — жодне з цього не є опціональним для продакшн-бакета у 2026 році:
variable "name" {
type = string
description = "Bucket name suffix. Will be prefixed with environment."
validation {
condition = can(regex("^[a-z0-9-]{3,40}$", var.name))
error_message = "Name must be lowercase alphanumeric with dashes, 3-40 chars."
}
}
variable "environment" {
type = string
}
resource "aws_s3_bucket" "this" {
bucket = "${var.environment}-${var.name}"
force_destroy = var.environment != "prod"
tags = {
Environment = var.environment
ManagedBy = "terraform"
Module = "s3-bucket"
}
}
resource "aws_s3_bucket_versioning" "this" {
bucket = aws_s3_bucket.this.id
versioning_configuration {
status = "Enabled"
}
}
resource "aws_s3_bucket_public_access_block" "this" {
bucket = aws_s3_bucket.this.id
block_public_acls = true
block_public_policy = true
ignore_public_acls = true
restrict_public_buckets = true
}
resource "aws_s3_bucket_server_side_encryption_configuration" "this" {
bucket = aws_s3_bucket.this.id
rule {
apply_server_side_encryption_by_default {
sse_algorithm = "AES256"
}
}
}
Plan у PR, Apply на merge
Запускайте terraform plan на кожному pull request і постіть вивід як коментар. Запускайте terraform apply лише коли PR мерджиться у main. Це дає рев'юверам той самий вигляд "що насправді зміниться", який вони отримують з code diff.
Capability 5: Observability
Ви не можете експлуатувати те, чого не бачите. Три стовпи — це metrics, logs та traces, але чесний порядок пріоритету для нової команди:
- Структуровані логи першими. Якщо ваші логи не JSON, виправте це раніше за все.
- RED метрики другими. Rate, Errors, Duration per endpoint. Prometheus плюс Grafana-дашборд дають вам 80% цінності за післяобідній час.
- Traces, коли у вас більше трьох сервісів. OpenTelemetry SDK, OTLP exporter і бекенд на вибір (Tempo, Honeycomb, Datadog).
Єдиний шматок телеметричного коду, з яким має відправлятися кожен сервіс:
import { NodeSDK } from "@opentelemetry/sdk-node";
import { OTLPTraceExporter } from "@opentelemetry/exporter-trace-otlp-http";
import { getNodeAutoInstrumentations } from "@opentelemetry/auto-instrumentations-node";
import { resourceFromAttributes } from "@opentelemetry/resources";
import { ATTR_SERVICE_NAME, ATTR_SERVICE_VERSION } from "@opentelemetry/semantic-conventions";
const sdk = new NodeSDK({
resource: resourceFromAttributes({
[ATTR_SERVICE_NAME]: process.env.OTEL_SERVICE_NAME ?? "api",
[ATTR_SERVICE_VERSION]: process.env.GIT_SHA ?? "dev",
}),
traceExporter: new OTLPTraceExporter({
url: process.env.OTEL_EXPORTER_OTLP_ENDPOINT,
}),
instrumentations: [getNodeAutoInstrumentations()],
});
sdk.start();
process.on("SIGTERM", () => {
sdk.shutdown().finally(() => process.exit(0));
});
Щойно traces течуть, налаштуйте SLO. 99.9% availability SLO на публічний API з 30-денним вікном дає вам 43-хвилинний error budget. Якщо ви його спалюєте, припиняйте відправляти фічі і виправляйте reliability debt. Це найпотужніший важіль для вирівнювання пріоритетів продукту і SRE.
Культура: частина, яку не можна terraform apply
Кожен engineering leader, з яким ми працювали, недооцінив культурний бік переходу. Інструменти — легка частина. Важка — переконати команду погодитись, що:
- Спільний on-call — не покарання; це фідбек.
- Postmortems blameless, письмові і читаються усіма.
- "У мене працює" — це баг-репорт, а не виправдання.
- Розробник володіє продакшн-поведінкою свого коду.
Ви не можете це купити. Ви можете лише моделювати. Найшвидший шлях, який ми бачили, коли engineering leadership бере першу on-call зміну з командою, володіє першим postmortem і публічно дякує людині, що знайшла власний баг.
Стартовий план на дванадцять тижнів
Для команди, що починає близько до нуля, ось послідовність, яку ми б рекомендували.
Тижні 1-2: Baseline. Виміряйте чотири DORA метрики. Ви не можете виправити те, що не вимірюєте. Також аудитуйте кожен manual крок від коміту до прода — запишіть на дошці.
Тижні 3-4: CI. Виберіть один сервіс. Збудуйте зелений CI з тестами, lint, typecheck, security scan, container build. Більше нічого поки що.
Тижні 5-6: CD до staging. Автоматизуйте деплой у staging environment. Якщо у вас немає staging — створіть його через IaC.
Тижні 7-8: IaC для одного середовища. Перебудуйте staging з Terraform. Це виявить багато configuration drift. Виправте.
Тижні 9-10: Observability. Структуровані логи, RED метрики, один SLO, одна сторінка алертів. Направте алерти на командний PagerDuty чи Opsgenie.
Тижні 11-12: Прод. Промоутьте пайплайн у продакшн. Гейтуйте canary. Проведіть game day. Відсвяткуйте перший автоматичний rollback.
Наступні кроки
DevOps не завершений за дванадцять тижнів — він ніколи не завершений. Але за дванадцять тижнів команда може перейти з "ми деплоїмо у п'ятницю і молимось" до "ми деплоїмо щогодини, і пайплайн ловить власні помилки". Звідти наступний фронтир — зазвичай platform engineering: перетворити цей пайплайн на golden path, яким можуть користуватися інші команди.
Якщо хочете допомоги пройти від нуля до trunk-based, production-grade CD на реальному стеку, напишіть нам. Ми робимо цю роботу поруч із вашою командою і передаємо її, щойно ви нею володієте.