$ 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 запускаются в нём.

macOS
скачать Docker Desktop с docker.com
Linux
sudo apt install docker.io docker-compose-plugin
Win
Docker Desktop + WSL2 backend (в установщике)

версия ≥ 24.x. На Windows работаешь из WSL2-терминала, не из cmd.

docker --versionэтап 1

Terraform

Сам инструмент. 1.7+ обязательно: нужны removed- и import-блоки.

macOS
brew install tfenv && tfenv install 1.7.5 && tfenv use 1.7.5
Linux
git clone https://github.com/tfutils/tfenv ~/.tfenv && ln -s ~/.tfenv/bin/* /usr/local/bin/
Win
scoop install terraform # либо choco install terraform

tfenv даёт переключение версий, на Windows версия одна - обновляется через scoop.

terraform versionэтап 1

LocalStack

AWS-эмулятор. На нём поднимается весь стек capstone.

macOS
docker run -d -p 4566:4566 localstack/localstack:3
Linux
docker run -d -p 4566:4566 localstack/localstack:3
Win
docker run -d -p 4566:4566 localstack/localstack:3

проще всего через docker, одинаково на трёх ОС. CLI (pip install localstack) опционален.

curl -s http://localhost:4566/_localstack/healthэтап 1

awscli

Проверять что Terraform реально создал ресурсы в LocalStack.

macOS
brew install awscli
Linux
sudo apt install awscli # либо: pip install awscli
Win
scoop install aws # либо MSI с aws.amazon.com

в ~/.aws/config заведи профиль [profile localstack] с endpoint_url=http://localhost:4566.

aws --versionэтап 1

tflint

Линтер HCL. Ловит anti-patterns до plan.

macOS
brew install tflint
Linux
curl -s https://raw.githubusercontent.com/terraform-linters/tflint/master/install_linux.sh | bash
Win
scoop install tflint

после установки положи .tflint.hcl в корень репо, инициализируй: tflint --init.

tflint --versionэтап 5

checkov

Security-сканер HCL. Часть policy-gate в CI.

macOS
brew install checkov # либо: pip install checkov
Linux
pip install checkov
Win
pip install checkov

требует Python 3.8+. Версия 3.x.

checkov --versionэтап 5

pre-commit

Запускает fmt/validate/tflint при коммите. Защита от ломаных коммитов.

macOS
brew install pre-commit
Linux
pip install pre-commit
Win
pip install pre-commit

после клонирования template-репо обязательно запусти pre-commit install в его корне.

pre-commit --versionэтап 5

act

Локально запускает GitHub Actions workflows. CI без push в GitHub.

macOS
brew install act
Linux
curl https://raw.githubusercontent.com/nektos/act/master/install.sh | sudo bash
Win
scoop install act

для первого запуска act спросит какой образ runner использовать - выбирай medium.

act --versionэтап 5

opa

Policy engine. Проверяет plan.json по Rego-правилам.

macOS
brew install opa
Linux
curl -L -o opa https://openpolicyagent.org/downloads/latest/opa_linux_amd64_static && chmod +x opa && sudo mv opa /usr/local/bin/
Win
scoop install opa
opa versionэтап 5

terragrunt

Обёртка над Terraform. Финальный run-all apply поверх всех слоёв.

macOS
brew install terragrunt
Linux
curl -L https://github.com/gruntwork-io/terragrunt/releases/latest/download/terragrunt_linux_amd64 -o /usr/local/bin/terragrunt && chmod +x /usr/local/bin/terragrunt
Win
scoop install terragrunt

версия ≥ 0.55. На macOS можно через tgenv для переключения версий.

terragrunt --versionэтап 6

infracost

Оценка стоимости плана. Реальные prices поверх LocalStack-плана.

macOS
brew install infracost
Linux
curl -fsSL https://raw.githubusercontent.com/infracost/infracost/master/scripts/install.sh | sh
Win
scoop install infracost

после установки: infracost auth login, получишь бесплатный API-ключ.

infracost --versionэтап 6

Rover

Визуализирует terraform-граф интерактивно. Скриншот для портфолио.

macOS
docker run -p 9000:9000 -v $(pwd):/src im2nguyen/rover
Linux
docker run -p 9000:9000 -v $(pwd):/src im2nguyen/rover
Win
docker run -p 9000:9000 -v ${PWD}:/src im2nguyen/rover

проще всего через 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. Этап 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 считаешь до того как написал первую строчку.

    Уроки

    hint · Продумай иерархию state до того как заведёшь первый ресурс. Переразбить state после apply дороже, чем потратить лишние пять минут на дизайн слоёв.

  2. Этап 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.

    Уроки

    hint · LocalStack не эмулирует все edge-кейсы Transit Gateway или PrivateLink, для capstone их и не нужно. Если в реальном проекте появятся, поведение Terraform остаётся тем же, изменится только что покажет облако.

  3. Этап 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.

    Уроки

    hint · ALB target group health-check это частая причина «всё зелёное, но сервис недоступен». Проверь что path и port совпадают с тем что слушает контейнер.

  4. Этап 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.

    Уроки

    hint · Документируй ограничения LocalStack прямо в комментариях HCL: это «зачем тут такой паттерн» для следующего ревьювера. В проде RDS Aurora работает иначе, и ты увидишь это только если оставил пометку.

  5. Этап 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 он не поднимается.

    Уроки

    hint · Не пытайся прогнать act локально по полному пайплайну в первый раз, иди шагами. Сначала fmt-check job, потом validate, потом tflint, потом checkov, потом plan. Каждый шаг проверь отдельно, будет проще когда что-то падает.

  6. Этап 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 для портфолио, на собеседованиях полезнее чем сертификат.

    Уроки

    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; эта же страница это продлённая версия с разбиением на этапы и свободным темпом.