Deployment
VentureKit applications are deployed to AWS using CDK through the vk CLI.
Prerequisites
Section titled “Prerequisites”- AWS credentials configured (
aws configureor environment variables) - Node.js >= 20
- VentureKit project initialized with
vk init
Development
Section titled “Development”Start a local development server with hot-reloading:
vk devThis starts a fully local development server that:
- Serves your routes via HTTP (no AWS credentials needed)
- Starts Docker Compose services for Postgres, Redis, and MinIO
- Loads TypeScript handlers at runtime — no build step
Custom Stage
Section titled “Custom Stage”vk dev --stage my-devDeploying
Section titled “Deploying”Dev Environment
Section titled “Dev Environment”vk deployStaging
Section titled “Staging”vk deploy --stage stageProduction
Section titled “Production”vk deploy --stage prodFree-Tier Deployment
Section titled “Free-Tier Deployment”Deploy VentureKit at zero cost using only AWS free-tier services:
import type { EnvConfigInput } from '@venturekit/core';
export const dev: EnvConfigInput = { preset: 'free', dataSafety: 'relaxed',};The free preset automatically:
- Uses Lambda (1M free requests/month) with 128 MB
- Uses API Gateway HTTP API (1M free calls/month for 12 months)
- Substitutes DynamoDB for RDS databases (25 GB always-free)
- Skips VPC and NAT gateways (not free)
- Skips ElastiCache — uses DynamoDB-based rate limiting instead
- Uses SQS (1M free requests/month) and EventBridge (free)
Environment Selection
Section titled “Environment Selection”The VENTURE_STAGE environment variable maps to your config files:
| Stage | Config | Typical Preset |
|---|---|---|
dev | config/dev.ts | free or nano |
stage | config/stage.ts | micro |
prod | config/prod.ts | medium or large |
# These are equivalent:vk deploy --stage prodVENTURE_STAGE=prod vk deployTearing Down
Section titled “Tearing Down”Remove deployed resources:
# Remove dev (no confirmation needed)vk remove
# Remove staging (requires confirmation)vk remove --stage stage
# Remove production (requires confirmation, skip with --yes)vk remove --stage prod --yesGitHub Actions Example
Section titled “GitHub Actions Example”name: Deployon: push: branches: [main]
jobs: deploy: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: actions/setup-node@v4 with: node-version: 20 - uses: pnpm/action-setup@v2 with: version: 9
- run: pnpm install - run: vk deploy --stage prod env: AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }} AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} AWS_REGION: eu-west-1Custom Domains
Section titled “Custom Domains”Configure a custom domain in your environment config:
export const prod: EnvConfigInput = { preset: 'medium', api: { customDomain: { domainName: 'api.example.com', certificateArn: 'arn:aws:acm:us-east-1:...', }, },};Multi-Stack Mode (opt-in)
Section titled “Multi-Stack Mode (opt-in)”By default vk deploy synthesizes a single CloudFormation stack per stage that owns every resource — networking, databases, Lambdas, the lot. This is the simplest layout to reason about and the right default for small projects.
For larger projects (especially production deployments handling user data) VentureKit also ships a seven-tier multi-stack layout that splits resources by lifecycle. Opt in with an environment variable:
VK_MULTI_STACK=1 vk deploy --stage prodThe deploy synthesizes seven stacks instead of one, named <project>-<stage>-<tier>:
| Tier | Owns |
|---|---|
network | VPC, subnets, NAT, security groups, flow logs |
data | RDS / DynamoDB / S3 / ElastiCache + the migration runner |
identity | Cognito User Pools, federated provider Secrets |
config | Top-level secrets intent (skipped if you declare none) |
messaging | SQS queues, SNS topics, SES configuration sets, dispatcher/bounce DLQs |
edge | CloudFront distributions, custom domains, ACM cert references |
app | Lambdas (route / queue / cron / notify handlers), HttpApi routes, IAM role |
Why opt in
Section titled “Why opt in”- Independent lifecycles. A typical week churns Lambda code dozens of times but never touches RDS. With seven stacks a
cdk deploy <project>-<stage>-appupdates the throwaway tier in ~90 seconds and leaves the stateful tiers untouched. The single-stack layout re-evaluates every resource on every deploy — slower and noisier in CFN events. - Blast-radius isolation. A bug in your edge config (e.g. a malformed CloudFront cache policy) can’t take the database with it during a failed rollback. Each tier rolls back independently.
- Cleaner ops boundaries. The data tier is owned by your DBA / SRE; the app tier by your application engineers. Splitting the CloudFormation stack mirrors that ownership.
When NOT to opt in
Section titled “When NOT to opt in”- Local dev or small projects where one stack is just simpler.
- Projects already running in single-stack mode in production — migrating an existing deployment to multi-stack is a manual cutover (see “Migrating an existing project” below).
Retention guarantees
Section titled “Retention guarantees”Both single-stack and multi-stack modes apply the same retention rules under dataSafety: 'strict':
- Every stateful resource (RDS, S3, Cognito, Secrets, ElastiCache, EventBridge buses, DLQs) carries
DeletionPolicy: Retain+UpdateReplacePolicy: Retain. - Native deletion-protection is enabled where AWS supports it (RDS, DynamoDB).
vk remove --stage prodorphans those resources rather than destroying them.
The retention guarantees are tested independently per stack tier. See @venturekit/infra’s *-stack.test.ts files for the exact invariants pinned by tests.
Migrating an existing project
Section titled “Migrating an existing project”Existing single-stack deployments cannot be flipped to multi-stack via a config change — CloudFormation does not natively split one stack into many. The cutover requires cdk import per stateful resource, executed in order. See the example runbook for the canonical pattern (RETAIN-flip → detach → cdk import → smoke test → decommission legacy).
For greenfield projects, simply set VK_MULTI_STACK=1 from the very first vk deploy and never look back.
Deploy Outputs
Section titled “Deploy Outputs”After deployment, the CLI displays:
- API URL — your API Gateway endpoint
- WebSocket URL — if WebSocket is enabled
- Stage and environment information
✅ Deployed to prod
API URL: https://abc123.execute-api.eu-west-1.amazonaws.com