Архитектор облачной инфраструктуры

Проектирует масштабируемую, безопасную и экономичную облачную архитектуру в AWS, Azure или GCP с IaC и дорожной картой.

// промпт
Действуй как ведущий архитектор облачной инфраструктуры с опытом проектирования продакшн-систем в AWS, Azure и GCP. Твоя задача — спроектировать масштабируемое, безопасное и экономически эффективное решение под мои вводные и обосновать каждое ключевое решение. ## Вводные данные - **Облачный провайдер:** {{cloud_provider}} - **Тип нагрузки:** {{workload_type}} - **Ожидаемый трафик / масштаб:** {{expected_scale}} - **Требования к доступности (SLA/RTO/RPO):** {{availability_requirements}} - **Бюджет / ограничения по затратам:** {{budget_constraints}} - **Требования по соответствию:** {{compliance_requirements}} - **Текущее состояние:** {{current_state}} ## Что нужно спроектировать 1. **Топология инфраструктуры** — многоуровневая архитектура, регионы и зоны доступности, сети (VPC/подсети), вычисления, хранилища и базы данных. Заложи высокую доступность и план аварийного восстановления под заданные RTO/RPO. 2. **Безопасность** — модель IAM по принципу наименьших привилегий, сегментация сети, шифрование в покое и в транзите, управление секретами, соответствие {{compliance_requirements}}. 3. **Масштабируемость и производительность** — авто-масштабирование, балансировка нагрузки, CDN, кэширование, оптимизация БД под целевой масштаб. 4. **DevOps и IaC** — структура Terraform/CloudFormation, организация окружений (dev/stage/prod), CI/CD-пайплайн, стратегия деплоя. 5. **Оптимизация затрат** — подбор типов ресурсов, резервирование/спот, оценка ежемесячной стоимости и приоритетные меры экономии. ## Формат ответа - **Краткое резюме решения** (3-5 предложений) и обоснование выбора сервисов. - **Текстовая диаграмма архитектуры** (ASCII или список компонентов и связей). - **Таблица ключевых сервисов** {{cloud_provider}}: компонент → сервис → назначение. - **Пример IaC-скелета** на Terraform для основных ресурсов. - **Оценка затрат** (ориентировочно, $/месяц) с допущениями. - **Риски и trade-off'ы** и **дорожная карта внедрения** по этапам. Помечай предположения явно. Если вводных не хватает для корректного проектирования — сначала задай уточняющие вопросы, затем предложи архитектуру.
Заполните переменные

Пример запуска

Сгенерировано Claude Opus 5.5, 23 сентября 2026 г.

Значения переменных

Cloud provider
AWS (основной регион — eu-central-1, Франкфурт; DR-регион — eu-west-1, Ирландия)
Workload type
Backend маркетплейса товаров ручной работы (handmade e-commerce): каталог, корзина, заказы, платежи, уведомления — микросервисы на Go и Node.js, REST + GraphQL API, веб- и мобильный клиенты
Expected scale
~250 000 активных пользователей в месяц, обычная нагрузка 150–300 RPS, пиковая (Чёрная пятница, декабрьские распродажи) до 1200 RPS; каталог ~2 млн товарных позиций, БД заказов растёт на ~500 тыс. записей/год; ожидаемый рост общего трафика x3 в течение ближайших 12 месяцев
Availability requirements
Целевой SLA для внешнего API — 99.95% (допустимый простой ~22 минуты в месяц). RTO (Recovery Time Objective) — не более 1 часа для полного восстановления сервиса после отказа региона, RPO (Recovery Point Objective) — не более 15 минут потери данных заказов и платежей. Архитектура должна быть отказоустойчивой минимум в пределах 3 зон доступности (AZ) внутри основного региона eu-central-1, с возможностью ручного или автоматического переключения (failover) на резервный регион eu-west-1 в случае катастрофического отказа. Для критичных данных (заказы, платежи, пользователи) требуется синхронная репликация в пределах региона и асинхронная межрегиональная репликация с лагом не более 5 минут. Плановые технические работы должны проводиться без простоя (zero-downtime deployments, blue/green или canary). Требуется автоматизированное тестирование disaster recovery не реже одного раза в квартал.
Budget constraints
$10 000–12 000 в месяц на облачную инфраструктуру (без учёта ФОТ), допустимо кратковременное превышение до $15 000 в пиковые месяцы (ноябрь–декабрь); приоритет — предсказуемость расходов и возможность прогнозирования на 6 месяцев вперёд
Compliance requirements
Обязательное соответствие GDPR (обработка персональных данных граждан ЕС: имена, адреса доставки, история заказов, email) — требуется хранение и обработка персональных данных исключительно в дата-центрах ЕС, реализация права на удаление данных («право на забвение») с полным удалением из всех бэкапов и логов в течение 30 дней по запросу, ведение журнала доступа к персональным данным сроком не менее 1 года, назначенный DPO (Data Protection Officer). Платежи обрабатываются через Stripe как процессинговый партнёр, поэтому требуется соответствие PCI DSS уровня SAQ A — компания не хранит, не обрабатывает и не передаёт номера карт напрямую, вся чувствительная платёжная информация остаётся на стороне Stripe (используется Stripe Elements/Checkout). Требуется шифрование персональных данных в состоянии покоя (at rest) и при передаче (in transit, TLS 1.2+), а также регулярный (не реже раза в год) внешний аудит безопасности инфраструктуры.
Current state
Монолитное приложение на Ruby on Rails 7, развёрнуто на одном выделенном сервере Hetzner (32 GB RAM, 8 vCPU); PostgreSQL 14 работает на том же сервере без репликации и без автоматических бэкапов, кроме еженедельного ручного дампа; деплой производится вручную через Capistrano разработчиками с локальных машин; CI/CD отсутствует, тесты запускаются локально; мониторинг ограничен базовым UptimeRobot без алертинга по метрикам и без централизованного логирования; команда — 6 инженеров (4 backend, 1 frontend, 1 DevOps на part-time), опыта работы с облачными провайдерами в команде минимальный

Архитектура AWS для handmade-маркетплейса: eu-central-1 (основной) + eu-west-1 (DR)

0. Уточняющие вопросы и принятые допущения

Часть вводных влияет на архитектуру и стоимость, но не указана. Ниже вопросы, а в скобках допущение, с которым я проектирую. Если допущение неверно, скорректируйте его, и я пересчитаю соответствующие разделы.

# Вопрос Допущение [ДОП]
1 Переписывание Rails → Go/Node.js уже идёт или это целевое состояние? [ДОП-1] Это целевое состояние. Сейчас в продакшене Rails-монолит, миграция поэтапная (strangler fig).
2 Объём медиа (фото товаров) и исходящий трафик? [ДОП-2] ~8 ТБ изображений в S3 и ~8 ТБ/мес исходящего трафика через CDN. Это самая неопределённая статья затрат.
3 География пользователей? [ДОП-3] Преимущественно ЕС, мобильные и веб-клиенты.
4 Git-хостинг и CI? [ДОП-4] GitHub + GitHub Actions. Их стоимость не входит в облачный бюджет.
5 Как устроен фронтенд (SPA или SSR)? [ДОП-5] SPA/статическая сборка в S3 + CloudFront. Если нужен SSR (Next.js), он выносится отдельным ECS-сервисом.
6 Есть ли юридическая обязанность хранить счета и заказы (для Германии: HGB/AO, 6–10 лет)? [ДОП-6] Есть. Финансовые записи заказов при запросе на удаление анонимизируются, но не удаляются (исключение по ст. 17(3)(b) GDPR). Решение за DPO и юристом.
7 Провайдер email и push-уведомлений? [ДОП-7] Email через Amazon SES (eu-central-1), push через FCM/APNs без персональных данных в payload.
8 Что входит в «внешний API 99.95%»? [ДОП-8] SLA измеряется на входе (CloudFront/ALB) по успешным ответам API, без учёта деградации внешних зависимостей (Stripe, SES).
9 Уровень поддержки AWS? [ДОП-9] Business Support. При целевом SLA 99.95% это обязательно.

1. Краткое резюме решения

Предлагаю контейнерную архитектуру на ECS Fargate (Graviton/ARM64) в 3 AZ региона eu-central-1. Данные размещаются так:

  • транзакционные данные — в Aurora PostgreSQL (синхронный кворум 4/6 копий в 3 AZ) с Aurora Global Database в eu-west-1 (типичный лаг меньше 1 с при требовании до 5 мин);
  • корзины, сессии и ключи идемпотентности — в DynamoDB Global Tables;
  • кэш — в ElastiCache (Valkey);
  • поиск по каталогу из 2 млн позиций — в OpenSearch.

