IaaS K8s Deployment Package
This is a TypeScript package for deploying Kubernetes infrastructure across multiple cloud providers (AWS, GCP) using Pulumi automation. It supports both dedicated and shared deployment types for cost optimization and resource efficiency.
🚀 New Features
Dynamic Helm Values Generation
- Automatic configuration: No longer requires manual Helm values files
- Cloud provider-aware defaults: Automatically configures images and settings based on your cloud provider
- Optional overrides: Use
--valuesFileonly when you need to override generated defaults - Smart merging: Combines dynamic values + tier allocation + user overrides seamlessly
Deployment Types
Dedicated Deployments (Default)
- Creates a new Kubernetes cluster for each company
- Complete infrastructure isolation
- Higher cost, maximum security
- Auto-configures HPA (Horizontal Pod Autoscaling) for optimal performance
Shared Deployments (Cost-Optimized)
- Reuses existing Kubernetes clusters across multiple companies
- Namespace-level isolation with automatic network policies
- Significant cost savings through resource sharing
- Automatic cluster lookup and creation if not found
See DEPLOYMENT_TYPES.md for detailed documentation.
How to Run
Install prerequisites:
- Node.js v18+
- Pulumi CLI
- Cloud CLI tools (AWS CLI, gcloud) and credentials
Install dependencies:
npm installBuild the project:
npm run buildPrepare configuration files:
config/secrets.jsonconfig/values.jsonconfig/aws.jsonorconfig/gcp.json
Run a deployment (CLI example):
Dedicated Deployment (Default)
npm run dev -- up my-stack \ --companyName mycompany \ --secretsFile ./config/secrets.json \ --cloudProvider aws \ --cloudConfigFile ./config/aws.json \ --deploymentType dedicated \ --autoSetupConfigShared Deployment (Cost-Optimized)
npm run dev -- up my-stack \ --companyName mycompany \ --secretsFile ./config/secrets.json \ --cloudProvider gcp \ --cloudConfigFile ./config/gcp.json \ --deploymentType shared \ --namespace mycompany-prod \ --autoSetupConfigWith Custom Configuration (Optional)
You can still provide a values file for specific overrides:
npm run dev -- up my-stack \ --companyName mycompany \ --secretsFile ./config/secrets.json \ --valuesFile ./config/values-overrides.json \ --cloudProvider aws \ --cloudConfigFile ./config/aws.json \ --deploymentType dedicated \ --autoSetupConfigFor GCP, use
--cloudProvider gcpand the appropriate config file.Outputs:
- The CLI will print endpoints, DNS, and next steps.
For advanced usage and library integration, see the sections below.
Project Structure
pulumi/
├── automation.ts # Main automation entry point and library exports
├── index.ts # Primary Pulumi program for infrastructure deployment
├── package.json # Dependencies and npm scripts
├── tsconfig.json # TypeScript configuration
├── config/ # Configuration files
│ ├── secrets.json # Kubernetes secrets configuration
│ └── values.json # Helm values configuration
├── src/ # Source code organized by functionality
│ ├── index.ts # Barrel export for all modules
│ ├── cli/ # Command-line interface modules
│ ├── core/ # Core infrastructure and deployment logic
│ ├── types/ # TypeScript type definitions
│ ├── utils/ # Utility functions and helpers
│ └── examples/ # Example usage and integration tests
└── dist/ # Compiled JavaScript output (generated)
Installation
npm install @chimoney.io/iaas-k8s-deployment
Prerequisites
- Node.js >= 18.0.0
- Pulumi CLI installed on the system
- Cloud provider credentials configured (AWS CLI, gcloud, etc.)
Usage
As a Library
import {
handleDeployment,
DeploymentOptions,
} from "@chimoney.io/iaas-k8s-deployment";
const options: DeploymentOptions = {
action: "up",
stackName: "my-company-dev",
secretsJson: JSON.stringify(require("./config/secrets.json")),
companyName: "my-company",
workDir: "/path/to/pulumi/project",
cloudProvider: "aws",
cloudConfig: require("./config/cloudConfig.json"),
autoSetupConfig: true,
};
const result = await handleDeployment(options);
if (result.success) {
console.log("Deployment successful!");
console.log("Outputs:", result.outputs);
if (result.kubeconfig) {
// Save kubeconfig for kubectl access
fs.writeFileSync("kubeconfig.yaml", result.kubeconfig);
}
} else {
console.error("Deployment failed:", result.error);
}
As CLI Tool (Dynamic Values Generation)
The CLI now automatically generates Helm values based on your deployment configuration:
iaas-deploy up my-stack \
--companyName mycompany \
--secretsFile ./config/secrets.json \
--cloudProvider aws \
--cloudConfigFile ./config/cloudConfig.json \
--autoSetupConfig
Key Changes:
--valuesFileis now optional - the system generates comprehensive Helm values automatically- Values are dynamically created based on your cloud provider, deployment type, and configuration options
- Use
--valuesFileonly when you need to override the generated defaults
Example with optional overrides:
iaas-deploy up my-stack \
--companyName mycompany \
--secretsFile ./config/secrets.json \
--valuesFile ./config/custom-overrides.json \
--cloudProvider aws \
--cloudConfigFile ./config/cloudConfig.json \
--autoSetupConfig
Example for GCP:
iaas-deploy up dev \
--companyName mycompany \
--secretsFile ./config/secrets.json \
--cloudProvider gcp \
--cloudConfigFile ./config/cloudConfig.gcp.json \
--autoSetupConfig
Supported --cloudConfigFile fields
- For AWS:
{ "region": "us-east-1", "profile": "default", "accessKeyId": "...", "secretAccessKey": "..." } - For GCP:
{ "project": "my-gcp-project", "region": "us-central1", "zone": "us-central1-a", "credentials": "/path/to/key.json" }
Note: You can still use
--secretsJsonand--cloudConfigwith raw JSON strings, but using files is recommended for all non-trivial deployments.
Available Actions
up- Deploy/update infrastructurepreview- Preview changes without applyingdestroy- Destroy infrastructureoutputs- Get stack outputsrefresh- Refresh stack state
Configuration
The package now uses dynamic value generation with minimal configuration requirements:
Required Configuration
- secretsFile: Path to a JSON file containing sensitive configuration values
- companyName: String identifying the company/tenant
- stackName: Pulumi stack name (e.g., 'company-env')
- cloudProvider: Target cloud provider ('aws' or 'gcp')
- cloudConfigFile: Path to a JSON file with cloud provider config
Optional Configuration
- valuesFile: Path to a JSON file for overriding generated defaults
- deploymentType: 'dedicated' (default) or 'shared'
- namespace: Kubernetes namespace (auto-generated for shared deployments)
- planTier: Resource tier for shared deployments ('basic', 'standard', 'premium')
- (Removed) Custom Helm chart path option eliminated; bundled chart always used.
Dynamic Configuration Options
The CLI now supports extensive configuration options for fine-tuning your deployment:
- Service Control:
--enableRafikiAuth,--enableRafikiBackend,--enableNginx,--enableRedis - Custom Images:
--rafikiAuthImageRepository,--rafikiAuthImageTag, etc. - Domain Configuration:
--defaultDomainfor automatic hostname generation - HPA Settings:
--dedicatedDeploymentHpaEnabledByDefault - Network Policies:
--sharedDeploymentNetworkPolicyEnabled
Run iaas-deploy --help to see all available options.
Multi-Cloud Support
The package automatically detects cloud provider based on Pulumi configuration:
- AWS: Uses EKS for Kubernetes clusters
- GCP: Uses GKE for Kubernetes clusters
Dynamic Helm Values Generation
The package now automatically generates comprehensive Helm values based on your deployment configuration, eliminating the need for manual Helm values files in most cases.
How It Works
- Base Generation: Creates complete Helm values with sensible defaults
- Cloud Provider Optimization: Adjusts configurations based on AWS/GCP best practices
- Deployment Type Configuration:
- Dedicated: Enables HPA for optimal performance
- Shared: Configures network policies for security isolation
- Tier Integration: Merges resource allocations for shared deployments
- User Overrides: Applies any custom values from
--valuesFile - Custom chart override removed: the bundled internal chart is always used and auto-detected.
Generated Configuration Includes
- Service Enablement: All Rafiki services with appropriate defaults
- Image Configuration: Cloud provider-optimized container images
- Networking: Automatic hostname generation and ingress configuration
- Security: Network policies for shared deployments
- Scaling: HPA configuration for dedicated deployments
- Resource Management: Tier-based resource allocation for shared deployments
Example Generated Values
For a company named "acme" with domain "example.com":
companyName: acme
deploymentType: dedicated
rafikiAuth:
enabled: true
image:
repository: ghcr.io/interledger/rafiki-auth
tag: v1.0.0-alpha.20
hpa:
enabled: true # Auto-enabled for dedicated deployments
nginx:
config:
serverNameIlp: ilp.acme.example.com
serverNameAuth: auth-ilp.acme.example.com
networkPolicy:
enabled: false # Disabled for dedicated, enabled for shared
When to Use Values File
Use --valuesFile only when you need to:
- Override specific image tags or repositories
- Customize resource limits beyond tier defaults
- Add custom ingress annotations
- Configure additional services or sidecars
Helm Chart Path Simplification
All deployments now always use the bundled Helm chart (pulumi/../helm-chart). Previous override mechanisms have been removed to ensure consistency.
Return Values
The handleDeployment function returns a DeploymentResult object:
interface DeploymentResult {
success: boolean;
outputs?: any; // Pulumi stack outputs
summary?: any; // Operation summary
error?: string; // Error message if failed
kubeconfig?: string; // Kubernetes config for cluster access
}
Examples
Basic Deployment (Auto-Generated Configuration)
iaas-deploy up acme-dev \
--companyName acme \
--secretsFile ./config/secrets.json \
--cloudProvider aws \
--cloudConfigFile ./config/cloudConfig.aws.json \
--autoSetupConfig
Shared Deployment with Tier (Cost-Optimized)
iaas-deploy up acme-dev \
--companyName acme \
--secretsFile ./config/secrets.json \
--cloudProvider gcp \
--cloudConfigFile ./config/cloudConfig.gcp.json \
--deploymentType shared \
--planTier premium \
--namespace acme-production \
--autoSetupConfig
Custom Configuration with Overrides
iaas-deploy up acme-prod \
--companyName acme \
--secretsFile ./config/secrets.json \
--valuesFile ./config/custom-overrides.json \
--cloudProvider aws \
--cloudConfigFile ./config/cloudConfig.aws.json \
--defaultDomain "acme.com" \
--authDomain "auth-ilp.acme.com" \
--openPaymentsDomain "ilp.acme.com" \
--connectorDomain "ilp-connector.acme.com" \
--rafikiAuthImageTag "latest" \
--autoSetupConfig
Authentication
AWS Authentication
Follow standard AWS CLI configuration using IAM user credentials with necessary permissions for EKS, EC2, IAM, S3, etc.
aws configure
Pulumi will use these default credentials. For specific profiles:
export AWS_PROFILE=your-profile-name
GCP Authentication
Authenticate using service account or user credentials:
gcloud auth login
gcloud config set project YOUR_PROJECT_ID
Or using a service account:
export GOOGLE_APPLICATION_CREDENTIALS=/path/to/service-account-key.json
Building and Publishing
For developers working on this package:
# Build the package
npm run build
# Test locally
npm link
cd /path/to/test/project
npm link @chimoney.io/iaas-k8s-deployment
# Publish to npm
npm publish
License
MIT
Advanced: Manual Pulumi Config (Not Recommended)
You can still use manual pulumi config set ... commands if you want full control, but the recommended approach is to use the CLI's --autoSetupConfig and file-based options for all configuration.