Skip to content

Infrastructure as Code

MolnOS IaC provides declarative infrastructure management through a single JSON file. Define your functions, databases, storage buckets, sites, schemas, and identities in molnos.json and apply them with one command.

Define your entire infrastructure in a single molnos.json file. Resources are grouped by type with natural, readable structure.

Resources belong to contexts—logical groupings that represent applications, services, or workloads. Contexts enable safe pruning and clear ownership.

No state file. MolnOS queries live resources by natural key (name, email, etc.) and reconciles: create if missing, update if exists.

Add $schema to your molnos.json for autocomplete, inline documentation, and validation in VSCode and other editors:

{
"$schema": "https://schemas.molnos.cloud/schema-iac-v1.json",
"version": "1",
...
}
  • Application Deployment: Define functions, databases, and storage for a complete application stack
  • Environment Replication: Use the same molnos.json across dev, staging, and production
  • GitOps Workflows: Store infrastructure as code in version control alongside application code
  • Team Onboarding: New developers get identical infrastructure with one command
  • Disaster Recovery: Rebuild infrastructure from declarative definitions
{
"$schema": "https://schemas.molnos.cloud/schema-iac-v1.json",
"version": "1",
"context": {
"name": "my-service",
"intent": "Handles user authentication and sessions."
},
"resources": {
"functions": {
"auth-api": {
"source": "./dist/auth.js",
"methods": ["POST"],
"bindings": [
{ "service": "databases", "resource": "sessions", "permissions": ["read", "write"] }
]
}
},
"databases": {
"sessions": {},
"users": {}
},
"storage": {
"avatars": { "public": true }
},
"schemas": {
"session-created": {
"schema": {
"properties": {
"userId": { "type": "string" },
"token": { "type": "string" }
},
"required": ["userId", "token"]
}
}
}
}
}
Terminal window
# Validate configuration without applying
molnos validate
# Show what would change
molnos diff
# Apply configuration
molnos apply
# Apply and remove resources not in file (within context only)
molnos apply --prune
# Apply a specific file
molnos apply path/to/molnos.json

IaC operations are also available via HTTP. The request body is the full IaC configuration object:

Terminal window
# Validate configuration
POST /iac/validate
Content-Type: application/json
{
"version": "1",
"context": { "name": "my-service" },
"resources": { ... }
}
# Show diff
POST /iac/diff
Content-Type: application/json
{
"version": "1",
"context": { "name": "my-service" },
"resources": { ... }
}
# Apply configuration
POST /iac/apply
Content-Type: application/json
{
"version": "1",
"context": { "name": "my-service" },
"resources": { ... }
}
# Apply with pruning (removes resources not in config)
POST /iac/apply?prune=true
Content-Type: application/json
{
"version": "1",
"context": { "name": "my-service" },
"resources": { ... }
}

Functions require either source (file path) or code (inline content):

{
"functions": {
"my-api": {
"source": "./dist/handler.js",
"methods": ["GET", "POST"],
"triggers": [
{ "type": "http" },
{ "type": "event", "eventName": "order-created" }
],
"allowUnauthenticated": false,
"bindings": [
{ "service": "databases", "resource": "data", "permissions": ["read"] }
]
}
}
}

When using the API directly, you can provide inline code instead of a file path:

{
"functions": {
"my-api": {
"code": "export async function handler(event) { return { statusCode: 200 }; }",
"methods": ["GET"]
}
}
}

The CLI reads source files and sends inline code to the API automatically.

{
"databases": {
"users": {},
"sessions": {},
"audit-log": {}
}
}

Empty object {} is valid—it declares the table exists.

{
"storage": {
"uploads": { "public": false },
"assets": { "public": true }
}
}

Sites require either source (directory path) or files (inline content):

{
"sites": {
"dashboard": {
"source": "./dist/site"
}
}
}

When using the API directly, you can provide inline files instead of a directory path. File content must be base64-encoded:

{
"sites": {
"dashboard": {
"files": [
{ "path": "index.html", "content": "PCFET0NUWVBFIGh0bWw+Li4u" },
{ "path": "styles.css", "content": "Ym9keSB7IG1hcmdpbjogMDsgfQ==" }
]
}
}
}

The CLI reads source directories, base64-encodes file content, and sends inline files to the API automatically.

Define event schemas declaratively. Schemas are created or updated on apply, and deleted on prune:

{
"schemas": {
"order-created": {
"description": "Emitted when a new order is placed",
"schema": {
"properties": {
"orderId": { "type": "string" },
"amount": { "type": "number" },
"currency": { "type": "string" }
},
"required": ["orderId", "amount", "currency"],
"additionalProperties": false
}
}
}
}

When a schema already exists, applying updates the definition and increments the version automatically.

{
"identities": {
"users": {
"admin": {
"email": "[email protected]",
"roles": ["administrator"]
}
},
"serviceAccounts": {
"batch-processor": {
"roles": ["user"],
"description": "Nightly data processing"
}
}
}
}

Contexts group related resources. All resources in a file belong to the same context.

{
"context": {
"name": "billing-service",
"intent": "Handles invoicing and payment processing.",
"attributes": {
"data": { "sensitivity": "high" },
"owner": "[email protected]"
}
}
}

If context is omitted, resources go to the default context.

Terminal window
# List all contexts
molnos context list
# Show context details
molnos context show billing-service
# Delete all resources in a context (keeps the context)
molnos context delete-resources billing-service
# Delete the context metadata (after resources are deleted)
molnos context delete billing-service
# Destroy context and all its resources (combines both operations)
molnos context destroy billing-service
Terminal window
# List all contexts
GET /contexts
# Get context details
GET /contexts/:contextName
# Create a context
POST /contexts
Content-Type: application/json
{ "name": "my-context", "intent": "Description" }
# Update a context
PATCH /contexts/:contextName
Content-Type: application/json
{ "intent": "Updated description" }
# Delete all resources in a context
DELETE /contexts/:contextName/resources
# Delete context metadata
DELETE /contexts/:contextName

The DELETE /contexts/:contextName/resources endpoint removes all actual resources (functions, databases, storage, sites, schemas, applications, users, service accounts) within the context. It returns a detailed response:

{
"success": true,
"context": "billing-service",
"deleted": [
{ "type": "function", "name": "invoice-api" },
{ "type": "database", "name": "invoices" }
],
"errors": [],
"summary": {
"totalResources": 2,
"deletedCount": 2,
"failedCount": 0
}
}

IaC operations require appropriate permissions:

  • iac.validate - Validate IaC configurations
  • iac.diff - View what would change
  • iac.apply - Apply IaC configurations

Additionally, users need permissions for the resources being created:

  • functions.create, databases.create, storage.bucket.create, schemas.schema.create, etc.