A tenant deployment automation application for System Initiative, built with Deno and TypeScript. Automates the creation of AWS Organizations accounts, SI workspaces, IAM roles via CloudFormation StackSets, and VPC infrastructure using SI templates.
- π’ AWS Organizations Account Creation - Automatically creates AWS accounts in Organizations
- π SI Workspace Provisioning - Creates and configures System Initiative workspaces for each tenant
- π IAM Role Deployment - Deploys cross-account IAM roles via CloudFormation StackSets
- π VPC Infrastructure - Deploys production-ready VPC using SI templates (2 public + 2 private subnets with NAT)
- π Real-time Progress Tracking - Timeline-based UI showing deployment progress
- ποΈ DynamoDB State Management - Stores deployment history and tenant metadata
- π¦ Docker containerization - Ready for ECS deployment
- Deno v2.0 or later installed
- Docker and Docker Compose (for local DynamoDB)
- AWS credentials with Organizations permissions
- System Initiative workspace and API token
-
Clone and create environment file:
cd pluto cp .env.example .env -
Configure
.envwith required variables:# AWS Credentials (for Organizations management) AWS_ACCESS_KEY_ID=your_access_key AWS_SECRET_ACCESS_KEY=your_secret_key AWS_SESSION_TOKEN=your_session_token_if_needed AWS_REGION=us-east-1 # System Initiative Configuration SI_WORKSPACE_ID=your_workspace_id WORKSPACE_API_TOKEN=your_si_api_token # DynamoDB Configuration (local dev) DYNAMODB_ENDPOINT=http://dynamodb-local:8000 # Server Configuration PORT=8080
Option 1: Docker Compose (Recommended)
docker-compose up --buildOption 2: Local Development
# Start DynamoDB Local separately
docker run -p 8001:8000 amazon/dynamodb-local
# Run the app
deno task dev- Web UI: http://localhost:8080
- Local DynamoDB Admin: http://localhost:8001
When you deploy a tenant, Pluto orchestrates the following steps:
- Create Changeset - Creates a new changeset in the management SI workspace
- AWS Account Component - Creates AWS Organizations Account component
- Workspace Component - Creates Workspace Management component
- Apply Changeset - Applies changeset, triggering AWS account and workspace creation
- Extract Workspace Token - Polls for and extracts the new workspace API token
- Extract AWS Account ID - Retrieves the created AWS account ID
- Store Data - Saves workspace token and AWS account ID to DynamoDB
- Deploy StackSet - Creates CloudFormation StackSet with IAM roles for SI access
- Seed Tenant Workspace - Configures the new workspace with:
- AWS Credential component (with assume role ARN)
- Region component (us-east-1)
- Deploy VPC Template - Runs SI template to create production VPC infrastructure
The VPC deployment uses the @systeminit/template CLI via a wrapper script:
- Templates are TypeScript files that define infrastructure as code
- The template runner automatically initializes context and executes the template
- VPC template creates: 2 public subnets, 2 private subnets, NAT gateway, Internet gateway, and routing
GET /- Web UI for tenant managementPOST /api/test-aws- Test AWS Organizations credentialsPOST /api/test-dynamodb- Test DynamoDB connectionPOST /api/save-config- Save deployment configurationPOST /api/deploy-tenant/start- Start tenant deployment (returns deploymentId)GET /api/deploy-tenant/progress/:deploymentId- Get real-time deployment progressGET /api/tenant-deployments- List all tenant deploymentsGET /api/tenant-deployments/:deploymentId- Get specific deployment detailsPOST /api/prune-database- Clear all database records
docker build -t pluto-app .docker run -p 8080:8080 \
-e AWS_ACCESS_KEY_ID=your_key \
-e AWS_SECRET_ACCESS_KEY=your_secret \
-e AWS_REGION=us-east-1 \
pluto-appThe Docker image is ready for ECS deployment. Configure environment variables in your ECS task definition.
| Variable | Description | Required | Default |
|---|---|---|---|
PORT |
Server port | No | 8080 |
AWS_ACCESS_KEY_ID |
AWS Organizations admin access key | Yes | - |
AWS_SECRET_ACCESS_KEY |
AWS Organizations admin secret key | Yes | - |
AWS_SESSION_TOKEN |
AWS session token (if using temp creds) | No | - |
AWS_REGION |
AWS region for Organizations API | No | us-east-1 |
DYNAMODB_ENDPOINT |
DynamoDB endpoint (local dev) | No | - |
SI_WORKSPACE_ID |
Management SI workspace ID | Yes | - |
WORKSPACE_API_TOKEN |
Management SI workspace API token | Yes | - |
src/
βββ main.ts # Main Hono server with API routes
βββ services/
β βββ deployment.ts # Main deployment orchestration
β βββ changeset.ts # SI changeset operations
β βββ component.ts # SI component management
β βββ dynamodb.ts # DynamoDB state persistence
β βββ aws-credentials.ts # AWS credential handling
β βββ workspace.ts # Workspace API integration
β βββ token-extractor.ts # Workspace token extraction
βββ si-templates/
β βββ aws-standard-vpc.ts # VPC infrastructure template
β βββ aws-standard-vpc-prod-input.yaml # VPC template inputs
β βββ run-cli.ts # SI template CLI wrapper
βββ templates/
βββ index.html # Web UI
- Deno Runtime - Modern TypeScript/JavaScript runtime
- Hono - Fast web framework
- @systeminit/api-client - SI API TypeScript client
- @systeminit/template - SI template engine
- @aws-sdk/client-dynamodb - AWS DynamoDB SDK
- @aws-sdk/credential-providers - AWS credential management
Templates are located in src/si-templates/. To create a new template:
- Create a TypeScript file exporting a default function
- Use
TemplateContextAPI to define infrastructure - Add corresponding input YAML file for parameters
- Update deployment service to call the template
Example:
import { TemplateContext } from "@systeminit/template";
export default function (c: TemplateContext) {
c.name("My Template");
c.changeSet(`${c.name()} - ${c.invocationKey()}`);
// Define components, subscriptions, etc.
}deno task test # When tests are added"Context has not been initialized"
- Ensure you're using the CLI wrapper (
run-cli.ts) not importingrunTemplatedirectly - The wrapper properly initializes the SI template context
"Cannot set secrets directly on component"
- Use
attributesfield with$sourcesubscriptions, notsecretsfield - Check socket names (e.g.,
/secrets/credentialnot/secrets/AWS Credential)
DynamoDB connection issues
- Verify
DYNAMODB_ENDPOINTis set correctly for local dev - Check Docker Compose network connectivity
Workspace token not found
- Token extraction can take time; check polling logs
- Ensure Workspace Management component action completed successfully
MIT