Как код применяется к инфраструктуре и запускается в проектах с использованием CI/CD

«Как код применяется к инфраструктуре и запускается в проектах с использованием CI/CD» — вопрос из категории CI/CD, который задают на 23% собеседований Devops Инженер. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

В современных DevOps-практиках код приложения и код инфраструктуры (IaC) проходят единый автоматизированный конвейер CI/CD, который обеспечивает их согласованное и надежное развертывание.

Типичный пайплайн для микросервиса в Kubernetes:

# .gitlab-ci.yml (или Jenkinsfile, GitHub Actions)
stages:
  - validate    # Валидация кода инфраструктуры
  - test        # Тесты приложения
  - build       # Сборка артефакта
  - scan        # Сканирование безопасности
  - deploy-infra # Деплой инфраструктуры (если нужно)
  - deploy-app  # Деплой приложения
  - smoke-test  # Дымовое тестирование

variables:
  K8S_NAMESPACE: "staging"
  APP_IMAGE: "$CI_REGISTRY_IMAGE:$CI_COMMIT_SHA"

# 1. ВАЛИДАЦИЯ: Проверяем корректность манифестов Kubernetes и Terraform
validate_k8s:
  stage: validate
  script:
    - kubectl apply --dry-run=client -f k8s/manifests/
    - terraform -chdir=infra/ init -backend=false
    - terraform -chdir=infra/ validate

# 2. ТЕСТЫ и СБОРКА: Тестируем и собираем Docker-образ
unit_test:
  stage: test
  script:
    - npm run test:ci

build_image:
  stage: build
  script:
    - docker build --pull -t $APP_IMAGE .
    - docker push $APP_IMAGE

# 3. ДЕПЛОЙ: Обновляем инфраструктуру и приложение
deploy_to_staging:
  stage: deploy-app
  script:
    # Используем Kustomize или Helm для подстановки тега образа
    - sed -i "s|__IMAGE_TAG__|$CI_COMMIT_SHA|g" k8s/manifests/deployment.yaml
    - kubectl apply -f k8s/manifests/ -n $K8S_NAMESPACE
    - kubectl rollout status deployment/my-app -n $K8S_NAMESPACE --timeout=120s
  environment:
    name: staging
    url: https://staging.myapp.com

# 4. ДЕПЛОЙ В PROD (ручное подтверждение)
deploy_to_prod:
  stage: deploy-app
  script:
    - kubectl apply -f k8s/manifests/ -n production
    - kubectl rollout status deployment/my-app -n production --timeout=180s
  environment:
    name: production
    url: https://myapp.com
  when: manual
  only:
    - main

Ключевые принципы:

  1. Everything as Code: Манифесты K8s, конфигурации Terraform/Ansible, пайплайны — все хранится в Git.
  2. Идемпотентность: Деплой инфраструктуры через Terraform и приложения через kubectl apply можно запускать многократно с одинаковым результатом.
  3. Неизменяемые артефакты: Собирается один Docker-образ с уникальным тегом (например, хэш коммита), который промоутится по всем средам. Конфигурация инжектируется через переменные окружения или ConfigMaps/Secrets.
  4. Стратегии деплоя: Для минимизации downtime в K8s используем стратегию RollingUpdate, а для более сложных сценариев — blue-green или canary-деплой, настраиваемые через сервис-меши (Istio) или инструменты вроде Flagger.
  5. Деплой инфраструктуры: Изменения в инфраструктуре (добавление ноды, изменение Security Group) также проходят через CI/CD: план (terraform plan) проверяется, а применение (terraform apply) часто требует мануального подтверждения для production.