Getting Started
ts-cloud is an Infrastructure as Code library for TypeScript that generates AWS CloudFormation templates.
Installation
npm install ts-cloud
pnpm add ts-cloud
bun add ts-cloud
Basic Usage
Creating a Stack
import { CloudFormation } from 'ts-cloud'
const stack = new CloudFormation('my-app-stack', {
Description: 'My application infrastructure',
})
// Add resources
stack.addResource('MyResource', {
Type: 'AWS::S3::Bucket',
Properties: {
BucketName: 'my-bucket',
},
})
// Generate template
const template = stack.toJSON()
Template Builder
Use the fluent template builder API:
import { TemplateBuilder } from 'ts-cloud'
const template = new TemplateBuilder()
.description('My infrastructure')
.addParameter('Environment', {
Type: 'String',
Default: 'dev',
AllowedValues: ['dev', 'staging', 'prod'],
})
.addResource('VPC', {
Type: 'AWS::EC2::VPC',
Properties: {
CidrBlock: '10.0.0.0/16',
EnableDnsHostnames: true,
Tags: [
{ Key: 'Name', Value: { Ref: 'AWS::StackName' } },
],
},
})
.addOutput('VpcId', {
Value: { Ref: 'VPC' },
Export: { Name: 'VpcId' },
})
.build()
Intrinsic Functions
Use CloudFormation intrinsic functions:
import { Fn, Pseudo } from 'ts-cloud'
const template = new TemplateBuilder()
.addResource('Bucket', {
Type: 'AWS::S3::Bucket',
Properties: {
// Reference parameter
BucketName: Fn.Sub('${Environment}-${AppName}-bucket'),
// Join strings
Tags: [
{
Key: 'FullName',
Value: Fn.Join('-', [
Pseudo.StackName,
'bucket',
]),
},
],
},
})
.build()
Available Functions
// Reference
Fn.Ref('ResourceName')
// Get attribute
Fn.GetAtt('ResourceName', 'AttributeName')
// Join
Fn.Join('-', ['a', 'b', 'c'])
// Sub (substitute)
Fn.Sub('${AWS::StackName}-resource')
// If condition
Fn.If('ConditionName', 'trueValue', 'falseValue')
// Select from list
Fn.Select(0, ['a', 'b', 'c'])
// Split string
Fn.Split(',', 'a,b,c')
// Base64 encode
Fn.Base64('string')
// Pseudo parameters
Pseudo.StackName
Pseudo.StackId
Pseudo.Region
Pseudo.AccountId
Resource Naming
Generate consistent resource names:
import { ResourceNaming } from 'ts-cloud'
const naming = new ResourceNaming({
prefix: 'myapp',
environment: 'prod',
separator: '-',
})
const bucketName = naming.name('assets')
// 'myapp-prod-assets'
const functionName = naming.name('handler', { suffix: 'lambda' })
// 'myapp-prod-handler-lambda'
Configuration File
Create a cloud.config.ts file:
import type { CloudConfig } from 'ts-cloud'
export default {
name: 'my-app',
region: 'us-east-1',
environments: {
dev: {
account: '123456789012',
region: 'us-east-1',
},
prod: {
account: '987654321098',
region: 'us-west-2',
},
},
stacks: {
network: './stacks/network.ts',
database: './stacks/database.ts',
application: './stacks/application.ts',
},
} satisfies CloudConfig
Stack Definition
Define stacks in separate files:
// stacks/network.ts
import { defineStack } from 'ts-cloud'
export default defineStack({
name: 'network',
resources: (ctx) => ({
VPC: {
Type: 'AWS::EC2::VPC',
Properties: {
CidrBlock: '10.0.0.0/16',
EnableDnsHostnames: true,
},
},
PublicSubnet: {
Type: 'AWS::EC2::Subnet',
Properties: {
VpcId: { Ref: 'VPC' },
CidrBlock: '10.0.1.0/24',
AvailabilityZone: { 'Fn::Select': [0, { 'Fn::GetAZs': '' }] },
MapPublicIpOnLaunch: true,
},
},
}),
outputs: {
VpcId: {
Value: { Ref: 'VPC' },
Export: { Name: 'VpcId' },
},
},
})
Template Validation
Validate templates before deployment:
import { validateTemplate, validateResourceLimits } from 'ts-cloud'
const template = stack.toJSON()
// Validate template structure
const result = validateTemplate(template)
if (!result.valid) {
console.error('Validation errors:', result.errors)
}
// Check resource limits
const limitsResult = validateResourceLimits(template)
if (!limitsResult.valid) {
console.warn('Resource limit warnings:', limitsResult.warnings)
}
Dependency Graph
Visualize resource dependencies:
import { DependencyGraph } from 'ts-cloud'
const graph = new DependencyGraph(template)
// Get deployment order
const order = graph.getDeploymentOrder()
console.log('Deploy in order:', order)
// Check for circular dependencies
const circular = graph.findCircularDependencies()
if (circular.length > 0) {
console.error('Circular dependencies found:', circular)
}
Stack Diff
Compare templates before deployment:
import { diffStacks } from 'ts-cloud'
const currentTemplate = await loadCurrentTemplate()
const newTemplate = stack.toJSON()
const diff = diffStacks(currentTemplate, newTemplate)
console.log('Resources to add:', diff.added)
console.log('Resources to remove:', diff.removed)
console.log('Resources to update:', diff.modified)
CLI Commands
# Initialize project
cloud init my-project
# Generate templates
cloud generate
# Validate templates
cloud validate
# Show diff against deployed stack
cloud diff --stack my-stack
# Deploy stack
cloud deploy --stack my-stack
# Deploy all stacks
cloud deploy --all
# Destroy stack
cloud destroy --stack my-stack
Next Steps
- Cloud Providers - AWS resource types
- Deployment - Deploy infrastructure