@caelo-cms/provisioning 0.2.47 → 0.2.49
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.
- package/package.json +2 -2
- package/stacks/gcp/Pulumi.yaml +16 -0
- package/stacks/gcp/README.md +6 -0
- package/stacks/gcp/index.ts +26 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@caelo-cms/provisioning",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.49",
|
|
4
4
|
"private": false,
|
|
5
5
|
"license": "MPL-2.0",
|
|
6
6
|
"description": "Pulumi-driven provisioning for Caelo CMS — `bunx @caelo-cms/provisioning --provider <self-hosted|gcp|aws|azure>` brings up a TLS-served install with Postgres + storage + secrets manager + the admin + the API gateway.",
|
|
@@ -38,7 +38,7 @@
|
|
|
38
38
|
"prepublishOnly": "tsc -b --force"
|
|
39
39
|
},
|
|
40
40
|
"dependencies": {
|
|
41
|
-
"@caelo-cms/shared": "^0.2.
|
|
41
|
+
"@caelo-cms/shared": "^0.2.49",
|
|
42
42
|
"@clack/prompts": "1.3.0",
|
|
43
43
|
"@pulumi/aws": "^7",
|
|
44
44
|
"@pulumi/awsx": "^3",
|
package/stacks/gcp/Pulumi.yaml
CHANGED
|
@@ -54,6 +54,22 @@ config:
|
|
|
54
54
|
type: string
|
|
55
55
|
default: "0"
|
|
56
56
|
description: Admin Cloud Run min instances. 0 = scale to zero. 1 = no cold start (+~$15/mo).
|
|
57
|
+
caelo-gcp:adminMaxInstances:
|
|
58
|
+
type: string
|
|
59
|
+
default: "5"
|
|
60
|
+
description: |
|
|
61
|
+
Admin Cloud Run max instances. Default 5 caps the connection-pool
|
|
62
|
+
footprint at ~100 Postgres conns (Bun SQL pool max=10, two pools per
|
|
63
|
+
admin instance). Bump alongside maxConnections + cloudSqlTier when
|
|
64
|
+
sizing for heavy editorial traffic.
|
|
65
|
+
caelo-gcp:maxConnections:
|
|
66
|
+
type: string
|
|
67
|
+
default: "100"
|
|
68
|
+
description: |
|
|
69
|
+
Postgres max_connections database flag. Default 100 matches the safe
|
|
70
|
+
ceiling for adminMaxInstances=5 + light gateway traffic. Cloud SQL's
|
|
71
|
+
db-f1-micro defaults to 25 — too low for any sustained admin load.
|
|
72
|
+
Tune up alongside cloudSqlTier when scaling out.
|
|
57
73
|
caelo-gcp:gatewayMinInstances:
|
|
58
74
|
type: string
|
|
59
75
|
default: "0"
|
package/stacks/gcp/README.md
CHANGED
|
@@ -26,6 +26,12 @@ pulumi config set caelo-gcp:ownerEmail me@example.com
|
|
|
26
26
|
pulumi config set caelo-gcp:project my-gcp-project
|
|
27
27
|
pulumi config set caelo-gcp:region us-central1
|
|
28
28
|
|
|
29
|
+
# Optional: scale up beyond the safe-by-default ceiling. The defaults
|
|
30
|
+
# size for a small editorial install (admin maxScale 5 × Bun SQL pool
|
|
31
|
+
# max 10 × 2 pools = 100 conns, matching Postgres max_connections=100).
|
|
32
|
+
# pulumi config set caelo-gcp:adminMaxInstances 10
|
|
33
|
+
# pulumi config set caelo-gcp:maxConnections 200
|
|
34
|
+
|
|
29
35
|
# Build + push images. Operator does this once + on every release.
|
|
30
36
|
gcloud auth configure-docker us-central1-docker.pkg.dev
|
|
31
37
|
gcloud builds submit ... --tag us-central1-docker.pkg.dev/$PROJECT/caelo/admin:latest
|
package/stacks/gcp/index.ts
CHANGED
|
@@ -42,7 +42,26 @@ const cloudSqlEdition = cfg.get("cloudSqlEdition") ?? "ENTERPRISE";
|
|
|
42
42
|
// wants to `caelo-cms destroy` shouldn't hit a wall).
|
|
43
43
|
const deletionProtection = cfg.getBoolean("deletionProtection") ?? false;
|
|
44
44
|
const adminMinInstances = Number.parseInt(cfg.get("adminMinInstances") ?? "0", 10);
|
|
45
|
+
// adminMaxInstances default is intentionally low. Each admin process holds
|
|
46
|
+
// TWO Bun SQL pools (admin_role on cms_admin + admin_role on cms_public),
|
|
47
|
+
// each with default pool-max=10 → up to ~20 connections per instance under
|
|
48
|
+
// sustained load. With db-f1-micro's tunable max_connections, even 5 admin
|
|
49
|
+
// instances saturate the pool (5 × 20 = 100 = our default ceiling below).
|
|
50
|
+
// Operators on larger SQL tiers should bump maxConnections AND
|
|
51
|
+
// adminMaxInstances together.
|
|
52
|
+
//
|
|
53
|
+
// Why 5, not 10 (Cloud Run's default)? An incident on production showed
|
|
54
|
+
// admin scaling to 10 under bursty editor traffic, demanding 200 slots
|
|
55
|
+
// against the original 25-slot Postgres default — connection exhaustion
|
|
56
|
+
// took the admin offline. v0.2.49 bakes the post-incident shape so fresh
|
|
57
|
+
// installs don't trip the same wall.
|
|
58
|
+
const adminMaxInstances = Number.parseInt(cfg.get("adminMaxInstances") ?? "5", 10);
|
|
45
59
|
const gatewayMinInstances = Number.parseInt(cfg.get("gatewayMinInstances") ?? "0", 10);
|
|
60
|
+
// Postgres connection slot ceiling. Cloud SQL's db-f1-micro defaults to 25,
|
|
61
|
+
// which 1 admin pool exhausts under load (Bun SQL pool-max=10, two pools per
|
|
62
|
+
// admin instance, plus gateway + migrations + backup-agent overhead). 100 is
|
|
63
|
+
// the safe floor for a small editorial install — tune up alongside SQL tier.
|
|
64
|
+
const maxConnections = Number.parseInt(cfg.get("maxConnections") ?? "100", 10);
|
|
46
65
|
const wafAdaptiveProtection = cfg.getBoolean("wafAdaptiveProtection") ?? false;
|
|
47
66
|
const backupRetentionDays = Number.parseInt(cfg.get("backupRetentionDays") ?? "7", 10);
|
|
48
67
|
// IAP allowlist: comma-list of "user:<email>" or "group:<group@domain>".
|
|
@@ -188,6 +207,12 @@ const sqlInstance = new gcp.sql.DatabaseInstance(
|
|
|
188
207
|
diskSize: 20,
|
|
189
208
|
diskType: "PD_SSD",
|
|
190
209
|
diskAutoresize: true,
|
|
210
|
+
// db-f1-micro defaults max_connections=25, which a single
|
|
211
|
+
// admin Cloud Run instance can exhaust under load (Bun SQL
|
|
212
|
+
// pool-max=10, two pools per admin process). Override at
|
|
213
|
+
// instance level so the cap matches the Cloud Run scale-out
|
|
214
|
+
// headroom defined by adminMaxInstances + gatewayMaxInstances.
|
|
215
|
+
databaseFlags: [{ name: "max_connections", value: maxConnections.toString() }],
|
|
191
216
|
backupConfiguration: {
|
|
192
217
|
enabled: true,
|
|
193
218
|
pointInTimeRecoveryEnabled: cloudSqlHa,
|
|
@@ -490,7 +515,7 @@ function cloudRunService(args: CloudRunArgs): gcp.cloudrunv2.Service {
|
|
|
490
515
|
const adminSvc = cloudRunService({
|
|
491
516
|
serviceName: "admin",
|
|
492
517
|
minInstances: adminMinInstances,
|
|
493
|
-
maxInstances:
|
|
518
|
+
maxInstances: adminMaxInstances,
|
|
494
519
|
memory: "1Gi",
|
|
495
520
|
// Admin's second pool: admin_role on cms_public for cross-DB reads
|
|
496
521
|
// + DDL + migrations. NOT public_role (write-limited).
|