Списком
DevOps — це культура, що зближує розробку (Dev) та операції (Ops) для прискорення доставки програмного забезпечення без жертви якістю та надійністю. CI/CD є технологічним втіленням DevOps: автоматизований пайплайн, що перетворює кожну зміну коду на Production-готовий артефакт. Хмарні провайдери пропонують повністю інтегровані CI/CD-платформи, що усувають потребу у самостійному хостингу Jenkins та подібних інструментів.
DevOps — культурний та технічний рух, що об’єднує практики розробки, безпеки та операційної діяльності з метою скорочення циклу доставки програмного забезпечення при збереженні або підвищенні його надійності.
Ключові принципи DevOps:
Організація DORA (DevOps Research and Assessment, тепер частина Google) визначила 4 ключові показники ефективності DevOps:
| Метрика | Elite performers | High | Medium | Low |
|---|---|---|---|---|
| Deployment Frequency (DF) | Кілька разів/день | Раз/тиждень–місяць | Раз/місяць–квартал | Раз/квартал і рідше |
| Lead Time for Changes | < 1 години | 1 день–1 тиждень | 1 тиждень–1 місяць | > 6 місяців |
| Change Failure Rate (CFR) | 0–15% | 16–30% | 16–30% | 46–60% |
| MTTR | < 1 години | < 1 дня | 1 день–1 тиждень | > 6 місяців |
Висновок DORA: Elite DevOps-команди випускають 46× частіше і відновлюються після інцидентів 2604× швидше, ніж Low-performers.
Continuous Integration (CI) — практика, за якої розробники часто (кілька разів на день) інтегрують свій код у спільну гілку, а кожна інтеграція автоматично перевіряється збіркою та тестами.
CI Pipeline — типові кроки:
git push → Trigger
│
├── 1. Source Checkout (клонування репозиторію)
├── 2. Install Dependencies (npm install / pip install)
├── 3. Lint & Code Style (ESLint, flake8, gofmt)
├── 4. SAST (static security: SonarQube, Semgrep, Snyk)
├── 5. Unit Tests (pytest, JUnit, Jest)
├── 6. Integration Tests
├── 7. Build (docker build, maven package)
├── 8. Container Scanning (Trivy, ECR Scan)
└── 9. Push Artifact to Registry (ECR, DockerHub)
«Fail Fast» принцип: швидкі перевірки (lint, unit tests) виконуються першими. Якщо вони впали — не витрачаємо час на повільні інтеграційні тести.
GitHub Actions — найпопулярніша CI/CD платформа, інтегрована у GitHub.
name: CI Pipeline
on:
pull_request:
branches: [main]
push:
branches: [main]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: "3.11"
- name: Install dependencies
run: pip install -r requirements.txt
- name: Run linting
run: flake8 src/ tests/
- name: Run tests with coverage
run: pytest --cov=src tests/ --cov-report=xml
- name: Upload coverage to Codecov
uses: codecov/codecov-action@v3
build-and-push:
needs: test
runs-on: ubuntu-latest
if: github.ref == 'refs/heads/main'
steps:
- uses: actions/checkout@v4
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v4
with:
aws-access-key-id: $
aws-secret-access-key: $
- name: Login to Amazon ECR
id: login-ecr
uses: aws-actions/amazon-ecr-login@v2
- name: Build and push Docker image
run: |
docker build -t $ECR_REGISTRY/myapp:$GITHUB_SHA .
docker push $ECR_REGISTRY/myapp:$GITHUB_SHA
Continuous Delivery (CD):
Continuous Deployment:
AWS CodePipeline — оркестратор пайплайну:
Source (CodeCommit/Github)
│
▼ CodeBuild (build & test)
│
▼ Manual Approval (опціонально)
│
▼ CodeDeploy (deploy to EC2/ECS/Lambda)
AWS CodeBuild — керований сервіс збірки:
buildspec.yml)AWS CodeDeploy — автоматизований деплоймент на EC2, Lambda або ECS:
Azure DevOps — повна DevOps-платформа Microsoft (Boards, Repos, Pipelines, Artifacts, Test Plans):
# azure-pipelines.yml
trigger:
branches:
include: [main]
pool:
vmImage: "ubuntu-latest"
stages:
- stage: Build
jobs:
- job: BuildJob
steps:
- task: Docker@2
inputs:
command: "buildAndPush"
repository: "myapp"
containerRegistry: "myACR"
- stage: Deploy
condition: and(succeeded(), eq(variables['Build.SourceBranch'], 'refs/heads/main'))
jobs:
- deployment: DeployProd
environment: "production"
strategy:
runOnce:
deploy:
steps:
- task: KubernetesManifest@1
inputs:
action: "deploy"
manifests: "$(Pipeline.Workspace)/drop/*.yaml"
Google Cloud Build — серверний CI/CD-сервіс GCP.
Особливість: кожен крок пайплайну — Docker-образ. Можна використовувати будь-який Docker-образ як кроку.
Make — утиліта автоматизації збірки, що існує з 1976 року. Попри вік, вона стала де-факто стандартом DevOps-інтерфейсу для проєктів будь-якого розміру. Причина проста: Makefile дозволяє будь-якому новому розробнику або CI-системі запустити складну послідовність команд одним словом — make build, make deploy, make test — без необхідності читати README.
Чому Makefile у CI/CD:
make ci, а не десятки окремих командmake help показує всі доступні ціліmake deploy → спочатку make build# Базовий синтаксис:
<ціль>: [залежності]
[TAB]<команда 1>
[TAB]<команда 2>
⚠️ Критично важливо: відступ перед командою — це символ TAB (не пробіли). Це найпоширеніша помилка при написанні Makefile.
Ключові конструкції:
# Змінні
APP_NAME := myapp
IMAGE_NAME := $(APP_NAME):$(shell git rev-parse --short HEAD)
REGISTRY := 123456789.dkr.ecr.us-east-1.amazonaws.com
# .PHONY — оголошення псевдоцілей (не файлів)
# Без .PHONY: якщо є файл з іменем 'build' — make не виконає ціль
.PHONY: build test deploy clean help
# Ціль з залежністю
deploy: build test
$(MAKE) push
$(MAKE) rollout
# Ціль з умовою
check-env:
@test -n "$(AWS_REGION)" || (echo "ERROR: AWS_REGION не встановлено" && exit 1)
# Автодокументування через коментарі ##
help: ## Показати доступні команди
@grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | \
awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-20s\033[0m %s\n", $$1, $$2}'
Повний Makefile для хмарного проєкту (Terraform + Docker + K8s):
# =============================================================================
# Налаштування
# =============================================================================
APP_NAME := myapp
ENV ?= dev # можна перевизначити: make deploy ENV=prod
AWS_REGION ?= us-east-1
ACCOUNT_ID := $(shell aws sts get-caller-identity --query Account --output text)
REGISTRY := $(ACCOUNT_ID).dkr.ecr.$(AWS_REGION).amazonaws.com
IMAGE_TAG := $(shell git rev-parse --short HEAD)
FULL_IMAGE := $(REGISTRY)/$(APP_NAME):$(IMAGE_TAG)
.PHONY: help build test lint push deploy destroy clean fmt validate plan apply
# =============================================================================
# Документація
# =============================================================================
help: ## Показати всі доступні команди
@echo "\nДоступні команди для проєкту $(APP_NAME):"
@grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | \
awk 'BEGIN {FS = ":.*?## "}; {printf " \033[36m%-18s\033[0m %s\n", $$1, $$2}'
@echo ""
# =============================================================================
# Якість коду
# =============================================================================
lint: ## Запустити linting (eslint / flake8)
@echo "→ Linting..."
npx eslint src/
test: ## Запустити unit-тести
@echo "→ Testing..."
npm test -- --coverage
security-scan: ## Сканування вразливостей (Trivy)
trivy image $(FULL_IMAGE)
# =============================================================================
# Docker
# =============================================================================
build: ## Зібрати Docker-образ
@echo "→ Building $(FULL_IMAGE)..."
docker build \
--build-arg GIT_COMMIT=$(IMAGE_TAG) \
--build-arg BUILD_DATE=$(shell date -u +%Y-%m-%dT%H:%M:%SZ) \
-t $(FULL_IMAGE) \
-t $(REGISTRY)/$(APP_NAME):latest \
.
push: build ## Завантажити образ в ECR
@echo "→ Logging into ECR..."
aws ecr get-login-password --region $(AWS_REGION) | \
docker login --username AWS --password-stdin $(REGISTRY)
@echo "→ Pushing $(FULL_IMAGE)..."
docker push $(FULL_IMAGE)
docker push $(REGISTRY)/$(APP_NAME):latest
# =============================================================================
# Terraform
# =============================================================================
TF_DIR := terraform/envs/$(ENV)
fmt: ## Форматувати Terraform-файли
terraform -chdir=$(TF_DIR) fmt -recursive
validate: fmt ## Перевірити коректність Terraform-конфігурації
terraform -chdir=$(TF_DIR) init -backend=false
terraform -chdir=$(TF_DIR) validate
plan: ## Переглянути зміни (terraform plan)
terraform -chdir=$(TF_DIR) init
terraform -chdir=$(TF_DIR) plan -var="image_tag=$(IMAGE_TAG)" -out=tfplan
apply: plan ## Застосувати зміни (terraform apply)
terraform -chdir=$(TF_DIR) apply tfplan
destroy: ## Знищити інфраструктуру
@echo "⚠️ ПОПЕРЕДЖЕННЯ: видалення $(ENV) інфраструктури!"
@read -p "Введіть назву середовища для підтвердження: " confirm; \
test "$$confirm" = "$(ENV)" || (echo "Скасовано" && exit 1)
terraform -chdir=$(TF_DIR) destroy -var="image_tag=$(IMAGE_TAG)"
# =============================================================================
# Kubernetes
# =============================================================================
rollout: ## Оновити K8s Deployment
kubectl set image deployment/$(APP_NAME) \
$(APP_NAME)=$(FULL_IMAGE) \
--namespace=$(ENV)
kubectl rollout status deployment/$(APP_NAME) --namespace=$(ENV)
rollback: ## Відкотити попередню версію
kubectl rollout undo deployment/$(APP_NAME) --namespace=$(ENV)
# =============================================================================
# Повний CI pipeline (використовується у GitHub Actions)
# =============================================================================
ci: lint test build security-scan ## Повний CI pipeline
@echo "✓ CI pipeline завершено успішно"
# =============================================================================
# Очищення
# =============================================================================
clean: ## Видалити локальні артефакти
@echo "→ Cleaning..."
rm -rf node_modules dist coverage .terraform tfplan
docker image prune -f
Makefile і CI-пайплайн доповнюють одне одного: CI викликає Make-цілі, а не окремі команди. Це гарантує, що CI та локальне середовище поводяться ідентично:
# .github/workflows/ci.yml
name: CI/CD Pipeline
on:
push:
branches: [main]
pull_request:
branches: [main]
jobs:
ci:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up Node.js
uses: actions/setup-node@v4
with:
node-version: "20"
cache: "npm"
- name: Install dependencies
run: npm ci
# Замість окремих команд — одна Make-ціль:
- name: Run CI pipeline
run: make ci # ← lint + test + build + security-scan
- name: Push to ECR
if: github.ref == 'refs/heads/main'
env:
AWS_ACCESS_KEY_ID: $
AWS_SECRET_ACCESS_KEY: $
run: make push # ← build + ecr-login + docker push
- name: Deploy to production
if: github.ref == 'refs/heads/main'
run: make deploy ENV=prod # ← terraform apply + kubectl rollout
Переваги такого підходу:
make cigit clone → make help → make ciНайкращі практики написання Makefile:
| Практика | Приклад | Чому важливо |
|---|---|---|
Завжди оголошувати .PHONY |
.PHONY: build test |
Уникнути конфліктів з файлами |
Використовувати @ для тихих команд |
@echo "→ Building..." |
Чистий output без дублювання команди |
| Параметризувати через змінні | ENV ?= dev |
make deploy ENV=prod |
?= для змінних за замовчуванням |
AWS_REGION ?= us-east-1 |
Можна перевизначити з оточення |
Ціль help з ##-коментарями |
Автодокументування | Новий розробник одразу розуміє API |
| Перевіряти обов’язкові змінні | test -n "$(VAR)" |
Fail fast з зрозумілим повідомленням |
| Підтвердження для деструктивних операцій | read -p "Підтвердіть: " |
Захист від make destroy у prod |
v1 v1 v1 v1 v1 → v2 v1 v1 v1 v1 → v2 v2 v1 v1 v1 → v2 v2 v2 v2 v2
Blue (v1) ────── prod traffic ──── [ALB]
Green (v2) ────── тестування [ALB]
│
Switch traffic ▼
Blue (v1) ────── (резерв для rollback)
Green (v2) ────── prod traffic ──── [ALB]
Canary: v2 (5% трафіку) ──► моніторинг: error rate, latency
Main: v1 (95% трафіку)
Якщо метрики OK:
Canary: v2 (25% трафіку)
Canary: v2 (50% трафіку)
Canary: v2 (100% трафіку) → деплоймент завершено
GitOps — підхід, за якого Git-репозиторій є єдиним джерелом істини для стану інфраструктури та застосунку:
ArgoCD — найпопулярніший GitOps-оператор для Kubernetes.
DevOps — культура та набір практик, що прискорює доставку при збереженні надійності. DORA Metrics дозволяють об’єктивно виміряти ефективність DevOps-трансформації.
CI Pipeline автоматично перевіряє якість кожної зміни: lint, тести, security scanning, збірка артефакту. «Fail Fast» принцип мінімізує час отримання зворотного зв’язку.
CD Pipeline автоматизує доставку верифікованих артефактів у середовища. Continuous Delivery (з ручним підтвердженням Production) та Continuous Deployment (повністю автоматично) — два рівні зрілості.
Makefile є стандартизованим DevOps-інтерфейсом, що забезпечує єдиний point of entry для CI-систем і розробників. Інтеграція Makefile з GitHub Actions гарантує ідентичне виконання пайплайну локально та в CI.
Стратегії деплойменту (Rolling, Blue/Green, Canary) дозволяють знизити ризик під час оновлень. Canary є найбезпечнішим, але найскладнішим; Blue/Green — простим і передбачуваним.
GitOps (ArgoCD) робить Git єдиним джерелом істини для стану K8s-кластера — будь-яка «дрейф» конфігурації автоматично виправляється.
buildspec.yml в AWS CodeBuild та azure-pipelines.yml?.PHONY у Makefile? Що відбудеться, якщо її не вказати?make ci у GitHub Actions краще, ніж прямий виклик команд у YAML.