$ terraform apply -target=career
MiniCo Cloud Platform.
Сквозной проект, 1–2 недели.
MiniCo это выдуманная компания, которой нужна типовая stateful облачная платформа: веб-сервис за балансировщиком, асинхронные обработчики, object storage, IAM, monitoring. Ты строишь её на Terraform, по слоям, с CI/CD-пайплайном и policy-gate. Реального AWS нет, всё на LocalStack.
Где это делается. Capstone это работа на твоей машине, в твоём собственном git-репозитории на GitHub. Не в учебной песочнице. Уроки и /lab дают песочницу с предустановленным Terraform и LocalStack, чтобы отрабатывать отдельные приёмы. Capstone это переход дальше: ты живёшь со стеком неделю-две, делаешь шесть PR, ловишь интеграционные проблемы - это можно только локально. Что поставить и как проверить окружение - следующая секция.
Это не урок. Уроки уже пройдены, capstone собирает их в один артефакт. Шесть этапов; каждый занимает ~1–2 дня работы, если делаешь после основного дня, или 1 день если выделяешь целиком. Финал: working stack, CI-pipeline, plan-as-artefact, dashboard, retrospective.
Это и есть то, что обычно показывают на собеседованиях. Один работающий проект побеждает три сертификата.
Что поставить на машину
Уроки и /lab работают в учебной песочнице - там ничего ставить не надо. Capstone это твой собственный репозиторий на твоей машине, поэтому набор инструментов нужен локально. Не ставь всё разом - колонка нужно на этапе показывает, когда что появится. Этапы 1-4 живут на Docker + Terraform + LocalStack; tflint/checkov/ act/opa нужны только когда дойдёшь до CI; terragrunt/infracost/ Rover - на финале.
| Инструмент / зачем | Установка (выбери свою ОС) | Проверка | Нужно на этапе |
|---|---|---|---|
Docker Контейнерный рантайм. LocalStack и act запускаются в нём. |
версия ≥ 24.x. На Windows работаешь из WSL2-терминала, не из cmd. | docker --version | этап 1 |
Terraform Сам инструмент. 1.7+ обязательно: нужны removed- и import-блоки. |
tfenv даёт переключение версий, на Windows версия одна - обновляется через scoop. | terraform version | этап 1 |
LocalStack AWS-эмулятор. На нём поднимается весь стек capstone. |
проще всего через docker, одинаково на трёх ОС. CLI (pip install localstack) опционален. | curl -s http://localhost:4566/_localstack/health | этап 1 |
awscli Проверять что Terraform реально создал ресурсы в LocalStack. |
в ~/.aws/config заведи профиль [profile localstack] с endpoint_url=http://localhost:4566. | aws --version | этап 1 |
tflint Линтер HCL. Ловит anti-patterns до plan. |
после установки положи .tflint.hcl в корень репо, инициализируй: tflint --init. | tflint --version | этап 5 |
checkov Security-сканер HCL. Часть policy-gate в CI. |
требует Python 3.8+. Версия 3.x. | checkov --version | этап 5 |
pre-commit Запускает fmt/validate/tflint при коммите. Защита от ломаных коммитов. |
после клонирования template-репо обязательно запусти pre-commit install в его корне. | pre-commit --version | этап 5 |
act Локально запускает GitHub Actions workflows. CI без push в GitHub. |
для первого запуска act спросит какой образ runner использовать - выбирай medium. | act --version | этап 5 |
opa Policy engine. Проверяет plan.json по Rego-правилам. |
| opa version | этап 5 |
terragrunt Обёртка над Terraform. Финальный run-all apply поверх всех слоёв. |
версия ≥ 0.55. На macOS можно через tgenv для переключения версий. | terragrunt --version | этап 6 |
infracost Оценка стоимости плана. Реальные prices поверх LocalStack-плана. |
после установки: infracost auth login, получишь бесплатный API-ключ. | infracost --version | этап 6 |
Rover Визуализирует terraform-граф интерактивно. Скриншот для портфолио. |
проще всего через docker - биться с go install не стоит. Открывается на localhost:9000. | rover --version | этап 6 |
Чтобы убедиться что окружение готово к старту этапа 1, прогони этот блок:
# базовый стек - нужен с первого этапа docker --version terraform version # требуется ≥ 1.7 aws --version localstack --version # либо: docker run --rm -p 4566:4566 localstack/localstack:3 # проверим что LocalStack живой curl -s http://localhost:4566/_localstack/health | head -20
Заведи отдельный git-репозиторий minico-cloud-platform на GitHub. Каждый из шести этапов это отдельный PR в этот репо. История по PR -то, что потом показывают на собеседовании.
Что строим
Типовая stateful-платформа. Похожая на то, что у большинства SaaS до 50 человек в команде.
- VPC
- 2 AZ, public + private subnets, NAT
- ALB
- L7 балансировщик, target group → ECS
- ECS Fargate
- кластер + сервис + task definition, IAM execution role
- Lambda
- асинхронный обработчик S3-events; archive_file + source_code_hash
- S3
- 2 бакета: app data (с lifecycle) и terraform state backend
- DynamoDB
- lock table для backend; стенд-ин вместо RDS
- IAM
- роли для ECS, Lambda, GHA через OIDC, least-privilege
- CloudWatch
- logs для ECS/Lambda; metric alarms на ALB 5xx
┌─────────────────────────────────────────────┐
│ GitHub Actions (через act) │
│ PR: fmt → validate → tflint → checkov → │
│ plan → OPA-gate → comment │
│ main: apply из plan.tfplan │
│ cron: drift-detection (detailed-exitcode 2)│
└────────────────┬────────────────────────────┘
▼ OIDC
┌─────────────────────────────────────────────┐
│ LocalStack (AWS-эмуляция) │
│ │
│ VPC (2 AZ) │
│ ├─ public ─ ALB ─► ECS Fargate service │
│ └─ private ─ Lambda ◄ S3 events │
│ │
│ S3 ─ app data / state backend │
│ DynamoDB ─ lock table │
│ IAM ─ ECS / Lambda / GHA OIDC │
│ CloudWatch ─ logs + alarms │
└─────────────────────────────────────────────┘Шесть этапов
Делай по порядку. Каждый этап это отдельный PR. К концу будет рабочий стек и git-история, по которой видно как собирался.
- Этап 1
Foundation: project layout и remote state
цель · Подготовить структуру репозитория, поднять S3-backend в LocalStack, поделить state по слоям.
Один root-модуль на всё быстро превращается в проблему: blast radius растёт, plan тормозит, конкурентные apply конфликтуют. Поэтому в capstone сразу делим на network/, platform/, services/, каждый слой это отдельный state. LocalStack-backend это S3-бакет, который ты создаёшь bootstrap-скриптом и потом ссылаешь из backend-блока. DynamoDB для блокировки тоже эмулируется. Иерархия из tf-large-scale-state твой ориентир, blast radius считаешь до того как написал первую строчку.
Уроки
- tf-intermediate-06-remote-backendRemote state в S3 (LocalStack)
- tf-intermediate-12-multi-env-layoutMulti-env: workspaces vs директории
- tf-advanced-04-large-scale-stateLarge-scale state: разбиение монолита
hint · Продумай иерархию state до того как заведёшь первый ресурс. Переразбить state после apply дороже, чем потратить лишние пять минут на дизайн слоёв.
- Этап 2
Network layer: VPC, subnets, security groups
цель · Поднять VPC с публичными и приватными подсетями в двух AZ, NAT, маршруты, security groups.
Network это самый длинный список ресурсов и самые тяжёлые changes (NAT, route table занимают минуты). LocalStack VPC эмулируется в core, поэтому ты увидишь почти ту же модель что в реальном AWS. В capstone берём внешний vpc-модуль (terraform-aws-modules/vpc/aws): он закрывает 80% повседневных VPC-конфигов и экономит сотни строк HCL. Свой VPC-модуль имеет смысл писать, когда нужен нетипичный layout (custom routing, mirror sessions, особые tagging-схемы) или жёсткий compliance-контракт. Версионирование модулей через registry, а не git: чище CI и lockfile.
Уроки
- tf-intermediate-01-first-moduleСвой первый модуль: выноси S3 в reusable
- tf-intermediate-02-module-from-registryМодуль из Terraform Registry
- tf-intermediate-03-module-for-eachfor_each над модулем: N экземпляров одним блоком
hint · LocalStack не эмулирует все edge-кейсы Transit Gateway или PrivateLink, для capstone их и не нужно. Если в реальном проекте появятся, поведение Terraform остаётся тем же, изменится только что покажет облако.
- Этап 3
Compute: ECS Fargate + ALB
цель · Поднять ECS-кластер в Fargate-режиме, ALB перед ним, target group, container definition.
EKS в LocalStack Community не работает (платная фича), поэтому Fargate. В реальном AWS выбор между ECS Fargate и EKS зависит от команды: Fargate проще операционно (нет nodes, нет kubelet, нет апгрейдов кластера), EKS даёт стандартный k8s API и экосистему (Helm, controllers, GitOps). Для одного-двух сервисов и небольшой команды Fargate обычно дешевле по operational cost; на 30+ микросервисах и платформенной команде уже стоит смотреть на EKS. Один сервис на старт, dynamic-блоки для портов и переменных окружения, templatefile для container definition. Provider-aws ставит security defaults, но Checkov всё равно найдёт что покритиковать, ты увидишь типичный suppression-flow.
Уроки
- tf-intermediate-04-dynamic-blocksdynamic блоки: повторяющиеся подблоки
- tf-intermediate-05-templatefiletemplatefile: рендерим конфиги из HCL
- tf-intermediate-10-preconditionspreconditions, postconditions и check блок
hint · ALB target group health-check это частая причина «всё зелёное, но сервис недоступен». Проверь что path и port совпадают с тем что слушает контейнер.
- Этап 4
Data plane: S3, Lambda, IAM
цель · Положить object storage (S3 с lifecycle-правилами), асинхронный обработчик (Lambda), правильно собрать IAM-роли.
S3 это база. Lambda нужна для асинхронных задач (например, обрабатывать загруженные объекты через S3 event). IAM это самая частая причина что «работает у меня, не работает в проде»: scope ролей и assume_role_policy. archive_file провайдер пакует Lambda-код в zip, source_code_hash триггерит redeploy. LocalStack RDS Community поддерживает только Postgres community-edition, ограничения: no IAM auth, no parameter groups в полном объёме. Для capstone S3 + DynamoDB заменяют RDS.
Уроки
- tf-intermediate-11-utility-providersrandom, time, archive, external
- tf-beginner-07-data-sourceData sources: читаем что есть
- tf-intermediate-10-preconditionspreconditions, postconditions и check блок
hint · Документируй ограничения LocalStack прямо в комментариях HCL: это «зачем тут такой паттерн» для следующего ревьювера. В проде RDS Aurora работает иначе, и ты увидишь это только если оставил пометку.
- Этап 5
CI/CD: pipeline, policy-gate, drift detection
цель · Собрать GitHub Actions pipeline через act, plan на PR, OPA-gate, scheduled drift detection.
Pre-commit (fmt/validate/tflint) на разработчика, GHA на PR. Plan становится артефактом, apply из артефакта. OPA-policy проверяет что нет публичных S3 и захардкоженных секретов. Scheduled workflow с -detailed-exitcode ловит drift. OIDC обязательно: никаких access keys в репозитории. CloudFront в LocalStack эмулируется ограниченно. Оставь его в отдельной директории как «реальный AWS вариант», документируй что в sandbox он не поднимается.
Уроки
- tf-production-01-fmt-validate-tflintЛинтеры: fmt, validate, tflint
- tf-production-02-pre-commitpre-commit hooks для Terraform
- tf-production-05-checkovCheckov security scan
- tf-production-06-opa-regoOPA + Rego policy-gate на plan.json
- tf-production-08-github-actionsGitHub Actions pipeline через act
- tf-production-09-oidcOIDC: passwordless CI к AWS
- tf-production-10-drift-detectionDrift через scheduled plan
hint · Не пытайся прогнать act локально по полному пайплайну в первый раз, иди шагами. Сначала fmt-check job, потом validate, потом tflint, потом checkov, потом plan. Каждый шаг проверь отдельно, будет проще когда что-то падает.
- Этап 6
Observability и финал: monitoring, cost, выводы
цель · CloudWatch alarms на ALB и Lambda, dashboard, оценка стоимости через Infracost, выводы и retrospective.
CloudWatch в LocalStack эмулирует базово: alarm и dashboard можно создать через HCL, ALB-метрики идут. Infracost требует токен и реальные prices, для capstone это «как бы было если бы в реальном AWS». Финал: запусти весь стек целиком (terragrunt run-all apply), сделай скриншот плана и архитектуры через Rover, напиши retrospective про то что было сложно, где ошибся, что бы переделал. Это твой artefact для портфолио, на собеседованиях полезнее чем сертификат.
Уроки
- tf-advanced-01-terragruntTerragrunt: DRY между dev/stage/prod
- tf-advanced-06-cost-infracostInfracost: оценка стоимости плана
- tf-advanced-08-capstoneCapstone: VPC + ALB + ECS Fargate + Lambda (учебный)
hint · Retrospective это не школьное «что узнал». Запиши три конкретных решения которые ты бы переделал и почему. Это и есть инженерная зрелость.
Что в capstone не делаем
Некоторые сервисы LocalStack Community эмулирует ограниченно или не эмулирует совсем. Это не запрет, а явный scope-cut, чтобы capstone оставался учебным.
- CloudFront
- эмулируется ограниченно в LocalStack Community; держи как «реальный AWS вариант» с пометкой в HCL
- RDS Aurora
- community-edition не поддерживает Aurora; используй S3 + DynamoDB как стенд-ин
- Route 53 hosted zones
- для domains нужен реальный AWS; для sandbox оставь plain ALB DNS
- EKS
- платная фича LocalStack Pro; ECS Fargate это функциональный эквивалент для capstone
- Multi-region
- провайдер можно навесить, но облако не отвечает на cross-region calls
Когда дойдёт до реального AWS, HCL почти не изменится. Уберёшьendpoints { ... }из провайдера, IAM-роли потребуют чуть других policy-arns. Само мышление останется тем же.
Что в финале
- Git-репозиторий с историей по этапам. Шесть PR, каждый это отдельный слой, читаемый коммит-стек.
- Working stack:
terragrunt run-all applyподнимает всё в LocalStack за один проход. - CI-pipeline через act: PR-pipeline зелёный, policy-gate срабатывает на подсунутом плохом изменении.
- Архитектурный диаграмма через Rover: свежий граф зависимостей, который можно показать на собеседовании.
- Retrospective.md: три решения которые переделал бы, и почему. Это и есть то, ради чего capstone.
Прежде чем начать
Беги по /intro если ещё не. Там карта треков. Шпаргалка команд под рукой: /cheatsheet. Учебный capstone-урок (одношаговый): tf-advanced-08-capstone; эта же страница это продлённая версия с разбиением на этапы и свободным темпом.