@crossdelta/infrastructure 0.2.17 → 0.2.19

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,50 @@
1
+ /**
2
+ * Cert-Manager deployment for DOKS
3
+ *
4
+ * Deploys cert-manager via Helm chart for automatic TLS certificate management
5
+ * with Let's Encrypt.
6
+ */
7
+ import * as k8s from '@pulumi/kubernetes';
8
+ export interface CertManagerConfig {
9
+ /** Email for Let's Encrypt notifications */
10
+ email: string;
11
+ /** Use Let's Encrypt staging (for testing) or production */
12
+ staging?: boolean;
13
+ }
14
+ export interface CertManagerResult {
15
+ /** The Helm release */
16
+ release: k8s.helm.v3.Release;
17
+ /** The namespace where cert-manager is deployed */
18
+ namespace: string;
19
+ /** The ClusterIssuer for Let's Encrypt */
20
+ clusterIssuer: k8s.apiextensions.CustomResource;
21
+ /** ClusterIssuer name to use in Ingress annotations */
22
+ issuerName: string;
23
+ }
24
+ /**
25
+ * Deploy cert-manager to the cluster with Let's Encrypt ClusterIssuer.
26
+ *
27
+ * This creates:
28
+ * - cert-manager deployment with CRDs
29
+ * - ClusterIssuer for Let's Encrypt (production or staging)
30
+ *
31
+ * After deployment, add these annotations to your Ingress:
32
+ * ```yaml
33
+ * annotations:
34
+ * cert-manager.io/cluster-issuer: "letsencrypt-production"
35
+ * spec:
36
+ * tls:
37
+ * - hosts:
38
+ * - example.com
39
+ * secretName: example-com-tls
40
+ * ```
41
+ *
42
+ * @example
43
+ * ```typescript
44
+ * const certManager = deployCertManager(provider, {
45
+ * email: 'admin@example.com',
46
+ * staging: false, // Use production Let's Encrypt
47
+ * })
48
+ * ```
49
+ */
50
+ export declare function deployCertManager(provider: k8s.Provider, config: CertManagerConfig): CertManagerResult;
@@ -0,0 +1,61 @@
1
+ import * as digitalocean from '@pulumi/digitalocean';
2
+ import * as k8s from '@pulumi/kubernetes';
3
+ import * as pulumi from '@pulumi/pulumi';
4
+ import type { DOKSClusterConfig } from './types';
5
+ /**
6
+ * Result of creating a DOKS cluster.
7
+ */
8
+ export interface DOKSClusterResult {
9
+ /** The DigitalOcean Kubernetes cluster resource */
10
+ cluster: digitalocean.KubernetesCluster;
11
+ /** Kubernetes provider configured for this cluster */
12
+ provider: k8s.Provider;
13
+ /** Kubeconfig for the cluster (raw YAML) */
14
+ kubeconfig: pulumi.Output<string>;
15
+ /** Cluster API endpoint URL */
16
+ endpoint: pulumi.Output<string>;
17
+ }
18
+ /**
19
+ * Creates a DigitalOcean Kubernetes (DOKS) cluster with a configured K8s provider.
20
+ *
21
+ * This function:
22
+ * - Creates a DOKS cluster with the specified configuration
23
+ * - Automatically creates a @pulumi/kubernetes Provider connected to the cluster
24
+ * - Uses sensible defaults for maintenance, upgrades, and tagging
25
+ *
26
+ * @example
27
+ * ```typescript
28
+ * const { cluster, provider, kubeconfig } = createDOKSCluster({
29
+ * name: 'orderboss-cluster',
30
+ * region: 'fra1',
31
+ * vpcUuid: vpc.id,
32
+ * nodePool: {
33
+ * name: 'default',
34
+ * size: 's-2vcpu-4gb',
35
+ * nodeCount: 3,
36
+ * },
37
+ * })
38
+ *
39
+ * // Use the provider for K8s resources
40
+ * const namespace = new k8s.core.v1.Namespace('app', { ... }, { provider })
41
+ * ```
42
+ */
43
+ export declare function createDOKSCluster(config: DOKSClusterConfig): DOKSClusterResult;
44
+ /**
45
+ * Creates a Kubernetes provider from an existing kubeconfig string.
46
+ *
47
+ * Useful for:
48
+ * - Connecting to existing clusters
49
+ * - Using kubeconfig from CI/CD secrets
50
+ * - Testing against local/remote clusters
51
+ *
52
+ * @example
53
+ * ```typescript
54
+ * // From a secret
55
+ * const provider = createK8sProviderFromKubeconfig('my-cluster', kubeconfigSecret)
56
+ *
57
+ * // From environment
58
+ * const provider = createK8sProviderFromKubeconfig('local', process.env.KUBECONFIG_CONTENT!)
59
+ * ```
60
+ */
61
+ export declare function createK8sProviderFromKubeconfig(name: string, kubeconfig: pulumi.Input<string>): k8s.Provider;
@@ -0,0 +1,54 @@
1
+ /**
2
+ * DigitalOcean Kubernetes (DOKS) Runtime Module
3
+ *
4
+ * This module provides helpers for deploying workloads to DigitalOcean Kubernetes clusters.
5
+ *
6
+ * ## Features
7
+ *
8
+ * - VPC creation for private networking
9
+ * - DOKS cluster provisioning with auto-configured K8s provider
10
+ * - NATS + JetStream deployment via Helm
11
+ * - Generic K8s workload deployment (Deployment, Service, Ingress, Secrets, PVCs)
12
+ *
13
+ * ## Usage
14
+ *
15
+ * ```typescript
16
+ * import { createVPC, createDOKSCluster, deployNats, deployK8sService, createNamespace } from '@crossdelta/infrastructure'
17
+ *
18
+ * // 1. Create VPC
19
+ * const vpc = createVPC({ name: 'my-vpc', region: 'fra1' })
20
+ *
21
+ * // 2. Create DOKS cluster
22
+ * const { provider } = createDOKSCluster({
23
+ * name: 'my-cluster',
24
+ * vpcUuid: vpc.id,
25
+ * nodePool: { name: 'default', size: 's-2vcpu-4gb', nodeCount: 3 },
26
+ * })
27
+ *
28
+ * // 3. Create namespace
29
+ * const namespace = createNamespace(provider, 'my-app')
30
+ *
31
+ * // 4. Deploy NATS
32
+ * const nats = deployNats(provider, 'my-app', { jetstream: { enabled: true } })
33
+ *
34
+ * // 5. Deploy services
35
+ * deployK8sService(provider, 'my-app', {
36
+ * name: 'api',
37
+ * image: 'my-registry/api:latest',
38
+ * containerPort: 3000,
39
+ * ingress: { path: '/api' },
40
+ * })
41
+ * ```
42
+ *
43
+ * @module
44
+ */
45
+ export type { CertManagerConfig, CertManagerResult } from './cert-manager';
46
+ export { deployCertManager } from './cert-manager';
47
+ export type { DOKSClusterResult } from './cluster';
48
+ export { createDOKSCluster, createK8sProviderFromKubeconfig } from './cluster';
49
+ export type { NginxIngressConfig, NginxIngressResult } from './ingress';
50
+ export { deployNginxIngress } from './ingress';
51
+ export { buildNatsUrl, deployNats } from './nats';
52
+ export type { DeployK8sServicesOptions, DOKSClusterArgs, DOKSClusterConfig, K8sHealthCheck, K8sIngressConfig, K8sResourceConfig, K8sResources, K8sServiceConfig, K8sServiceDeploymentResult, K8sVolumeMount, NatsConfig, NatsDeploymentResult, Region, VPCConfig, VpcArgs, } from './types';
53
+ export { createVPC } from './vpc';
54
+ export { buildInternalUrl, createImagePullSecret, createNamespace, deployK8sService, deployK8sServices, } from './workloads';
@@ -0,0 +1,57 @@
1
+ /**
2
+ * Ingress Controller deployment for DOKS
3
+ *
4
+ * Deploys nginx-ingress-controller via Helm chart.
5
+ * Creates a single LoadBalancer that routes traffic to all services.
6
+ */
7
+ import * as k8s from '@pulumi/kubernetes';
8
+ import * as pulumi from '@pulumi/pulumi';
9
+ export interface NginxIngressConfig {
10
+ /** Number of replicas for the ingress controller (default: 1) */
11
+ replicas?: number;
12
+ /** Resource requests/limits */
13
+ resources?: {
14
+ requests?: {
15
+ cpu?: string;
16
+ memory?: string;
17
+ };
18
+ limits?: {
19
+ cpu?: string;
20
+ memory?: string;
21
+ };
22
+ };
23
+ /** Enable proxy protocol for preserving client IPs (default: true for DO) */
24
+ useProxyProtocol?: boolean;
25
+ }
26
+ export interface NginxIngressResult {
27
+ /** The Helm release */
28
+ release: k8s.helm.v3.Release;
29
+ /** The LoadBalancer service name */
30
+ serviceName: string;
31
+ /** The namespace where ingress controller is deployed */
32
+ namespace: string;
33
+ /** The LoadBalancer external IP (available after deployment) */
34
+ loadBalancerIp: pulumi.Output<string>;
35
+ }
36
+ /**
37
+ * Deploy nginx-ingress-controller to the cluster.
38
+ *
39
+ * This creates:
40
+ * - Ingress controller deployment
41
+ * - LoadBalancer service (~$12/month on DigitalOcean)
42
+ * - Required RBAC resources
43
+ *
44
+ * After deployment, Ingress resources will automatically get an external IP.
45
+ *
46
+ * @example
47
+ * ```typescript
48
+ * const ingress = deployNginxIngress(provider, {
49
+ * replicas: 1,
50
+ * resources: {
51
+ * requests: { cpu: '100m', memory: '128Mi' },
52
+ * limits: { cpu: '200m', memory: '256Mi' },
53
+ * },
54
+ * })
55
+ * ```
56
+ */
57
+ export declare function deployNginxIngress(provider: k8s.Provider, config?: NginxIngressConfig): NginxIngressResult;
@@ -0,0 +1,51 @@
1
+ import * as k8s from '@pulumi/kubernetes';
2
+ import * as pulumi from '@pulumi/pulumi';
3
+ import type { NatsConfig, NatsDeploymentResult } from './types';
4
+ /**
5
+ * Deploys NATS with JetStream to a Kubernetes cluster using the official Helm chart.
6
+ *
7
+ * Features:
8
+ * - NATS cluster with configurable replicas (default: 3 for HA)
9
+ * - JetStream enabled with persistent storage via PVC
10
+ * - Optional authentication
11
+ * - DigitalOcean block storage integration
12
+ *
13
+ * @example
14
+ * ```typescript
15
+ * const nats = deployNats(provider, 'orderboss', {
16
+ * replicas: 3,
17
+ * jetstream: {
18
+ * enabled: true,
19
+ * storageSize: '20Gi',
20
+ * },
21
+ * auth: {
22
+ * enabled: true,
23
+ * user: natsUser,
24
+ * password: natsPassword,
25
+ * },
26
+ * })
27
+ *
28
+ * // Connect from other services:
29
+ * // nats://nats.orderboss.svc.cluster.local:4222
30
+ * ```
31
+ */
32
+ export declare function deployNats(provider: k8s.Provider, namespace: string, config?: NatsConfig): NatsDeploymentResult;
33
+ /**
34
+ * Creates a NATS connection URL with optional authentication.
35
+ *
36
+ * Note: Username and password are URL-encoded to handle special characters.
37
+ *
38
+ * @example
39
+ * ```typescript
40
+ * // Without auth
41
+ * const url = buildNatsUrl('orderboss') // nats://nats.orderboss.svc.cluster.local:4222
42
+ *
43
+ * // With auth
44
+ * const url = buildNatsUrl('orderboss', { user: 'myuser', password: 'secret' })
45
+ * // nats://myuser:secret@nats.orderboss.svc.cluster.local:4222
46
+ * ```
47
+ */
48
+ export declare function buildNatsUrl(namespace: string, auth?: {
49
+ user: pulumi.Input<string>;
50
+ password: pulumi.Input<string>;
51
+ }): pulumi.Output<string>;
@@ -0,0 +1,313 @@
1
+ import type * as digitalocean from '@pulumi/digitalocean';
2
+ import type * as pulumi from '@pulumi/pulumi';
3
+ /** DigitalOcean Kubernetes Cluster Args (from @pulumi/digitalocean) */
4
+ export type DOKSClusterArgs = digitalocean.KubernetesClusterArgs;
5
+ /** DigitalOcean VPC Args (from @pulumi/digitalocean) */
6
+ export type VpcArgs = digitalocean.VpcArgs;
7
+ /** DigitalOcean Region enum */
8
+ export type Region = digitalocean.Region;
9
+ /**
10
+ * Simplified DOKS cluster configuration.
11
+ *
12
+ * Wraps `digitalocean.KubernetesClusterArgs` with sensible defaults
13
+ * and a more ergonomic interface for common use cases.
14
+ *
15
+ * @example
16
+ * ```typescript
17
+ * const cluster = createDOKSCluster({
18
+ * name: 'orderboss-cluster',
19
+ * region: 'fra1',
20
+ * vpcUuid: vpc.id,
21
+ * nodePool: {
22
+ * name: 'default',
23
+ * size: 's-2vcpu-4gb',
24
+ * nodeCount: 3,
25
+ * },
26
+ * })
27
+ * ```
28
+ */
29
+ export interface DOKSClusterConfig {
30
+ /** Cluster name (will be suffixed with stack name) */
31
+ name: string;
32
+ /** DigitalOcean region (defaults to 'fra1') */
33
+ region?: digitalocean.Region | string;
34
+ /** Kubernetes version - use `doctl kubernetes options versions` to list available */
35
+ version?: string;
36
+ /** Node pool configuration */
37
+ nodePool: {
38
+ /** Node pool name */
39
+ name: string;
40
+ /** Droplet size slug (e.g., 's-2vcpu-4gb') */
41
+ size: string;
42
+ /** Number of nodes (ignored if autoScale is set) */
43
+ nodeCount?: number;
44
+ /** Auto-scale configuration */
45
+ autoScale?: {
46
+ minNodes: number;
47
+ maxNodes: number;
48
+ };
49
+ /** Labels for nodes */
50
+ labels?: Record<string, string>;
51
+ };
52
+ /** VPC UUID for private networking */
53
+ vpcUuid?: pulumi.Input<string>;
54
+ /** Enable HA control plane (defaults to false) */
55
+ ha?: boolean;
56
+ /** Enable auto-upgrade (defaults to true) */
57
+ autoUpgrade?: boolean;
58
+ /** Enable surge upgrades (defaults to true) */
59
+ surgeUpgrade?: boolean;
60
+ /** Tags for the cluster */
61
+ tags?: string[];
62
+ }
63
+ /**
64
+ * Simplified VPC configuration with stack-aware naming.
65
+ */
66
+ export interface VPCConfig {
67
+ /** VPC name (will be suffixed with stack name) */
68
+ name: string;
69
+ /** DigitalOcean region (defaults to 'fra1') */
70
+ region?: digitalocean.Region | string;
71
+ /** Optional description */
72
+ description?: string;
73
+ /** IP range for the VPC (e.g., '10.10.10.0/24') */
74
+ ipRange?: string;
75
+ }
76
+ /**
77
+ * Resource limits and requests for Kubernetes containers.
78
+ */
79
+ export interface K8sResources {
80
+ /** CPU (e.g., '100m', '0.5', '2') */
81
+ cpu?: string;
82
+ /** Memory (e.g., '128Mi', '1Gi') */
83
+ memory?: string;
84
+ }
85
+ /**
86
+ * Resource configuration for Kubernetes pods.
87
+ */
88
+ export interface K8sResourceConfig {
89
+ /** Resource requests (guaranteed resources) */
90
+ requests?: K8sResources;
91
+ /** Resource limits (maximum resources) */
92
+ limits?: K8sResources;
93
+ }
94
+ /**
95
+ * Health check configuration for Kubernetes probes.
96
+ */
97
+ export interface K8sHealthCheck {
98
+ /** HTTP path for health check (e.g., '/health') */
99
+ httpPath?: string;
100
+ /** Port for health check (defaults to containerPort) */
101
+ port?: number;
102
+ /** Initial delay before starting probes in seconds (default: 10) */
103
+ initialDelaySeconds?: number;
104
+ /** Period between probes in seconds (default: 10) */
105
+ periodSeconds?: number;
106
+ /** Number of consecutive failures before unhealthy (default: 3) */
107
+ failureThreshold?: number;
108
+ /** Number of consecutive successes to be healthy (default: 1) */
109
+ successThreshold?: number;
110
+ /** Probe timeout in seconds (default: 5) */
111
+ timeoutSeconds?: number;
112
+ }
113
+ /**
114
+ * Ingress configuration for public services.
115
+ */
116
+ export interface K8sIngressConfig {
117
+ /** Path prefix for routing (e.g., '/', '/api') */
118
+ path: string;
119
+ /** Path type: 'Prefix' (default) or 'Exact' */
120
+ pathType?: 'Prefix' | 'Exact';
121
+ /** Custom annotations for the ingress */
122
+ annotations?: Record<string, string>;
123
+ /** Hostname for the ingress (required for TLS) */
124
+ host?: string;
125
+ /** Additional hostnames (e.g., www subdomain) */
126
+ additionalHosts?: string[];
127
+ /** TLS configuration */
128
+ tls?: {
129
+ /** Enable TLS (requires cert-manager ClusterIssuer) */
130
+ enabled: boolean;
131
+ /** ClusterIssuer name (default: 'letsencrypt-production') */
132
+ issuerName?: string;
133
+ /** Secret name for the TLS certificate (auto-generated if not provided) */
134
+ secretName?: string;
135
+ };
136
+ }
137
+ /**
138
+ * Volume mount configuration for persistent storage.
139
+ */
140
+ export interface K8sVolumeMount {
141
+ /** Name of the volume/PVC */
142
+ name: string;
143
+ /** Mount path inside the container */
144
+ mountPath: string;
145
+ /** Size of the volume (e.g., '10Gi') */
146
+ size?: string;
147
+ /** Storage class (defaults to 'do-block-storage') */
148
+ storageClass?: string;
149
+ /** Access mode (defaults to 'ReadWriteOnce') */
150
+ accessMode?: 'ReadWriteOnce' | 'ReadOnlyMany' | 'ReadWriteMany';
151
+ /** Whether the volume is read-only */
152
+ readOnly?: boolean;
153
+ }
154
+ /**
155
+ * Configuration for a Kubernetes service deployment.
156
+ *
157
+ * This is the main interface for defining services in `infra/services/*.ts`.
158
+ * Each service config is translated into Kubernetes Deployment, Service,
159
+ * and optionally Ingress resources.
160
+ *
161
+ * @example
162
+ * ```typescript
163
+ * // Internal service (not publicly accessible)
164
+ * const config: K8sServiceConfig = {
165
+ * name: 'orders',
166
+ * image: 'ghcr.io/orderboss/platform/orders:latest',
167
+ * containerPort: 4001,
168
+ * replicas: 2,
169
+ * env: {
170
+ * PUBLIC_SUPABASE_URL: supabaseUrl,
171
+ * },
172
+ * secrets: {
173
+ * SUPABASE_SERVICE_ROLE_KEY: supabaseServiceRoleKey,
174
+ * },
175
+ * }
176
+ *
177
+ * // Public service with ingress
178
+ * const config: K8sServiceConfig = {
179
+ * name: 'storefront',
180
+ * image: 'ghcr.io/orderboss/platform/storefront:latest',
181
+ * containerPort: 3000,
182
+ * ingress: { path: '/' },
183
+ * healthCheck: { httpPath: '/health' },
184
+ * }
185
+ * ```
186
+ */
187
+ export interface K8sServiceConfig {
188
+ /** Unique name of the service (used for deployment, service, and labels) */
189
+ name: string;
190
+ /** Container image (e.g., 'ghcr.io/orderboss/platform/storefront:latest') */
191
+ image: string;
192
+ /** Port the container listens on */
193
+ containerPort: number;
194
+ /** Number of replicas (defaults to 1) */
195
+ replicas?: number;
196
+ /** Environment variables (plain values) */
197
+ env?: Record<string, pulumi.Input<string>>;
198
+ /** Secret environment variables (stored in K8s Secret) */
199
+ secrets?: Record<string, pulumi.Input<string>>;
200
+ /** Ingress configuration (set to enable public access) */
201
+ ingress?: K8sIngressConfig;
202
+ /** Health check configuration for liveness/readiness probes */
203
+ healthCheck?: K8sHealthCheck;
204
+ /** Resource requests and limits */
205
+ resources?: K8sResourceConfig;
206
+ /** Volume mounts for persistent storage */
207
+ volumes?: K8sVolumeMount[];
208
+ /** Command to run (overrides container entrypoint) */
209
+ command?: string[];
210
+ /** Arguments to pass to the command */
211
+ args?: string[];
212
+ /** Additional labels to apply to all resources */
213
+ labels?: Record<string, string>;
214
+ /** Additional annotations to apply to pods */
215
+ annotations?: Record<string, string>;
216
+ /** Service type: 'ClusterIP' (default), 'NodePort', or 'LoadBalancer' */
217
+ serviceType?: 'ClusterIP' | 'NodePort' | 'LoadBalancer';
218
+ /** Skip deployment (useful for temporarily disabling a service) */
219
+ skip?: boolean;
220
+ /** Image pull policy (defaults to 'Always' for :latest, 'IfNotPresent' otherwise) */
221
+ imagePullPolicy?: 'Always' | 'Never' | 'IfNotPresent';
222
+ /** Additional ports to expose (for services with multiple ports) */
223
+ additionalPorts?: Array<{
224
+ name: string;
225
+ port: number;
226
+ targetPort?: number;
227
+ protocol?: 'TCP' | 'UDP';
228
+ }>;
229
+ /** Name of the imagePullSecret to use for private registries */
230
+ imagePullSecretName?: string;
231
+ }
232
+ /**
233
+ * Options for deploying multiple K8s services.
234
+ */
235
+ export interface DeployK8sServicesOptions {
236
+ /** Image pull secret name (applied to all services) */
237
+ imagePullSecretName?: string;
238
+ }
239
+ /**
240
+ * Configuration for NATS deployment with JetStream via Helm.
241
+ *
242
+ * @example
243
+ * ```typescript
244
+ * const nats = deployNats(provider, 'orderboss', {
245
+ * replicas: 3,
246
+ * jetstream: {
247
+ * enabled: true,
248
+ * storageSize: '20Gi',
249
+ * },
250
+ * auth: {
251
+ * enabled: true,
252
+ * user: natsUser,
253
+ * password: natsPassword,
254
+ * },
255
+ * })
256
+ * ```
257
+ */
258
+ export interface NatsConfig {
259
+ /** Number of NATS server replicas (defaults to 3 for HA) */
260
+ replicas?: number;
261
+ /** JetStream storage configuration */
262
+ jetstream?: {
263
+ /** Enable JetStream (defaults to true) */
264
+ enabled?: boolean;
265
+ /** Storage size for file storage (e.g., '20Gi') */
266
+ storageSize?: string;
267
+ /** Storage class (defaults to 'do-block-storage') */
268
+ storageClass?: string;
269
+ /** Memory storage size (e.g., '1Gi') */
270
+ memoryStorageSize?: string;
271
+ };
272
+ /** Authentication configuration */
273
+ auth?: {
274
+ /** Enable authentication (defaults to false) */
275
+ enabled?: boolean;
276
+ /** Username for client connections */
277
+ user?: pulumi.Input<string>;
278
+ /** Password for client connections */
279
+ password?: pulumi.Input<string>;
280
+ };
281
+ /** Resource configuration */
282
+ resources?: K8sResourceConfig;
283
+ }
284
+ /**
285
+ * Deployment result for a K8s service.
286
+ */
287
+ export interface K8sServiceDeploymentResult {
288
+ /** The Kubernetes Deployment resource */
289
+ deployment: unknown;
290
+ /** The Kubernetes Service resource */
291
+ service: unknown;
292
+ /** The Kubernetes Ingress resource (if public) */
293
+ ingress?: unknown;
294
+ /** The Kubernetes Secret resource (if secrets are defined) */
295
+ secret?: unknown;
296
+ /** PVCs for persistent storage */
297
+ pvcs?: unknown[];
298
+ /** Internal service URL (e.g., 'http://orders.orderboss.svc.cluster.local:4001') */
299
+ internalUrl: pulumi.Output<string>;
300
+ /** Service DNS name within cluster */
301
+ serviceDns: string;
302
+ }
303
+ /**
304
+ * Result of deploying NATS.
305
+ */
306
+ export interface NatsDeploymentResult {
307
+ /** Helm release */
308
+ release: unknown;
309
+ /** Internal NATS URL for service-to-service communication */
310
+ internalUrl: string;
311
+ /** Service DNS name */
312
+ serviceDns: string;
313
+ }
@@ -0,0 +1,18 @@
1
+ import * as digitalocean from '@pulumi/digitalocean';
2
+ import type { VPCConfig } from './types';
3
+ /**
4
+ * Creates a DigitalOcean VPC for private networking.
5
+ *
6
+ * All DOKS nodes and services will use this VPC for internal communication.
7
+ * The VPC name is automatically suffixed with the current stack name.
8
+ *
9
+ * @example
10
+ * ```typescript
11
+ * const vpc = createVPC({
12
+ * name: 'orderboss-vpc',
13
+ * region: 'fra1',
14
+ * description: 'VPC for orderboss platform',
15
+ * })
16
+ * ```
17
+ */
18
+ export declare function createVPC(config: VPCConfig): digitalocean.Vpc;
@@ -0,0 +1,79 @@
1
+ import * as k8s from '@pulumi/kubernetes';
2
+ import * as pulumi from '@pulumi/pulumi';
3
+ import type { DeployK8sServicesOptions, K8sServiceConfig, K8sServiceDeploymentResult } from './types';
4
+ /**
5
+ * Creates an ImagePullSecret for private container registries (e.g., GHCR, DockerHub).
6
+ *
7
+ * @example
8
+ * ```typescript
9
+ * const secret = createImagePullSecret(provider, 'orderboss', 'ghcr-secret', {
10
+ * registry: 'ghcr.io',
11
+ * username: 'my-org',
12
+ * password: ghcrToken,
13
+ * })
14
+ * ```
15
+ */
16
+ export declare function createImagePullSecret(provider: k8s.Provider, namespace: string, name: string, config: {
17
+ registry: string;
18
+ username: pulumi.Input<string>;
19
+ password: pulumi.Input<string>;
20
+ }): k8s.core.v1.Secret;
21
+ /**
22
+ * Deploys a service to Kubernetes.
23
+ *
24
+ * Creates:
25
+ * - Deployment with configurable replicas, resources, and health checks
26
+ * - Service (ClusterIP by default) for internal access
27
+ * - Secret (if `secrets` are defined)
28
+ * - PVCs (if `volumes` are defined)
29
+ * - Ingress (if `ingress` is defined) - Note: requires ingress controller
30
+ *
31
+ * @example
32
+ * ```typescript
33
+ * const result = deployK8sService(provider, 'orderboss', {
34
+ * name: 'orders',
35
+ * image: 'ghcr.io/orderboss/platform/orders:latest',
36
+ * containerPort: 4001,
37
+ * replicas: 2,
38
+ * env: {
39
+ * PUBLIC_SUPABASE_URL: supabaseUrl,
40
+ * },
41
+ * secrets: {
42
+ * SUPABASE_SERVICE_ROLE_KEY: supabaseServiceRoleKey,
43
+ * },
44
+ * healthCheck: {
45
+ * httpPath: '/health',
46
+ * },
47
+ * })
48
+ *
49
+ * // Access the service internally:
50
+ * // http://orders.orderboss.svc.cluster.local:4001
51
+ * ```
52
+ */
53
+ export declare function deployK8sService(provider: k8s.Provider, namespace: string, config: K8sServiceConfig): K8sServiceDeploymentResult;
54
+ /**
55
+ * Deploys multiple services to Kubernetes.
56
+ *
57
+ * @example
58
+ * ```typescript
59
+ * const results = deployK8sServices(provider, 'orderboss', [
60
+ * ordersConfig,
61
+ * storefrontConfig,
62
+ * apiGatewayConfig,
63
+ * ], { imagePullSecretName: 'ghcr-secret' })
64
+ * ```
65
+ */
66
+ export declare function deployK8sServices(provider: k8s.Provider, namespace: string, configs: K8sServiceConfig[], options?: DeployK8sServicesOptions): Map<string, K8sServiceDeploymentResult>;
67
+ /**
68
+ * Creates a Kubernetes namespace.
69
+ *
70
+ * @example
71
+ * ```typescript
72
+ * const ns = createNamespace(provider, 'orderboss')
73
+ * ```
74
+ */
75
+ export declare function createNamespace(provider: k8s.Provider, name: string, labels?: Record<string, string>): k8s.core.v1.Namespace;
76
+ /**
77
+ * Builds an internal service URL for cluster-internal communication.
78
+ */
79
+ export declare function buildInternalUrl(serviceName: string, namespace: string, port: number): string;