DR-регион работает в режиме warm standby: минимальная копия сервисов запущена и масштабируется по runbook. Это закрывает RTO 1 ч и RPO 15 мин примерно за 8% бюджета, тогда как active-active обошёлся бы в 1.8–2 раза дороже и был бы на порядок сложнее для команды из 6 человек.

ECS Fargate выбран вместо EKS осознанно. В команде минимальный облачный опыт и один DevOps на part-time, поэтому сопровождение Kubernetes (обновления control plane, add-on'ы, CNI, Karpenter) создаёт операционный риск выше, чем экономия от гибкости K8s. При этом ECS поддерживает нативные blue/green и canary-деплои.

GDPR реализуется через четыре механизма:

  • Service Control Policy (SCP), разрешающие работу только в двух регионах ЕС;
  • отсутствие персональных данных в логах;
  • удержание бэкапов не более 28 дней в сочетании с реестром удалений;
  • оркестратор «права на забвение» на Step Functions.

PCI DSS SAQ A обеспечивается тем, что данные карт никогда не касаются нашей инфраструктуры: используются Stripe Checkout/Elements, а в нашей системе хранятся только токены и идентификаторы Stripe.

Ориентировочная стоимость — ~$11.3K/мес по on-demand ценам и ~$10.2K после покупки обязательств (Savings Plans/RI), в пиковые месяцы — ~$12.8–13.5K.

⚠️ Важно по срокам. Сегодня 23.09.2026, а Чёрная пятница 27.11.2026. Не переносите продакшен в AWS до пика. Перенос для команды без облачного опыта за 2 месяца до максимальной нагрузки — главный риск всего проекта. План на Q4 2026 — укрепить Hetzner (раздел 8, этап 0), а прод-cutover в AWS провести в январе–феврале 2027.


2. Диаграмма архитектуры

2.1 Структура аккаунтов (AWS Organizations + Control Tower)

AWS Organization (management account — только биллинг и Organizations, без нагрузок)
├── OU: Security
│   ├── security-tooling   ← делегированный админ GuardDuty, Security Hub, Config, Macie, Inspector
│   └── log-archive        ← org CloudTrail, VPC Flow Logs, audit-логи доступа к ПДн (S3 Object Lock, 13 мес)
├── OU: Infrastructure
│   └── shared-services    ← ECR (+репликация в eu-west-1), Route 53 hosted zones, роль CI через OIDC
├── OU: Workloads
│   ├── prod     (eu-central-1 = primary, eu-west-1 = DR)
│   ├── stage    (eu-central-1; раз в квартал — DR-учения в eu-west-1)
│   └── dev      (eu-central-1)
└── SCP: запрет регионов вне eu-central-1/eu-west-1, запрет отключения CloudTrail/GuardDuty/Config,
         запрет выхода из организации, запрет создания IAM-пользователей и ключей доступа

2.2 Прод-топология

                         Пользователи (Web SPA / iOS / Android)
                                        │  HTTPS, TLS 1.2+ (предпочтительно 1.3)
                    ┌───────────────────┴──────────────────────┐
                    ▼                                          ▼
   ┌─────────────────────────────────┐        ┌─────────────────────────────────────┐
   │ CloudFront #1: static.example   │        │ CloudFront #2: api.example          │
   │ SPA, изображения (S3 + OAC)     │        │ AWS WAF (managed rules, rate-limit, │
   │ Долгий кэш, WebP/AVIF           │        │ Bot Control), Shield Standard       │
   │ Без ПДн                         │        │ Кэш только для публичного каталога  │
   └───────────────┬─────────────────┘        │ (persisted GraphQL queries, GET)    │
                   │                          └───────────────┬─────────────────────┘
                   ▼                                          │ origin: origin-api.example
          S3 media (eu-central-1)                             ▼
          ──CRR+RTC──► S3 (eu-west-1)          Route 53 failover record + health checks
                                               PRIMARY → ALB euc1 │ SECONDARY → ALB euw1
                                                                  │
╔═════════════════════════════════════════════════════════════════╪══════════════════════════════╗
║ eu-central-1 (PRIMARY) — VPC 10.10.0.0/16 — AZ a / b / c        ▼                              ║
║ ┌─ Public /22 ×3 ──────────────────────────────────────────────────────────────────────────┐   ║
║ │  ALB (HTTPS 443, TLS13-1-2 policy, SG разрешает только CloudFront prefix list)           │   ║
║ │  NAT Gateway ×3 (по одному на AZ)                                                        │   ║
║ └──────────────────────────────────────────────────────────────────────────────────────────┘   ║
║ ┌─ Private-app /19 ×3 ─── ECS Fargate (ARM64), задачи в 3 AZ, min 3 на критичный сервис ───┐   ║
║ │  graphql-gateway (Node.js) ──┬─► catalog-svc (Go) ──► search-indexer (Go worker)         │   ║
║ │  REST /v1/*                  ├─► cart-svc (Go) ──────► DynamoDB carts/sessions          │   ║
║ │                              ├─► order-svc (Go) ───┐                                     │   ║
║ │                              ├─► payment-svc (Go) ─┼──► Stripe API (egress через NAT)   │   ║
║ │                              │    ▲ webhooks /stripe (проверка подписи)                  │   ║
║ │                              ├─► user-svc (Node.js) ← PII vault (шифрование ПДн)        │   ║
║ │                              └─► legacy-rails (на период strangler fig)                  │   ║
║ │  notification-svc (Node.js worker) ◄── SQS ◄── EventBridge ◄── Transactional Outbox     │   ║
║ │  gdpr-erasure (Step Functions + Lambda)                                                  │   ║
║ └──────────────────────────────────────────────────────────────────────────────────────────┘   ║
║ ┌─ Private-data /22 ×3 (без маршрута в интернет) ──────────────────────────────────────────┐   ║
║ │  RDS Proxy ──► Aurora PostgreSQL 16: writer (AZ-a), reader (AZ-b), autoscale-readers     │   ║
║ │                общий storage: 6 копий в 3 AZ, кворумная синхронная запись               │   ║
║ │  ElastiCache Valkey: primary + 2 replica (3 AZ), TLS + AUTH, Multi-AZ auto-failover      │   ║
║ │  OpenSearch: 3 data-ноды (3 AZ) + 3 dedicated masters                                    │   ║
║ └──────────────────────────────────────────────────────────────────────────────────────────┘   ║
║ Региональные сервисы (через VPC endpoints): S3/DynamoDB (gateway, бесплатно), ECR, Secrets     ║
║ Manager, KMS, SQS, STS, CloudWatch Logs (interface). SES, EventBridge, Step Functions.         ║
╚══════════════════════════╤═════════════════════════════════════════════════════════════════════╝
                           │ асинхронная репликация (цель ≤ 5 мин, факт обычно < 1 с)
                           │ • Aurora Global Database (storage-level)
                           │ • DynamoDB Global Tables
                           │ • S3 CRR + Replication Time Control (SLA 15 мин)
                           │ • OpenSearch Cross-Cluster Replication (индекс каталога)
                           │ • ECR replication, Secrets Manager replica, KMS multi-region keys
                           │ • AWS Backup cross-region copy (снапшоты, 28 дней)
╔══════════════════════════▼═════════════════════════════════════════════════════════════════════╗
║ eu-west-1 (DR, WARM STANDBY) — VPC 10.20.0.0/16 — 3 AZ                                         ║
║  ALB + ECS Fargate: по 1 задаче на сервис (прогрето, проходит health checks)                   ║
║  Aurora secondary cluster: 1× db.r7g.large (read-only, при failover становится writer)         ║
║  Valkey: 1 нода (холодный кэш допустим); OpenSearch: 2 ноды (follower-индекс)                  ║
║  NAT ×1 (при failover → ×3 через Terraform), тот же набор VPC endpoints                        ║
╚════════════════════════════════════════════════════════════════════════════════════════════════╝

Наблюдаемость: ADOT/OpenTelemetry → CloudWatch (метрики, логи, X-Ray/Application Signals),
SLO-дашборды, CloudWatch Alarms → SNS → PagerDuty (on-call). Sentry — для ошибок клиентов.

Почему API за CloudFront, а не напрямую на ALB. Это даёт WAF и Shield на edge, TLS-терминацию ближе к пользователю и кэширование публичного каталога. Кэш CloudFront физически распределён в том числе вне ЕС, поэтому ответы с персональными данными отдаются с Cache-Control: private, no-store и никогда не кэшируются. Транзит через edge-локации покрывается AWS DPA. Это решение нужно зафиксировать в реестре обработки (RoPA) и согласовать с DPO. Консервативная альтернатива: регионный ALB с WAF для запросов с ПДн и CloudFront только для каталога. Она безопаснее с юридической точки зрения, но медленнее для пользователей и сложнее в эксплуатации.


3. Таблица ключевых сервисов AWS

Слой Компонент Сервис AWS Назначение / обоснование
Edge CDN статики и медиа CloudFront + S3 (OAC) Снимает 80–90% трафика с origin, отдаёт изображения в WebP/AVIF
Edge CDN и защита API CloudFront + AWS WAF + Shield Standard OWASP- и bot-правила, rate limiting, защита от L3/L4 DDoS
DNS DNS и failover Route 53 (failover routing, health checks) Переключение origin между регионами, TTL 60 с
Вход Балансировка ALB (3 AZ) L7-маршрутизация на ECS, blue/green через два target group'а. API Gateway при 150–1200 RPS стоил бы около $2K/мес против ~$150
Compute Микросервисы ECS on Fargate (ARM64/Graviton) Нет серверов и control plane, оплата за vCPU/GB, нативный blue/green и canary
Compute Асинхронные задачи ECS Fargate (частично Fargate Spot), Lambda Воркеры уведомлений, индексации, GDPR-джобы
Данные Заказы, платежи, пользователи, каталог Aurora PostgreSQL 16 + Global Database Синхронный кворум в 3 AZ, межрегиональный лаг меньше 1 с, managed failover
Данные Пул соединений RDS Proxy Node.js создаёт много соединений; прокси ускоряет failover writer'а
Данные Корзина, сессии, идемпотентность DynamoDB (on-demand) + Global Tables Синхронная репликация в 3 AZ, асинхронная в DR, не требует администрирования
Данные Кэш ElastiCache for Valkey Карточки товаров, счётчики, rate limits. Valkey примерно на 20% дешевле Redis OSS
Данные Поиск Amazon OpenSearch Service Полнотекстовый поиск и фасеты по 2 млн товаров
Данные Медиа, бэкапы, логи S3 (+CRR, Intelligent-Tiering, Object Lock для audit) Хранение с опциональной неизменяемостью
Интеграция События EventBridge + SQS (+DLQ), transactional outbox Слабая связность сервисов, надёжная доставка событий заказов
Интеграция Оркестрация Step Functions Сага оформления заказа, workflow удаления данных по GDPR, DR-runbook
Коммуникации Email Amazon SES (eu-central-1) Транзакционные письма, обработка данных в ЕС
Безопасность Идентификация IAM Identity Center + permission sets SSO, без IAM-пользователей, MFA обязательна
Безопасность Ключи и секреты KMS (CMK, multi-region keys), Secrets Manager Шифрование at rest, ротация паролей БД, ключи Stripe
Безопасность Детекция и соответствие GuardDuty, Security Hub, Config, Inspector, Macie, CloudTrail (org) Непрерывный контроль, поиск ПДн в S3, доказательная база для аудита
Безопасность Периметр Security Groups, NACL, VPC endpoints, VPC Flow Logs Сегментация на уровне сети
Надёжность Бэкапы и DR AWS Backup (cross-region copy), FIS, Resilience Hub Ежеквартальные автоматизированные DR-учения
Наблюдаемость Метрики, логи, трейсы CloudWatch, X-Ray/Application Signals (через ADOT) Единый стек без отдельной эксплуатации Prometheus/Grafana
FinOps Контроль затрат Cost Explorer, Budgets, Cost Anomaly Detection, CUR 2.0 Прогноз на 6 месяцев вперёд, алерты об аномалиях

4. Проектирование по направлениям

4.1 Топология, HA и DR

Сеть. В каждом окружении и регионе своя VPC, диапазоны не пересекаются: prod-euc1 10.10/16, prod-euw1 10.20/16, stage 10.30/16, dev 10.40/16. Это заложено на будущее под Transit Gateway или peering. В каждой VPC три уровня подсетей по 3 AZ:

  • public — только ALB и NAT;
  • private-app — ECS-задачи, большие /19 с запасом IP под масштабирование Fargate;
  • private-data — без маршрута в интернет.

Высокая доступность внутри региона (закрывает 99.95%):

  • ECS: у критичных сервисов минимум 3 задачи, availability_zone_rebalancing включён, на ALB настроен cross-zone.
  • Aurora: при отказе writer'а reader (promotion tier 0) становится writer'ом примерно за 30 с. RDS Proxy сокращает видимый для приложения простой.
  • Valkey: Multi-AZ с автоматическим failover, 2 реплики.
  • OpenSearch: zone awareness на 3 AZ, 1 реплика на шард.
  • Синхронная репликация в регионе для заказов, платежей и пользователей обеспечивается архитектурой хранилища Aurora: запись подтверждается кворумом 4 из 6 копий в 3 AZ. Для DynamoDB синхронная запись в 3 AZ работает по умолчанию.

Композитный SLA только самих AWS-сервисов (CloudFront 99.9% × ALB × ECS × Aurora) формально ниже 99.95%. На практике фактическая доступность этих сервисов значительно выше контрактной. Однако 99.95% — это 22 минуты в месяц, и основной риск здесь не AWS, а собственные деплои, миграции БД и инциденты. Поэтому сильнее всего SLA защищают canary-деплои, миграции по схеме expand/contract, SLO-алертинг и on-call.

DR (warm standby) — как выполняются RTO ≤ 1 ч и RPO ≤ 15 мин:

Этап failover Механизм Время
Обнаружение Route 53 health checks, CloudWatch composite alarms, AWS Health events 5–10 мин
Решение Ручное подтверждение дежурным и CTO. Автоматический межрегиональный failover не делаем — ложное срабатывание при split-brain опаснее самого простоя 5–10 мин
БД Aurora Global Database: managed failover (unplanned) → secondary становится writer'ом 1–5 мин
Compute Step Functions/SSM runbook: desired_count DR-сервисов → прод-значения, NAT ×3, Valkey +реплики 5–15 мин
Трафик Route 53: переключение origin-записи (TTL 60 с), CloudFront сам начинает ходить в DR-ALB 1–5 мин
Проверка Синтетические тесты (CloudWatch Synthetics), сверка платежей со Stripe 5–10 мин
Итого ~25–50 мин (цель < 60)

RPO. Лаг Aurora Global обычно меньше 1 с, DynamoDB Global Tables — секунды, S3 RTC — до 15 мин. Для платежей дополнительно работает reconciliation-джоб: после failover он забирает из Stripe Events API все события с последнего checkpoint'а и восстанавливает статусы. Даже гипотетически потерянные в лаге записи о платежах восстанавливаются из источника истины (Stripe).

Риск ёмкости в DR. При региональной аварии многие клиенты AWS одновременно масштабируются в соседних регионах. Задачи, которые уже запущены в режиме warm standby, частично снимают этот риск. Для критичных сервисов можно дополнительно держать в DR 2 задачи вместо 1.

Ежеквартальное DR-тестирование:

  • Ежемесячно (stage): AWS FIS-сценарии: остановка задач, потеря AZ (сценарий «AZ Availability: Power Interruption»), failover Aurora.
  • Ежеквартально (stage): полный региональный switchover (Aurora Global switchover → DR → обратное переключение). Выполняется автоматическим Step Functions runbook'ом с замером RTO/RPO и отчётом в S3 (артефакт для аудиторов).
  • Раз в полгода (prod): плановый switchover в низкий трафик после двух успешных stage-прогонов.
  • Отдельно: тест восстановления бэкапа (point-in-time restore в изолированный аккаунт) — проверяет, что бэкапы действительно восстанавливаются.

4.2 Безопасность

IAM и наименьшие привилегии:

  • Нет IAM-пользователей и долгоживущих ключей (запрещено через SCP). Люди входят через IAM Identity Center с обязательной MFA.
  • Permission sets:
    • ReadOnly — все инженеры, prod;
    • Developer — полный доступ в dev, ограниченный в stage;
    • ProdOperator — 2–3 человека, с временным повышением прав через TEAM или ручной approval;
    • BreakGlass — хранится в сейфе, любое использование вызывает алерт.
  • CI работает через GitHub OIDC → IAM role с условием на repo:org/repo:environment:prod. Статические ключи не используются.
  • У каждого ECS-сервиса свой task role с доступом только к своей таблице, очереди и секретам. Например, payment-svc читает только секрет stripe/*. Execution role отделён от task role.
  • Доступ к БД: IAM auth и отдельные роли PostgreSQL на каждый сервис (схема = сервис). Прямой доступ людей к prod-БД возможен только через SSM Session Manager с записью сессии, без bastion-хостов с SSH.

Сегментация сети:

  • SG ALB разрешает 443 только из managed prefix list com.amazonaws.global.cloudfront.origin-facing. Дополнительно CloudFront передаёт секретный заголовок, который проверяется на ALB.
  • SG приложений разрешает вход только от ALB и сервис-к-сервису по нужным портам. SG данных разрешают вход только от SG конкретных сервисов.
  • Data-подсети не имеют маршрута в интернет. Egress из app-подсетей идёт через NAT к Stripe, APNs/FCM и прочим внешним API. На следующем этапе можно добавить AWS Network Firewall с allow-list доменов (~$300+/мес, отложено по бюджету).
  • VPC Flow Logs направляются в log-archive.

Шифрование:

  • At rest: KMS CMK отдельно для доменов pii, orders, logs, backups с ежегодной автоматической ротацией. Для S3 CRR и прикладного шифрования используются multi-region keys. Шифруются Aurora, DynamoDB, S3 (SSE-KMS + Bucket Keys ради экономии запросов к KMS), EBS, OpenSearch, Valkey, SQS и бэкапы.
  • Дополнительно для ПДн (email, телефон, адрес) — прикладное envelope-шифрование в user-svc (AWS Encryption SDK). Администратор БД видит только шифротекст, а дампы и логи не раскрывают ПДн.
  • In transit:
    • CloudFront: TLSv1.2_2021;
    • ALB: ELBSecurityPolicy-TLS13-1-2-2021-06;
    • Aurora: rds.force_ssl=1;
    • Valkey: in-transit encryption;
    • OpenSearch: enforce HTTPS;
    • внутри VPC ALB ходит в задачи по HTTPS. Service Connect с TLS — опция, на старте её можно отложить: трафик и так остаётся в изолированных подсетях.

Управление секретами. Все секреты хранятся в Secrets Manager: пароли БД с автоматической ротацией, секретные ключи Stripe, webhook signing secret. В задачи они попадают через secrets в task definition. Секреты реплицируются в eu-west-1. В git и переменных CI секретов нет, это проверяют gitleaks в pre-commit и secret scanning в GitHub.

GDPR:

Требование Реализация
Хранение и обработка только в ЕС SCP с deny для всех регионов, кроме eu-central-1 и eu-west-1 (с исключениями для глобальных сервисов IAM, CloudFront, Route 53, Support). Все субпроцессоры (SES, Stripe, провайдер push) проверяются и вносятся в реестр. CloudFront не кэширует ПДн.
Разделение ПДн «PII vault» в user-svc: ПДн хранятся только там и в зашифрованном виде. Остальные сервисы (заказы, аналитика) оперируют user_id и снапшотом адреса доставки, который тоже зашифрован ключом пользователя.
Право на забвение за 30 дней Step Functions workflow:<br>1) запрос → верификация личности;<br>2) событие UserErasureRequested в EventBridge;<br>3) каждый сервис удаляет или анонимизирует свои данные и отвечает ErasureCompleted: S3 — удаление всех версий в обоих регионах (CRR не переносит удаления версий автоматически); OpenSearch, DynamoDB и Valkey — удаление записей и сброс кэша; Stripe — DELETE /v1/customers/{id};<br>4) заказы анонимизируются, финансовые поля остаются по [ДОП-6];<br>5) удаляется per-user ключ шифрования (crypto-shredding);<br>6) формируется отчёт-доказательство для DPO.
Удаление из бэкапов Хранение PITR и снапшотов — 28 дней (меньше 30), поэтому бэкапы с удалёнными данными истекают естественным образом. Реестр удалений (хэши user_id) лежит в отдельной таблице и автоматически применяется скриптом при любом восстановлении из бэкапа. Если бизнесу нужны долгосрочные архивы, они хранятся только с прикладным шифрованием per-user ключами: удаление ключа делает данные в архиве нечитаемыми.
Удаление из логов Правило «никаких ПДн в логах»: структурированный логгер с redaction-фильтром плюс проверки в code review и тестах. Macie сканирует лог-бакеты на утечки. Retention прикладных логов — 30 дней.
Журнал доступа к ПДн от 1 года Каждый доступ к ПДн через user-svc и админку пишет событие (кто, когда, чей user_id, цель) → Firehose → S3 в log-archive с Object Lock на 13 месяцев. Дополнительно используются pgaudit по таблицам ПДн и CloudTrail (management + S3/KMS data events для PII-ресурсов). В журнале только псевдонимные идентификаторы, иначе Object Lock вступит в конфликт с правом на удаление.
DPO и процессы Организационная сторона: DPO, RoPA, DPIA для маркетплейса, DPA с AWS (входит в AWS Service Terms) и Stripe, процедура уведомления о breach за 72 часа, опирающаяся на алерты GuardDuty и Security Hub.

PCI DSS SAQ A:

  • Используется Stripe Checkout (redirect) или Payment Element в iframe Stripe. PAN никогда не проходит через наш бэкенд, логи или CloudFront.
  • В payment-svc хранятся только customer_id, payment_intent_id и статусы.
  • Webhooks проверяются по подписи (Stripe-Signature), для защиты от повторов обрабатываются идемпотентно через DynamoDB и допуск по времени.
  • Для страниц, встраивающих платёжную форму: строгий CSP, SRI для собственных скриптов, минимум сторонних скриптов, контроль изменений фронтенда через CI. Критерии пригодности SAQ A в PCI DSS v4.0.1 требуют, чтобы сайт мерчанта был защищён от атак через скрипты.
  • Ежегодно заполняется SAQ A и проводятся ASV-сканы по требованию эквайера.

Детекция и аудит:

  • GuardDuty (включая ECS Runtime Monitoring и RDS Protection);
  • Security Hub с AWS Foundational Security Best Practices и CIS;
  • AWS Config с conformance pack;
  • Inspector для сканирования образов в ECR;
  • Macie на S3;
  • IAM Access Analyzer.

Результаты агрегируются в security-tooling. Ежегодный внешний аудит и пентест покупается у стороннего подрядчика (не входит в облачный бюджет, ориентировочно €15–30K в год). Для него готовятся артефакты: Config compliance history, отчёты DR-тестов, IaC и журналы доступа.

4.3 Масштабируемость и производительность

Расчёт ёмкости. Сейчас пик 1200 RPS. С ростом ×3 через 12 месяцев получается ~3600 RPS в пике и 450–900 RPS в обычном режиме. Архитектура спроектирована под 4000+ RPS без переделки, растёт только число задач и реплик.

  • ECS autoscaling:

    • target tracking по ALBRequestCountPerTarget и CPU 60%;
    • scale-out быстрый (cooldown 60 с), scale-in медленный (300 с);
    • scheduled scaling перед Чёрной пятницей: min × 3 за 48 часов до пика, потому что Fargate поднимает задачи 1–2 минуты;
    • для ALB — LCU Reservation (резервирование ёмкости) на пиковые дни.
  • Aurora:

    • read/write splitting: writer для транзакций, reader endpoint для каталога и истории заказов;
    • Aurora Replica Auto Scaling от 1 до 3 readers по CPU и соединениям;
    • pg_stat_statements и CloudWatch Database Insights для поиска тяжёлых запросов;
    • 2 млн товаров и 500 тыс. заказов в год — малый объём для Aurora. Партиционирование заказов (pg_partman по месяцам) понадобится не раньше чем через 2–3 года, на старте достаточно корректных индексов.
  • Кэширование (многоуровневое):

    1. CloudFront: статика (TTL в днях, versioned assets) и публичный каталог через persisted GraphQL queries по GET (TTL 60–300 с);
    2. Valkey: cache-aside для карточек, категорий и цен, инвалидация по событиям ProductUpdated;
    3. in-process LRU в Go-сервисах для справочников.

    Цель — cache hit ratio каталога выше 90%.

  • Поиск. Индекс OpenSearch строится через CDC/outbox → search-indexer. Поиск по 2 млн документов со всеми фасетами укладывается в 3 data-ноды r7g.large.

  • Изображения. Ресайз и конвертация в WebP/AVIF выполняются при загрузке (Lambda) или on-the-fly (CloudFront + Lambda). Это главный рычаг снижения стоимости egress: минус 30–50% трафика.

  • Устойчивость к перегрузке:

    • rate limiting в WAF (по IP) и в gateway (по пользователю);
    • circuit breakers и таймауты во всех клиентах;
    • очереди SQS как буфер для уведомлений и индексации;
    • «деградация по плану»: при перегрузке отключаются рекомендации, а поиск откатывается на PostgreSQL FTS.
  • Нагрузочное тестирование (k6 или Distributed Load Testing on AWS) на stage перед каждым сезоном, профиль — 1.5 × ожидаемого пика.

4.4 DevOps и IaC

Организация окружений: dev, stage и prod — отдельные AWS-аккаунты. Это даёт изоляцию blast radius, раздельный биллинг и чистый периметр для аудита. Stage повторяет prod по топологии (3 AZ, Aurora Global в eu-west-1 для DR-учений), но с меньшими инстансами. Dev использует одну Aurora без реплики, единственный NAT и автоостановку вне рабочих часов.

CI/CD-пайплайн (GitHub Actions + OIDC):

PR:   lint → unit-тесты → SAST (Semgrep) → gitleaks → build image (ARM64) → Trivy scan
      → integration-тесты (testcontainers: Postgres, Valkey, LocalStack)
      → terraform fmt/validate/tflint/checkov + terraform plan в комментарий PR
merge в main:
      → push в ECR (shared-services, immutable tags = git SHA, cosign-подпись)
      → auto-deploy в dev → smoke tests
      → auto-deploy в stage → e2e + contract tests (Pact) + миграции БД (expand)
      → manual approval (GitHub Environment "prod", 2 approvers)
      → prod: ECS native BLUE/GREEN или CANARY (10% → bake 10 мин → 100%)
               автоматический rollback по CloudWatch alarms (5xx, p99 latency, SLO burn rate)
      → post-deploy synthetic checks
Infra:  Terraform plan в PR → apply через CI после approve (никаких apply с ноутбуков)

Zero-downtime миграции БД. Строго по паттерну expand → migrate → contract:

  1. добавить колонку или таблицу, при необходимости включить двойную запись;
  2. задеплоить код, работающий с обеими схемами;
  3. сделать backfill батчами;
  4. удалить старое в следующем релизе.

Инструменты: golang-migrate или Atlas с проверкой опасных операций (lock-heavy ALTER, индексы без CONCURRENTLY).

Структура Terraform описана в разделе 5. Ключевые принципы:

  • модули переиспользуются, root-модули разделены по слоям (network → data → services → edge), чтобы уменьшить blast radius и время plan;
  • state хранится в S3 с нативной блокировкой (use_lockfile, DynamoDB для блокировок больше не нужен);
  • версии модулей и провайдеров зафиксированы.

4.5 Оптимизация затрат (сводка, подробности в разделе 6)

  • Graviton везде: Fargate ARM64, r7g/m7g для Aurora, Valkey и OpenSearch дают −20% к стоимости compute.
  • Обязательства покупаются только после 2–3 месяцев стабильного прода, по фактической базовой линии, а не по прогнозу.
  • Fargate Spot — для воркеров (индексация, email) и stage/dev.
  • Расписание dev/stage: остановка ночью и в выходные экономит 60–65% на этих окружениях.

5. IaC-скелет (Terraform)

5.1 Структура репозитория infra/

infra/
├── modules/                       # переиспользуемые, версионируются git-тегами
│   ├── network/                   # VPC, подсети, NAT, endpoints, flow logs
│   ├── security-baseline/         # KMS, GuardDuty, Config, Security Hub (per account)
│   ├── aurora-global/             # global cluster + primary + secondary
│   ├── ecs-cluster/
│   ├── ecs-service/               # task def, service, ALB TG/rules, autoscaling, alarms
│   ├── elasticache-valkey/
│   ├── opensearch/
│   ├── edge/                      # CloudFront, WAF, Route 53 failover
│   └── observability/             # dashboards, SLO alarms, SNS
├── live/
│   ├── org/                       # Organizations, SCP, Identity Center, log-archive
│   ├── shared-services/           # ECR + replication, GitHub OIDC roles, Route 53 zones
│   ├── prod/
│   │   ├── eu-central-1/{network,data,platform,services,edge}/
│   │   └── eu-west-1/{network,platform,services}/     # DR
│   ├── stage/ (та же структура)
│   └── dev/
└── .github/workflows/terraform.yml

5.2 Провайдеры и backend (live/prod/eu-central-1/data/versions.tf)

terraform {
  required_version = ">= 1.10" # нужен для use_lockfile в S3 backend

  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 6.0" # зафиксировать конкретную минорную версию в .terraform.lock.hcl
    }
  }

  backend "s3" {
    bucket       = "acme-tfstate-prod"            # отдельный bucket на аккаунт, versioning + SSE-KMS
    key          = "prod/eu-central-1/data/terraform.tfstate"
    region       = "eu-central-1"
    encrypt      = true
    use_lockfile = true                           # нативная блокировка S3, без DynamoDB
  }
}

locals {
  tags = {
    Project     = "handmade-marketplace"
    Environment = "prod"
    Owner       = "platform"
    ManagedBy   = "terraform"
    DataClass   = "pii" # переопределяется на ресурсах: public | internal | pii | financial
  }
}

provider "aws" {
  alias  = "primary"
  region = "eu-central-1"
  default_tags { tags = local.tags }
}

provider "aws" {
  alias  = "dr"
  region = "eu-west-1"
  default_tags { tags = merge(local.tags, { Role = "dr" }) }
}

5.3 Сеть (live/prod/eu-central-1/network/main.tf)

module "vpc" {
  source  = "terraform-aws-modules/vpc/aws"
  version = "~> 6.0" # проверьте актуальную мажорную версию модуля

  name = "prod-euc1"
  cidr = "10.10.0.0/16"
  azs  = ["eu-central-1a", "eu-central-1b", "eu-central-1c"]

  public_subnets   = ["10.10.0.0/22", "10.10.4.0/22", "10.10.8.0/22"]     # ALB, NAT
  private_subnets  = ["10.10.32.0/19", "10.10.64.0/19", "10.10.96.0/19"]  # ECS tasks
  database_subnets = ["10.10.160.0/22", "10.10.164.0/22", "10.10.168.0/22"]

  enable_nat_gateway     = true
  one_nat_gateway_per_az = true # отказ AZ не ломает egress в других AZ

  create_database_subnet_group           = true
  create_database_internet_gateway_route = false
  create_database_nat_gateway_route      = false # data-подсети полностью изолированы

  enable_dns_hostnames = true
  enable_dns_support   = true

  enable_flow_log                      = true
  flow_log_destination_type            = "s3"
  flow_log_destination_arn             = var.log_archive_flowlogs_bucket_arn
  flow_log_max_aggregation_interval    = 600
}

# Gateway endpoints (бесплатно) + ключевые interface endpoints, чтобы не гонять трафик через NAT
module "endpoints" {
  source  = "terraform-aws-modules/vpc/aws//modules/vpc-endpoints"
  version = "~> 6.0"

  vpc_id             = module.vpc.vpc_id
  security_group_ids = [aws_security_group.endpoints.id]
  subnet_ids         = module.vpc.private_subnets

  endpoints = {
    s3       = { service = "s3", service_type = "Gateway", route_table_ids = module.vpc.private_route_table_ids }
    dynamodb = { service = "dynamodb", service_type = "Gateway", route_table_ids = module.vpc.private_route_table_ids }
    ecr_api  = { service = "ecr.api", private_dns_enabled = true }
    ecr_dkr  = { service = "ecr.dkr", private_dns_enabled = true }
    logs     = { service = "logs", private_dns_enabled = true }
    secrets  = { service = "secretsmanager", private_dns_enabled = true }
    kms      = { service = "kms", private_dns_enabled = true }
    sqs      = { service = "sqs", private_dns_enabled = true }
    sts      = { service = "sts", private_dns_enabled = true }
  }
}

5.4 KMS и Aurora Global Database (live/prod/eu-central-1/data/aurora.tf)

# Multi-region CMK: один логический ключ в обоих регионах (удобно для S3 CRR и прикладного шифрования)
resource "aws_kms_key" "core_data" {
  provider                = aws.primary
  description             = "prod core data (orders, payments, users) - PII/financial"
  enable_key_rotation     = true
  multi_region            = true
  deletion_window_in_days = 30
}

resource "aws_kms_replica_key" "core_data_dr" {
  provider        = aws.dr
  primary_key_arn = aws_kms_key.core_data.arn
}

resource "aws_rds_cluster_parameter_group" "core" {
  provider = aws.primary
  name     = "prod-core-apg16"
  family   = "aurora-postgresql16"

  parameter {
    name  = "rds.force_ssl"
    value = "1" # только TLS-подключения
  }
  parameter {
    name         = "shared_preload_libraries"
    value        = "pg_stat_statements,pgaudit"
    apply_method = "pending-reboot"
  }
  parameter {
    name  = "pgaudit.log"
    value = "ddl,role" # объектный аудит таблиц ПДн — через pgaudit.role
  }
  parameter {
    name  = "pgaudit.role"
    value = "rds_pgaudit"
  }
}

resource "aws_rds_global_cluster" "core" {
  provider                  = aws.primary
  global_cluster_identifier = "prod-core"
  engine                    = "aurora-postgresql"
  engine_version            = "16.6" # проверить актуальную минорную версию, поддерживаемую Global DB
  database_name             = "core"
  storage_encrypted         = true
  deletion_protection       = true
}

resource "aws_rds_cluster" "primary" {
  provider                  = aws.primary
  cluster_identifier        = "prod-core-euc1"
  global_cluster_identifier = aws_rds_global_cluster.core.id
  engine                    = aws_rds_global_cluster.core.engine
  engine_version            = aws_rds_global_cluster.core.engine_version

  master_username = "core_admin"
  master_password = data.aws_secretsmanager_secret_version.db_master.secret_string
  # Ротация — через Secrets Manager. Проверьте поддержку manage_master_user_password
  # для Global Database в актуальной версии RDS; если поддерживается — используйте её.

  db_subnet_group_name            = var.db_subnet_group_name
  vpc_security_group_ids          = [aws_security_group.aurora.id]
  db_cluster_parameter_group_name = aws_rds_cluster_parameter_group.core.name

  storage_encrypted = true
  kms_key_id        = aws_kms_key.core_data.arn

  backup_retention_period      = 28 # < 30 дней: бэкапы с удалёнными ПДн истекают естественно (GDPR)
  preferred_backup_window      = "01:00-02:00"
  preferred_maintenance_window = "sun:02:30-sun:03:30"
  copy_tags_to_snapshot        = true

  iam_database_authentication_enabled = true
  enabled_cloudwatch_logs_exports     = ["postgresql"]

  deletion_protection       = true
  skip_final_snapshot       = false
  final_snapshot_identifier = "prod-core-euc1-final"
}

resource "aws_rds_cluster_instance" "primary" {
  provider           = aws.primary
  count              = 2 # writer + reader (цель failover) в разных AZ
  identifier         = "prod-core-euc1-${count.index}"
  cluster_identifier = aws_rds_cluster.primary.id
  instance_class     = "db.r7g.xlarge"
  engine             = aws_rds_cluster.primary.engine
  engine_version     = aws_rds_cluster.primary.engine_version
  availability_zone  = element(["eu-central-1a", "eu-central-1b"], count.index)
  promotion_tier     = count.index
  monitoring_interval = 30
  monitoring_role_arn = aws_iam_role.rds_monitoring.arn
  auto_minor_version_upgrade = false # обновления — осознанно, через stage
}

# Автомасштабирование readers на пики (Чёрная пятница)
resource "aws_appautoscaling_target" "aurora_readers" {
  provider           = aws.primary
  service_namespace  = "rds"
  scalable_dimension = "rds:cluster:ReadReplicaCount"
  resource_id        = "cluster:${aws_rds_cluster.primary.cluster_identifier}"
  min_capacity       = 1
  max_capacity       = 3
}

resource "aws_appautoscaling_policy" "aurora_readers_cpu" {
  provider           = aws.primary
  name               = "aurora-readers-cpu"
  service_namespace  = aws_appautoscaling_target.aurora_readers.service_namespace
  scalable_dimension = aws_appautoscaling_target.aurora_readers.scalable_dimension
  resource_id        = aws_appautoscaling_target.aurora_readers.resource_id
  policy_type        = "TargetTrackingScaling"

  target_tracking_scaling_policy_configuration {
    predefined_metric_specification {
      predefined_metric_type = "RDSReaderAverageCPUUtilization"
    }
    target_value       = 60
    scale_in_cooldown  = 600
    scale_out_cooldown = 120
  }
}

# DR: secondary cluster в eu-west-1
resource "aws_rds_cluster" "dr" {
  provider                  = aws.dr
  cluster_identifier        = "prod-core-euw1"
  global_cluster_identifier = aws_rds_global_cluster.core.id
  engine                    = aws_rds_global_cluster.core.engine
  engine_version            = aws_rds_global_cluster.core.engine_version

  db_subnet_group_name   = var.dr_db_subnet_group_name
  vpc_security_group_ids = [var.dr_aurora_sg_id]
  storage_encrypted      = true
  kms_key_id             = aws_kms_replica_key.core_data_dr.arn

  backup_retention_period = 28
  deletion_protection     = true
  skip_final_snapshot     = false
  final_snapshot_identifier = "prod-core-euw1-final"

  depends_on = [aws_rds_cluster_instance.primary]

  lifecycle {
    ignore_changes = [replication_source_identifier] # рекомендация провайдера для secondary Global DB
  }
}

resource "aws_rds_cluster_instance" "dr" {
  provider           = aws.dr
  identifier         = "prod-core-euw1-0"
  cluster_identifier = aws_rds_cluster.dr.id
  instance_class     = "db.r7g.large" # при failover масштабируется до xlarge по runbook
  engine             = aws_rds_cluster.dr.engine
  engine_version     = aws_rds_cluster.dr.engine_version
}

5.5 ECS-сервис с нативным blue/green (modules/ecs-service/main.tf, фрагмент)

resource "aws_ecs_task_definition" "this" {
  family                   = var.name
  requires_compatibilities = ["FARGATE"]
  network_mode             = "awsvpc"
  cpu                      = var.cpu    # напр. 512
  memory                   = var.memory # напр. 1024
  execution_role_arn       = aws_iam_role.execution.arn
  task_role_arn            = aws_iam_role.task.arn # least privilege, свой на каждый сервис

  runtime_platform {
    operating_system_family = "LINUX"
    cpu_architecture        = "ARM64" # Graviton: ~20% дешевле
  }

  container_definitions = jsonencode([{
    name                   = var.name
    image                  = "${var.ecr_repo_url}:${var.image_tag}" # immutable tag = git SHA
    essential              = true
    readonlyRootFilesystem = true
    user                   = "10001"
    portMappings           = [{ containerPort = var.port, protocol = "tcp" }]
    secrets = [for k, arn in var.secrets : { name = k, valueFrom = arn }]
    healthCheck = {
      command  = ["CMD", "/app/healthcheck"]
      interval = 15, timeout = 5, retries = 3, startPeriod = 20
    }
    logConfiguration = {
      logDriver = "awslogs"
      options = {
        awslogs-group         = aws_cloudwatch_log_group.this.name
        awslogs-region        = var.region
        awslogs-stream-prefix = var.name
      }
    }
  }])
}

resource "aws_cloudwatch_log_group" "this" {
  name              = "/ecs/${var.env}/${var.name}"
  retention_in_days = 30 # прикладные логи без ПДн, 30 дней
  kms_key_id        = var.logs_kms_key_arn
}

resource "aws_ecs_service" "this" {
  name                          = var.name
  cluster                       = var.cluster_arn
  task_definition               = aws_ecs_task_definition.this.arn
  desired_count                 = var.min_count
  availability_zone_rebalancing = "ENABLED"
  propagate_tags                = "SERVICE"

  capacity_provider_strategy {
    capacity_provider = "FARGATE"
    base              = var.min_count
    weight            = 1
  }
  # для воркеров: дополнительная стратегия FARGATE_SPOT с weight > 0

  network_configuration {
    subnets          = var.private_subnet_ids
    security_groups  = [aws_security_group.task.id]
    assign_public_ip = false
  }

  # Нативный blue/green в ECS (требует свежий AWS provider 6.x — проверьте минимальную версию)
  deployment_configuration {
    strategy             = "BLUE_GREEN"
    bake_time_in_minutes = 10
  }

  alarms {
    alarm_names = [aws_cloudwatch_metric_alarm.error_rate.alarm_name,
                   aws_cloudwatch_metric_alarm.p99_latency.alarm_name]
    enable      = true
    rollback    = true # автоматический откат на blue при срабатывании
  }

  load_balancer {
    target_group_arn = aws_lb_target_group.blue.arn
    container_name   = var.name
    container_port   = var.port

    advanced_configuration {
      alternate_target_group_arn = aws_lb_target_group.green.arn
      production_listener_rule   = aws_lb_listener_rule.this.arn
      role_arn                   = var.ecs_infrastructure_role_arn
    }
  }

  lifecycle {
    ignore_changes = [desired_count] # управляет Application Auto Scaling
  }
}

resource "aws_appautoscaling_target" "svc" {
  service_namespace  = "ecs"
  scalable_dimension = "ecs:service:DesiredCount"
  resource_id        = "service/${var.cluster_name}/${aws_ecs_service.this.name}"
  min_capacity       = var.min_count # >= 3 для критичных сервисов (по 1 на AZ)
  max_capacity       = var.max_count
}

resource "aws_appautoscaling_policy" "rps" {
  name               = "${var.name}-rps"
  policy_type        = "TargetTrackingScaling"
  service_namespace  = aws_appautoscaling_target.svc.service_namespace
  scalable_dimension = aws_appautoscaling_target.svc.scalable_dimension
  resource_id        = aws_appautoscaling_target.svc.resource_id

  target_tracking_scaling_policy_configuration {
    predefined_metric_specification {
      predefined_metric_type = "ALBRequestCountPerTarget"
      resource_label         = "${var.alb_arn_suffix}/${aws_lb_target_group.blue.arn_suffix}"
    }
    target_value       = var.target_rps_per_task # определяется нагрузочным тестом
    scale_out_cooldown = 60
    scale_in_cooldown  = 300
  }
}

5.6 SCP: только регионы ЕС (live/org/scp.tf, фрагмент)

resource "aws_organizations_policy" "eu_only" {
  name = "deny-non-eu-regions"
  type = "SERVICE_CONTROL_POLICY"
  content = jsonencode({
    Version = "2012-10-17"
    Statement = [{
      Sid    = "DenyOutsideAllowedRegions"
      Effect = "Deny"
      NotAction = [ # глобальные сервисы, работающие через us-east-1
        "iam:*", "organizations:*", "sts:*", "support:*", "budgets:*", "ce:*",
        "cloudfront:*", "route53:*", "route53domains:*", "wafv2:*", "shield:*",
        "acm:*", "health:*", "sso:*", "identitystore:*", "account:*", "pricing:*"
      ]
      Resource = "*"
      Condition = {
        StringNotEquals = { "aws:RequestedRegion" = ["eu-central-1", "eu-west-1"] }
        ArnNotLike      = { "aws:PrincipalARN" = ["arn:aws:iam::*:role/AWSControlTowerExecution"] }
      }
    }]
  })
}
# Примечание: ACM-сертификат для CloudFront создаётся в us-east-1 — это не хранение ПДн.
# wafv2:* и acm:* сознательно в NotAction; для максимальной строгости ограничьте их
# дополнительным условием по ресурсам CloudFront.

6. Оценка затрат (ориентировочно, $/мес)

Допущения по расчёту:

  • цены eu-central-1 on-demand на осень 2026 приблизительны, перед закупкой проверьте их в AWS Pricing Calculator;
  • базовая нагрузка ~250 RPS, [ДОП-2] — 8 ТБ CDN egress;
  • ~12 сервисов, в сумме около 40 vCPU и 80 ГБ на Fargate ARM в prod-euc1, включая резерв на 3 AZ;
  • НДС не учтён.
# Компонент Конфигурация On-demand С обязательствами
1 ECS Fargate (prod euc1) ~40 vCPU / 80 ГБ ARM64 1 300 1 050 (Compute SP 1 год)
2 ALB 1 ALB, ~10–15 LCU 150 150
3 NAT Gateway 3 шт. + ~500 ГБ обработки 150 150
4 VPC Interface Endpoints 7 × 3 AZ + трафик 200 200
5 Aurora primary 2× r7g.xlarge, ~300 ГБ, I/O, бэкапы 1 200 900 (RI 1 год)
6 Aurora DR + репликация 1× r7g.large + replicated writes + storage 350 300
7 RDS Proxy по vCPU writer'а 100 100
8 ElastiCache Valkey 3× cache.r7g.large 450 320 (RI)
9 OpenSearch 3× r7g.large.search + 3 малых master + 600 ГБ gp3 700 520 (RI)
10 DynamoDB + Global Tables on-demand, корзины/сессии/идемпотентность 150 150
11 SQS / SNS / EventBridge / Step Functions / Lambda 100 100
12 S3 8 ТБ медиа (Intelligent-Tiering) + CRR-копия + бэкапы + логи 450 450
13 CloudFront ~8 ТБ egress + ~500 млн HTTPS-запросов 900 800*
14 AWS WAF 2 web ACL, managed rules, ~500 млн запросов, Bot Control (common) 400 400
15 Route 53 зоны, health checks 30 30
16 Наблюдаемость CloudWatch Logs (~400 ГБ), метрики, alarms, трейсы, Synthetics 600 600
17 Безопасность GuardDuty, Security Hub, Config, Inspector, Macie, CloudTrail data events 450 450
18 KMS + Secrets Manager ~15 CMK, ~50 секретов 60 60
19 AWS Backup cross-region copy, тесты restore 150 150
20 DR-регион (warm standby) ECS минимум, ALB, NAT ×1, endpoints, Valkey ×1, OpenSearch 2 ноды 650 550
21 Stage 3 AZ, малые инстансы, выключение ночью/в выходные, Spot 1 000 900
22 Dev 1 AZ-NAT, Aurora 1 инстанс, расписание 500 450
23 Shared-services + log-archive ECR (+репликация), S3 Object Lock, Firehose 150 150
24 Межзонный и межрегиональный трафик 250 250
25 AWS Business Support [ДОП-9] % от счёта, ступенчатая шкала (сверьте с текущими планами) 900 820
ИТОГО базовый месяц ≈ 11 340 ≈ 10 150

* Оцените flat-rate тарифы CloudFront (пакеты с включёнными WAF и трафиком). При вашем профиле они могут быть заметно дешевле связки «CloudFront + WAF по запросам». Проверьте актуальные условия.

Пиковые месяцы (ноябрь–декабрь):

  • Fargate ×2.5 на ~2–3 недели: +$800–1 100;
  • дополнительные Aurora readers: +$300–400;
  • CloudFront и WAF ×1.8: +$700–900;
  • логи: +$150.

Итого ≈ $12 800–13 500, в пределах лимита $15K.

Прогноз на 12 месяцев при росте трафика ×3. Без мер оптимизации база составит ≈ $14–16K/мес: растут compute, CDN, WAF и логи, а Aurora, OpenSearch и базовые компоненты растут сублинейно. Поэтому меры ниже — это необходимость для удержания бюджета, а не опция.

Приоритетные меры экономии (в порядке эффект/усилие):

  1. Оптимизация изображений (WebP/AVIF, адаптивные размеры) — −30–50% CDN egress, до −$400/мес при росте.
  2. Compute Savings Plan + RI на Aurora, Valkey и OpenSearch — покупать на ~70% от фактической базовой линии через 2–3 месяца после cutover. Экономия ≈ $1 200/мес.
  3. Бюджет логов: уровни логирования, сэмплинг трейсов (5–10%), класс CloudWatch Logs Infrequent Access для отладочных логов, retention 14–30 дней — −$200–300.
  4. Расписания и Spot для dev/stage — уже заложены.
  5. Кэширование публичного каталога на CloudFront через persisted queries снижает нагрузку на origin (Fargate, ALB, Aurora readers) в пике.
  6. Контроль VPC endpoints: удалить неиспользуемые и сравнить с объёмом трафика через NAT.
  7. Пересматривать rightsizing ежемесячно (Compute Optimizer).

Предсказуемость на 6 месяцев вперёд:

  • AWS Budgets на каждый аккаунт и сервис с алертами на 80/100/120% и forecast-алертами;
  • Cost Anomaly Detection;
  • обязательные теги Environment/Service/Owner (Tag Policies в Organizations);
  • CUR 2.0 → Athena → дашборд «стоимость на 1000 запросов» и «стоимость на заказ». Прогноз строится как (прогноз RPS / заказов) × unit cost + фиксированная база. Такой метод точнее трендовой экстраполяции Cost Explorer при сезонности.

7. Риски и trade-off'ы

# Риск / trade-off Влияние Митигация
1 Разрыв компетенций: 6 инженеров, облачного опыта мало, DevOps на part-time, а целевой SLA 99.95% Критическое Нанять (или перевести на full-time) platform-инженера. Обучение: AWS Cloud Practitioner → Solutions Architect Associate для 2–3 человек. On-call ротация 4–5 человек. Рассмотреть AWS Partner на этап Landing Zone и первого DR-теста (~2–4 недели работ).
2 Переход монолит → микросервисы одновременно с переездом в облако Высокое Два отдельных шага: сначала «lift & improve» монолита в ECS, затем постепенное выделение сервисов. 5–7 сервисов, а не 20. Сохранять модульный монолит там, где нет потребности в независимом масштабировании.
3 Переезд до Чёрной пятницы 2026 Критическое Cutover не раньше января 2027. На Q4 — укрепление Hetzner (этап 0).
4 Warm standby вместо active-active Ниже стоимость и сложность, но RTO 25–50 мин вместо секунд Соответствует требованию RTO 1 ч. Active-active пересмотреть при SLA 99.99%.
5 Межрегиональный failover ручной, а не автоматический +5–10 мин к RTO Защищает от ложных срабатываний и split-brain. Runbook автоматизирован, решение принимает человек.
6 Fargate вместо EKS или EC2 Unit cost compute на 15–30% выше, меньше контроля Резко меньше операционной нагрузки. Пересмотреть при compute больше $4–5K/мес (ECS на EC2 + Graviton + SP).
7 Vendor lock-in (Aurora Global, DynamoDB, EventBridge) Средний Код работает с PostgreSQL-совместимым API. Интерфейсы очередей и хранилищ абстрагированы в коде. DynamoDB используется только для простых key-value сценариев.
8 Хранение бэкапов 28 дней ради GDPR Нельзя восстановиться от логической порчи данных старше 28 дней Детектирование порчи (инварианты, сверки) в пределах дней. Долгосрочные архивы только с crypto-shredding. Финансовые записи дублируются в бухгалтерской системе.
9 Кэш CloudFront и edge-локации вне ЕС Юридическая неопределённость Не кэшировать ПДн, no-store, фиксация в RoPA, заключение DPO. Альтернатива — регионный ALB для персональных эндпоинтов.
10 Нехватка ёмкости Fargate в DR при массовом региональном инциденте Средний Warm tasks, ранее решение о failover, при необходимости Fargate + EC2 capacity providers в DR.
11 Бюджет при росте ×3 Высокий Unit economics, обязательства, оптимизация медиа. Ежеквартальный пересмотр с CFO.
12 ПДн в логах из-за ошибки разработчика Нарушение права на забвение Redaction-логгер, тесты, Macie, короткий retention. Инцидент по процедуре GDPR breach.
13 Зависимость от Stripe и SES Недоступность платежей за пределами нашего SLA Graceful degradation (заказ в статусе «ожидает оплаты» с повтором), мониторинг status-страниц, SLA в договорах.

8. Дорожная карта внедрения

Этап Сроки (ориентир) Содержание Критерий завершения
0. Остановить кровотечение (параллельно, на Hetzner) Сентябрь–ноябрь 2026 • Сегодня же: WAL-G/pgBackRest → S3 eu-central-1 (непрерывный WAL-архив + ежедневный base backup) — это даёт PITR. Проверить восстановление.<br>• Второй сервер Hetzner со streaming-репликой PostgreSQL (hot standby).<br>• GitHub Actions: тесты в CI, деплой только из CI (Capistrano из пайплайна, не с ноутбуков).<br>• CloudFront перед статикой и изображениями (снимает нагрузку в пик).<br>• Sentry + Grafana Cloud/Prometheus + алерты; нагрузочный тест монолита на 1500 RPS.<br>• Code freeze с 20 ноября по 2 декабря. Проверенный restore, RPO меньше 5 мин на Hetzner, CI для каждого PR, Чёрная пятница пройдена
1. Фундамент AWS Октябрь–декабрь 2026 (без касания прода) Organizations + Control Tower, SCP, Identity Center, log-archive, security baseline. Terraform-репозиторий, state, модули network/security. GitHub OIDC. Обучение команды. Договоры и DPA, старт DPIA. Security Hub score выше 90%, dev-аккаунт полностью в IaC
2. Платформа и контейнеризация монолита Декабрь 2026 – январь 2027 Docker-образ Rails-монолита, ECS в dev/stage, Aurora PG 16 в stage, S3-медиа, Valkey, CI/CD с blue/green, наблюдаемость и SLO-алерты, runbooks. Stage обслуживает полный e2e-набор, деплой без простоя проверен
3. Cutover в AWS Январь – февраль 2027 (низкий сезон) Логическая репликация PG14 (Hetzner) → Aurora (через DMS или нативную logical replication по TLS/VPN), синхронизация медиа в S3, дублирование трафика и сравнение. Переключение DNS с коротким read-only окном (цель меньше 5 мин, единственный согласованный плановый простой). Hetzner остаётся горячим откатом на 2–4 недели. Прод в eu-central-1, 3 AZ, 99.95% в течение 30 дней
4. DR и соответствие Февраль – апрель 2027 Aurora Global + warm standby в eu-west-1, S3 CRR, ECR и Secrets replication, FIS-эксперименты, первое полноценное DR-учение с замером RTO/RPO. GDPR: erasure workflow, журнал доступа к ПДн, Macie. Покупка SP/RI по фактическим данным. RTO меньше 60 мин и RPO меньше 15 мин подтверждены отчётом, erasure выполняется end-to-end
5. Декомпозиция (strangler fig) Март – сентябрь 2027 Порядок выделения — от низкого риска к высокому: notifications → search/catalog (+OpenSearch) → cart (DynamoDB) → GraphQL gateway → users/PII vault → orders + payments (последними, с сагой и outbox). Каждый сервис — отдельный canary-релиз с feature flags. Rails обслуживает меньше 20% трафика или выведен из эксплуатации
6. Операционная зрелость С сентября 2027, постоянно Подготовка к сезону: нагрузочный тест на ×1.5 от прогноза, scheduled scaling, LCU reservation. Ежеквартальные DR-учения, ежегодный внешний аудит и пентест, ежемесячный FinOps-обзор, ревизия IAM раз в квартал. Чёрная пятница 2027 пройдена в рамках SLA и лимита $15K

Что прислать для уточнения расчётов:

  1. Реальный объём медиа и egress (из статистики Hetzner или nginx) — это главная неопределённость в бюджете.
  2. Требования к хранению финансовых документов по юрисдикции.
  3. Решение DPO по API через CloudFront.
  4. Статус переписывания на Go/Node.js.

С этими данными я пересчитаю стоимость и при необходимости скорректирую DR-модель, например перейду на headless secondary Aurora ради экономии ещё ~$250/мес ценой RTO.

Похожие промпты

IT и Администрирование

Ревью и рефакторинг PowerShell-скрипта

Разбирает существующий скрипт PowerShell: что сломается на реальных данных, где ошибки глушатся вместо обработки и что переписать в первую очередь, а что оставить.

IT и Администрирование

Скрипт PowerShell под задачу

Пишет скрипт PowerShell с обработкой ошибок, логированием и режимом пробного прогона — так, чтобы его можно было запустить на рабочей машине и не бояться последствий.

IT и Администрирование

Диагностика проблем VPN-подключения

Методично диагностирует проблемы VPN: соединение не устанавливается, скорость падает, утекает DNS — по одному шагу, с командами под вашу ОС.

IT и Администрирование

Помощник по настройке WireGuard и OpenVPN

Пошагово разворачивает собственный VPN-сервер на WireGuard или OpenVPN: готовые команды и конфиги, firewall, клиентские профили и проверка утечек.