@mesh-tech/mesh-cli
Version:
CLI for Mesh platform development utilities
96 lines (85 loc) • 4.86 kB
text/typescript
import * as pulumi from "@pulumi/pulumi";
import * as aws from "@pulumi/aws";
import { mesh, parseEnvFromStack } from "@mesh-tech/infra-components";
// ============================================================================
// Configuration
// ============================================================================
const config = new pulumi.Config("mesh");
const tenant = config.require("tenant");
const env = parseEnvFromStack(tenant);
// Get AWS account ID
const callerIdentity = await aws.getCallerIdentity();
const awsAccountId = callerIdentity.accountId;
// ============================================================================
// Platform Infrastructure
// ============================================================================
// MeshPlatform:
// - Auto-imports core from SSM (use coreEnv config to override which env)
// - Creates Temporal, Zitadel, Monitoring (if configured)
// - Auto-exports to SSM: /mesh/{tenant}/{env}/platform
const meshPlatform = new mesh.layers.MeshPlatform("platform", {
tenant,
env,
// Core environment to import from (defaults to env)
// Set mesh:coreEnv in Pulumi config when core is deployed to a different stack
coreEnv: config.get("coreEnv"),
// Platform services - all disabled by default
// Enable via Pulumi config: mesh:temporal, mesh:zitadel, mesh:spicedb, mesh:monitoring
// infra-components >= 0.1.130 bundles the Temporal server source, so no
// serverSourcePath override is needed — the SDK resolves its bundled copy.
// Env-zone DNS (personal / secondary platform stacks): mesh:dns with a
// public.parentZone makes every platform hostname derive from
// {env}.{parentZone} instead of the shared core zone.
dns: config.getObject("dns") ?? false,
temporal: config.getObject("temporal") ?? false,
zitadel: config.getObject("zitadel") ?? false,
headscale: config.getObject("headscale") ?? false,
subnetRouter: config.getObject("subnetRouter") ?? false,
// Platform auth — org admin seeding (Zitadel users granted platform-wide
// Temporal system admin). Config: mesh:auth: { orgAdmins: ["zitadel-id", ...] }
// (SpiceDB authorization schemas are owned by apps/stacks, not the platform.)
auth: config.getObject("auth") ?? false,
monitoring: config.getObject("monitoring") ?? false,
// Mesh Hub (operations dashboard) — tenant-opt-in via mesh:hub config.
// Omit auth.clientId to have MeshHub auto-provision the Zitadel OIDC app
// (requires mesh:zitadel + Temporal auth + public DNS, all enabled here).
hub: config.getObject("hub") ?? false,
// Database provisioner - enabled when RDS is available in core
databaseProvisioner: config.getBoolean("databaseProvisioner") ?? true,
// Cluster owner: controls whether cluster-scoped resources are created
// Only ONE stack per cluster should be the owner (default: true)
// Set mesh:clusterOwner: false for secondary stacks sharing the same EKS cluster
clusterOwner: config.getBoolean("clusterOwner") ?? true,
// Shared tenants that use this platform (creates per-tenant infra)
// Config: mesh:tenants: { acme: {}, smallbank: { subdomain: sb } }
tenants: config.getObject("tenants"),
// Node pools for primary tenant workloads (e.g., Dagster jobs)
// Config: mesh:primaryTenantNodePools: { dagster-jobs: { instanceType: t3.large } }
primaryTenantNodePools: config.getObject("primaryTenantNodePools"),
// Package registry (CodeArtifact) for distributing @mesh-tech/* packages
// Config: mesh:packageRegistry: {} or mesh:packageRegistry: { readerRoleArns: [...] }
// NOTE: no monorepoRoot here — package publishing stays with the
// mesh-platform monorepo (scripts/publish-packages.sh). This stack only
// provisions the CodeArtifact registry.
packageRegistry: config.getObject("packageRegistry") ?? false,
// DevBox - remote development instances (optional)
// Config: mesh:devbox: { users: { <username>: { home: "/Users/<username>", ... } } }
devbox: config.getObject("devbox") ?? false,
});
// ============================================================================
// Stack Exports
// ============================================================================
// These are available via `pulumi stack output`
export const stack = pulumi.getStack();
export const tenantName = tenant;
export const environment = env;
export const accountId = awsAccountId;
// All platform infrastructure outputs (includes core infra, services, ssmPath)
export const platform = meshPlatform.outputs;
// Tenant environments (primary + shared) - deployer roles, ingress config
// Note: Also exported to SSM at /mesh/{tenant}/{env}/app-tenants
export const tenantEnvironments = {
primary: meshPlatform.tenantEnvironments.primaryTenant,
shared: meshPlatform.tenantEnvironments.sharedTenants,
ssmPath: meshPlatform.tenantEnvironments.ssmPath,
};