Environments
Kyku has built-in workspace support for managing multiple environments (dev, staging, prod) from a single config.
How It Works
Section titled “How It Works”kyku plan --env=dev # → .kyku/state.dev.jsonkyku apply --env=staging # → .kyku/state.staging.jsonkyku plan --env=prod # → .kyku/state.prod.jsonkyku plan # → .kyku/state.json (default)Each environment has its own:
- State file — separate
.kyku/state.<env>.json - Deploy prefix — unique 8-char hex prefix per env (e.g.,
a3f27b1d-web-server) - Cloud resources — completely isolated from other environments
Per-Environment Configuration
Section titled “Per-Environment Configuration”Use TypeScript to parameterize your config:
import { Vpc, Vm, SecurityGroup } from '@kykucloud/types';
const env = process.env.KYKU_ENV || 'dev';
const configs = { dev: { instanceType: 'micro' as const, instanceCount: 1, distAzs: 1, }, staging: { instanceType: 'small' as const, instanceCount: 2, distAzs: 2, }, prod: { instanceType: 'medium' as const, instanceCount: 3, distAzs: 3, },};
const cfg = configs[env as keyof typeof configs];
const vpc = new Vpc({ id: 'vpc-main', name: `app-vpc-${env}`, cidr: '10.0.0.0/16', region: 'us-east', distributeAcrossAzs: cfg.distAzs,});
const sg = new SecurityGroup({ id: 'sg-web', name: `web-sg-${env}`, ingress: [ { protocol: 'tcp', fromPort: 80, toPort: 80, sources: ['0.0.0.0/0'] }, ],});
const servers = Array.from({ length: cfg.instanceCount }, (_, i) => new Vm({ id: `vm-web-${i}`, name: `web-server-${i}`, instanceType: cfg.instanceType, image: 'ubuntu-24.04', network: vpc, securityGroups: [sg], }));
export default { provider: 'aws', resources: [vpc, sg, ...servers] };Deploy Prefix
Section titled “Deploy Prefix”Each environment gets a unique 8-character hex deploy prefix, auto-generated on first plan/apply and stored in StateFile.metadata.prefix.
| Environment | Prefix | Example Resource Name |
|---|---|---|
| dev | a3f27b1d |
a3f27b1d-web-server-0 |
| staging | c8e41f9a |
c8e41f9a-web-server-0 |
| prod | b7d12e83 |
b7d12e83-web-server-0 |
This prevents name collisions when managing multiple environments in the same cloud account.
Custom prefix:
// In your config or engine initconst engine = new KykuEngine({ deployPrefix: 'myapp', // Custom prefix instead of random hex});Branch-Based Environments (CI)
Section titled “Branch-Based Environments (CI)”name: Deployon: push: branches: - main # → prod - dev # → dev - staging # → staging
jobs: deploy: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: oven-sh/setup-bun@v2 - run: | ENV=${{ github.ref_name }} kyku apply --env=$ENV --auto-approve env: KYKU_PASSPHRASE: ${{ secrets.KYKU_PASSPHRASE }}State Isolation
Section titled “State Isolation”State files are fully isolated per environment:
.kyku/├── state.json # default├── state.dev.json # dev├── state.staging.json # staging└── state.prod.json # prodEach state file contains its own:
- Encryption metadata (salt, IV)
- Resource tracking (provider IDs, outputs)
- Deploy prefix
Environment-Specific Config Files
Section titled “Environment-Specific Config Files”For larger differences between environments, use separate config files:
kyku plan --config=./infrastructure.dev.ts --env=devkyku plan --config=./infrastructure.prod.ts --env=prodBest Practices
Section titled “Best Practices”- Use
--envconsistently: Always pass--envto avoid mixing environments in the default state file. - CI matches env to branch: Map branches to environments automatically.
- Separate credentials: Use different cloud accounts or IAM roles per environment.
- Passphrase per env: Consider different
KYKU_PASSPHRASEvalues per environment. - Destroy selectively:
kyku destroy --env=devonly destroys dev resources.