На каком этапе CI/CD пайплайна подготавливается инфраструктура для развертывания приложения?

Ответ

Подготовка инфраструктуры (Provisioning) обычно выполняется до основного CI/CD пайплайна приложения или в его отдельной, выделенной стадии, часто называемой infrastructure или deploy-infra. Это делается для разделения ответственности и повышения стабильности: инфраструктура должна быть готова и проверена до попыток деплоя кода.

Типичный подход "Инфраструктура как код" (IaC):

  1. Отдельный пайплайн/репозиторий: Инфраструктура (VPC, сети, кластер Kubernetes, базы данных) описывается в коде (Terraform, CloudFormation) и разворачивается через свой собственный CI/CD пайплайн. Изменения в инфраструктуре проходят свой код-ревью и план применения.
  2. Стадия в основном пайплайне: В некоторых подходах стадия подготовки инфраструктуры (например, создание/обновление временного окружения для тестирования) может быть частью основного пайплайна приложения.

Пример структуры пайплайна GitLab CI для приложения в K8s:

stages:
  - build
  - test
  - deploy-infra  # Стадия подготовки инфраструктуры
  - deploy-app    # Стадия деплоя приложения

# 1. Сборка и тесты приложения
build-and-test:
  stage: build
  script: ...

# 2. ПОДГОТОВКА ИНФРАСТРУКТУРЫ: Развертывание/обновление манифестов K8s
deploy_kubernetes_infra:
  stage: deploy-infra
  script:
    - kubectl apply -f k8s/namespace.yaml
    - kubectl apply -f k8s/configmap.yaml
    - kubectl apply -f k8s/secrets.yaml
  only:
    - main  # Инфраструктура обновляется только при мерже в main

# 3. ДЕПЛОЙ ПРИЛОЖЕНИЯ: Развертывание самого приложения в подготовленную инфраструктуру
deploy_application:
  stage: deploy-app
  script:
    - kubectl set image deployment/my-app app=$CI_REGISTRY_IMAGE:$CI_COMMIT_SHA
  needs: ["deploy_kubernetes_infra"] # Зависит от успешного выполнения стадии инфраструктуры

Ключевые инструменты: Terraform, Pulumi, AWS CloudFormation, Ansible для provisioning; kubectl, Helm — для настройки ресурсов внутри Kubernetes.

Ответ 18+ 🔞

Давай разберём эту тему, а то тут некоторые, как мартышлюшки, пытаются всё в одну кучу свалить. Слушай сюда, чувак.

Представь, что ты строишь дом. Ты же не будешь сначала обои клеить, а потом фундамент заливать? Вот и тут так же. Подготовка инфраструктуры — это как раз заливка фундамента, прокладка коммуникаций, расстановка стен. А деплой приложения — это уже завоз мебели и поклейка обоев. Если стены кривые, то хоть какую дорогую мебель не завози — всё равно будет пиздец.

Так вот, как это обычно делают умные люди:

  1. Отдельная песочница (репозиторий/пайплайн). Самый адекватный подход. Всё, что касается сетей, баз данных, самого кубернетеса — описывается кодом (Terraform, Pulumi) и живёт отдельно. Изменения там проходят свой, отдельный код-ревью и план. Это чтобы какой-нибудь распиздяй из команды разработки не мог по ошибке нахуй удалить продакшен-базу, пытаясь обновить версию своего сервиса. Доверия ебать ноль, поэтому доступы к этому пайплайну строже.
  2. Стадия в основном пайплайне. Часто используется для тестовых окружений. Скажем, на каждый пулл-реквест нужно поднять временный стенд. Вот тогда в пайплайне приложения есть стадия, которая сначала на коленке из палок и верёвок (читай: из шаблонов) собирает этот стенд, а уже потом на него деплоит последнюю сборку приложения для проверки. После тестов — всё сносится к ебеням.

Смотри, как это может выглядеть в GitLab CI, если делать по второму варианту (для тестового окружения):

stages:
  - build
  - test
  - deploy-infra  # Вот она, стадия-мать инфраструктуры
  - deploy-app    # А вот уже стадия для самого приложения

# 1. Собираем артефакт и гоняем тесты
build-and-test:
  stage: build
  script: ...

# 2. ПОДГОТОВКА ИНФРАСТРУКТУРЫ: Создаём/обновляем манифесты в K8s
deploy_kubernetes_infra:
  stage: deploy-infra
  script:
    - kubectl apply -f k8s/namespace.yaml
    - kubectl apply -f k8s/configmap.yaml
    - kubectl apply -f k8s/secrets.yaml
  only:
    - main  # Постоянную инфраструктуру трогаем только когда всё сливается в main

# 3. ДЕПЛОЙ ПРИЛОЖЕНИЯ: Теперь тащим нашу сборку в подготовленное место
deploy_application:
  stage: deploy-app
  script:
    - kubectl set image deployment/my-app app=$CI_REGISTRY_IMAGE:$CI_COMMIT_SHA
  needs: ["deploy_kubernetes_infra"] # Ждём, пока инфраструктура не будет готова. Без этого — ни хуя!

Какие инструменты в ходу? Для создания самого "фундамента" (серверов, сетей) — Terraform, Pulumi, CloudFormation. Это мощные штуки, они могут нахуй снести пол-облака, если неаккуратно ткнуть. А для настройки уже внутри готового кубернетеса (создания неймспейсов, конфигов) — kubectl, Helm, Ansible. Это уже более тонкая работа.

Короче, суть в чём: разделяй и властвуй. Сначала убедись, что твоя платформа стабильна и готова (инфраструктура), а потом уже запускай на неё изменчивый и часто обновляемый код (приложение). Иначе получится хитрая жопа, когда из-за падения базы данных ты будешь искать баг в своём коде, а его там нет. Сам от себя охуеешь, потратив на это полдня.