Skip to content

Deployment

VentureKit applications are deployed to AWS using CDK through the vk CLI.

  • AWS credentials configured (aws configure or environment variables)
  • Node.js >= 20
  • VentureKit project initialized with vk init

Start a local development server with hot-reloading:

Terminal window
vk dev

This 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
Terminal window
vk dev --stage my-dev
Terminal window
vk deploy
Terminal window
vk deploy --stage stage
Terminal window
vk deploy --stage prod

Deploy VentureKit at zero cost using only AWS free-tier services:

config/dev.ts
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)

The VENTURE_STAGE environment variable maps to your config files:

StageConfigTypical Preset
devconfig/dev.tsfree or nano
stageconfig/stage.tsmicro
prodconfig/prod.tsmedium or large
Terminal window
# These are equivalent:
vk deploy --stage prod
VENTURE_STAGE=prod vk deploy

Remove deployed resources:

Terminal window
# 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 --yes
name: Deploy
on:
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-1

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:...',
},
},
};

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:

Terminal window
VK_MULTI_STACK=1 vk deploy --stage prod

The deploy synthesizes seven stacks instead of one, named <project>-<stage>-<tier>:

TierOwns
networkVPC, subnets, NAT, security groups, flow logs
dataRDS / DynamoDB / S3 / ElastiCache + the migration runner
identityCognito User Pools, federated provider Secrets
configTop-level secrets intent (skipped if you declare none)
messagingSQS queues, SNS topics, SES configuration sets, dispatcher/bounce DLQs
edgeCloudFront distributions, custom domains, ACM cert references
appLambdas (route / queue / cron / notify handlers), HttpApi routes, IAM role
  • Independent lifecycles. A typical week churns Lambda code dozens of times but never touches RDS. With seven stacks a cdk deploy <project>-<stage>-app updates 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.
  • 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).

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 prod orphans 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.

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.

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