Skip to content

Commit a67bc28

Browse files
committed
infra: isolate dev lane layer stacks
Create dedicated dev layer stacks and make platform stack references configurable so dev can move onto the foundation/dev-staging manager without sharing production layer state. Made-with: Cursor
1 parent f4fe273 commit a67bc28

File tree

11 files changed

+74
-19
lines changed

11 files changed

+74
-19
lines changed

environments/main-dev.json

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"version": 1,
33
"name": "main-dev",
4-
"display_name": "Main Dev (pre-prod Swarm)",
4+
"display_name": "Main -> Dev (dedicated dev Swarm)",
55
"kind": "hosted",
66
"status": "active",
77
"repo_root": ".",
@@ -11,8 +11,8 @@
1111
"infra_root": "/Users/jacbaile/Workspace/MLE/RocketLeague/sprocket/infra"
1212
},
1313
"entrypoints": {
14-
"web": "https://dev.app.sprocket.gg",
15-
"api_graphql": "https://api.dev.app.sprocket.gg/graphql"
14+
"web": "https://dev.sprocket.mlesports.gg",
15+
"api_graphql": "https://api.dev.sprocket.mlesports.gg/graphql"
1616
},
1717
"topology": [
1818
"web",
@@ -47,7 +47,7 @@
4747
"safety": {
4848
"mutable_side_effects_require_operator_judgment": true,
4949
"notes": [
50-
"Hosted dev shares the pre-prod Swarm; treat mutations as non-production but still bounded.",
50+
"Hosted dev runs on the dedicated foundation/dev-staging manager; treat mutations as non-production but still bounded.",
5151
"GitHub Actions Tier 0 uses the development environment secret HARNESS_MAIN_DEV_ENV (multiline key=value file, same shape as scripts/harness/env/main-dev.env) written to a temp path and passed as the third argument to verify-lane.sh so CI can override URLs/markers without committing secrets. Operators still use the committed template for local runs."
5252
]
5353
}

infra/README.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -112,16 +112,16 @@ Canonical mapping (Pulumi platform stack names, subdomains, and public hostnames
112112
| `dev` | `dev` | `dev.sprocket.mlesports.gg`, `api.dev.sprocket.mlesports.gg`, … |
113113
| `staging` | `staging` | `staging.sprocket.mlesports.gg`, `api.staging.sprocket.mlesports.gg`, … |
114114

115-
Hostnames are derived in `infra/platform` from `platform:hostname` and `platform:subdomain` (`global/helpers/buildHost.ts` and `Platform.ts`). Staging uses `Pulumi.staging.yaml` on the same Swarm as dev with a different stack name so Swarm services do not collide.
115+
Hostnames are derived in `infra/platform` from `platform:hostname` and `platform:subdomain` (`global/helpers/buildHost.ts` and `Platform.ts`). The dev lane now uses dedicated `layer_1/dev`, `layer_2/dev`, and `platform/dev` stacks on the foundation-managed `dev-staging` node.
116116
## Lane ↔ Pulumi stack map (hosted)
117117

118118
| Lane (harness) | Environment contract | Platform stack (typical) | Notes |
119119
|----------------|----------------------|---------------------------|--------|
120120
| `main-prod` | `environments/main-prod.json` | `platform` / `prod` | Production Swarm + DO managed DB. |
121-
| `main-dev` | `environments/main-dev.json` | `platform` / `dev` | Pre-prod Swarm; **isolated** subdomain, DB target, Redis prefix, RabbitMQ vhost, and Swarm labels vs prod/staging. Template: `platform/Pulumi.dev.template.yaml`. Cross-ref: GitHub #672. |
121+
| `main-dev` | `environments/main-dev.json` | `platform` / `dev` | Dedicated dev Swarm with `layer_1/dev`, `layer_2/dev`, and `platform/dev`; isolated subdomain, DB target, Redis prefix, RabbitMQ vhost, and Swarm labels vs prod/staging. Template: `platform/Pulumi.dev.template.yaml`. Cross-ref: GitHub #672. |
122122
| `v15-beta` | `environments/v15-beta.json` | `platform` / stack per operator | Template: `platform/Pulumi.v15-beta.template.yaml`. |
123123

124-
`layer_1` and `layer_2` stack names are usually `layer_1` and `layer_2` on the same manager unless a separate substrate is provisioned; confirm with `pulumi stack ls` per project before apply.
124+
`layer_1` and `layer_2` stack names are environment-specific when a lane has its own substrate (for example `dev` on the dedicated `dev-staging` node) and remain `layer_1` / `layer_2` on the production manager; confirm with `pulumi stack ls` per project before apply.
125125

126126
## GitHub Actions
127127

infra/ci/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ Maintainers who add or rename Pulumi stacks. After `pulumi stack ls` in each pro
9797

9898
**Execution model:** `_reusable-pulumi-deploy.yml` now computes a scope-aware plan from `git_sha`, then runs the selected stack sequence in a **single runner**. App-only commits usually touch `platform` only; lower-layer infra changes pull in the affected layer plus `platform`; shared infra / workflow changes keep the full order. When an explicit `preview` row exists immediately before an `up` row for the same stack, the apply uses `--skip-preview` to avoid paying for the same preview twice.
9999

100-
For `dev_cd`, the reusable workflow also runs a **foundation prerequisite** against `infra/foundation` / `dev-staging` before the Swarm stacks. That foundation apply is gated so it only runs when the foundation stack has never been applied yet or when the target commit touches foundation-related inputs; otherwise the job records a skip and continues to the normal dev stack sequence.
100+
For `dev_cd`, the reusable workflow also runs a **foundation prerequisite** against `infra/foundation` / `dev-staging` before the Swarm stacks. Dev then applies the dedicated `layer_1/dev`, `layer_2/dev`, and `platform/dev` stacks against the dev manager host instead of sharing the production layer stacks. The foundation apply is gated so it only runs when the foundation stack has never been applied yet or when the target commit touches foundation-related inputs; otherwise the job records a skip and continues to the normal dev stack sequence.
101101

102102
**Reusable workflow inputs (for junior devs):**
103103

infra/ci/stack-map.yaml

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,12 @@ version: 1
77

88
environments:
99
dev:
10-
description: "Pre-prod Swarm on the main dev manager — matches .github/workflows/cd-deploy-dev.yml"
10+
description: "Dedicated dev Swarm on the foundation/dev-staging manager — matches .github/workflows/cd-deploy-dev.yml"
1111
deploy_order:
12-
# layer_* stack names match project folder names (same as prod). Platform stack defaults to dev;
13-
# CD can override via workflow input / PULUMI_DEV_PLATFORM_STACK (must not be prod).
14-
- { project: layer_1, stack: layer_1 }
15-
- { project: layer_2, stack: layer_2 }
12+
# Dev runs dedicated layer stacks on the dev manager. Platform stack defaults to dev;
13+
# CD can override the platform stack via workflow input / PULUMI_DEV_PLATFORM_STACK (must not be prod).
14+
- { project: layer_1, stack: dev }
15+
- { project: layer_2, stack: dev }
1616
- project: platform
1717
stack: dev
1818

infra/global/refs/LayerOne.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,4 @@ export enum LayerOneExports {
44
IngressNetwork = "IngressNetwork",
55
}
66

7-
export default new SprocketStackDefinition("layer_1", `${__dirname}/../../layer_1`);
7+
export default new SprocketStackDefinition("layer_1", `${__dirname}/../../layer_1`, "layer_1-stack");

infra/global/refs/LayerTwo.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,4 +25,4 @@ export enum LayerTwoExports {
2525
N8nNetwork = "N8nNetworkId"
2626
}
2727

28-
export default new SprocketStackDefinition("layer_2", `${__dirname}/../../layer_2`);
28+
export default new SprocketStackDefinition("layer_2", `${__dirname}/../../layer_2`, "layer_2-stack");

infra/global/refs/types.ts

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,28 @@
11
import * as pulumi from "@pulumi/pulumi";
22

33
export class SprocketStackDefinition {
4-
constructor(public readonly name: string,
5-
public readonly location: string) {
4+
constructor(
5+
public readonly name: string,
6+
public readonly location: string,
7+
private readonly stackConfigKey?: string,
8+
) {
69
}
710

811
_stack: pulumi.StackReference | undefined
12+
_stackReferenceName: string | undefined
913

1014
get stack() {
11-
if (!this._stack)
12-
this._stack = new pulumi.StackReference(`gankoji/${this.name}/${this.name}`)
15+
const configuredStackName = this.stackConfigKey
16+
? new pulumi.Config().get(this.stackConfigKey)?.trim()
17+
: undefined;
18+
const stackName = configuredStackName || this.name;
19+
const stackReferenceName = `gankoji/${this.name}/${stackName}`;
20+
21+
if (!this._stack || this._stackReferenceName !== stackReferenceName) {
22+
this._stack = new pulumi.StackReference(stackReferenceName);
23+
this._stackReferenceName = stackReferenceName;
24+
}
25+
1326
return this._stack
1427
}
1528
}

infra/layer_1/Pulumi.dev.yaml

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
config:
2+
layer_1:discord-fa-client-secret:
3+
secure: AAABAPlXRAG7Fju5B2ZlThOfDiA/Q2d6utE2LbmRO7GRrgQs6zt3galkykj9eTgC6a1dp2/WInIw9PN/+06jyg==
4+
layer_1:docker-access-token:
5+
secure: AAABAKJiFFU994YKGc2MXodmncCWXoDtKdbEcxCcVkxBouN43YXKDoRYO9FjmCqg8XHLTuxXbHDtRWtBlMB9XrtrFkhC2Pbp
6+
layer_1:docker-username: gankoji
7+
layer_1:hostname: dev.sprocket.mlesports.gg
8+
layer_1:image-namespace: sprocketbot
9+
layer_1:postgres-host: sprocketbot-postgres-d5033d2-do-user-24528890-0.j.db.ondigitalocean.com
10+
layer_1:postgres-password:
11+
secure: AAABAGL/iz/zELYpO9YXB3et6YlOiPpP7RDbJ3iW5LgHQcmbC9d69OTidghR0wtwFv/csG3MXgg=
12+
layer_1:postgres-port: "25060"
13+
layer_1:postgres-username: sprocketbot
14+
layer_1:vault-s3-access-key: DO801Q8P44QRYP9HEQVL
15+
layer_1:vault-s3-bucket: vault-secrets
16+
layer_1:vault-s3-endpoint: https://nyc3.digitaloceanspaces.com
17+
layer_1:vault-s3-secret-key:
18+
secure: AAABAKLovp2AYHUSmiVzKyos7mPFK9rRoVR/izXq3pTU1CsHZIav75tUBePuwiAX/nB42u0/YWf4IGwuzfPmVlLQKkrFcjoXPSim

infra/layer_2/Pulumi.dev.yaml

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
config:
2+
layer_2:docker-access-token:
3+
secure: AAABAF9TFDLGgwbqwEPc3azts0liRLSc8pToLr0PYwYLkqGQIwHVZ/1/p0hHLk3sGrbNZ1PYtDtwh29+LoI2PAePxdil9wrQ
4+
layer_2:docker-username: gankoji
5+
layer_2:hostname: dev.sprocket.mlesports.gg
6+
layer_2:image-namespace: sprocketbot
7+
layer_2:postgres-host: sprocketbot-postgres-d5033d2-do-user-24528890-0.j.db.ondigitalocean.com
8+
layer_2:postgres-password:
9+
secure: AAABABAZ/oN/74YPhYlCC/4xd/9oLLTrV6LXJx68skEY1Zat30A/6zjahiHAmiuck7hPmkAcHv0=
10+
layer_2:postgres-port: "25060"
11+
layer_2:postgres-username: doadmin
12+
layer_2:root-vault-token:
13+
secure: AAABAPHRxFJegysezP56OpCZ9gbYfvpemsXN0t8bZFPQ2BHBgk81/Og=
14+
layer_2:s3-access-key: DO004ZHPV38R8C9Q46XG
15+
layer_2:s3-endpoint: nyc3.digitaloceanspaces.com
16+
layer_2:s3-secret-key:
17+
secure: AAABAIeQCGx2unCboHD/foN8TOap8B7IlHk2/NE2rN0USfZxlRd6nWrn9vJoFMjwckqA198ubn/DhxmFJF3Uy/eTn7uWV5KuE3A/
18+
layer_2:smtp-password:
19+
secure: AAABAFjL2/m0iFUvA0S18ecmawH9yJC4vNXBQUzjnCWdc1mBAuejpijWloZyh01Aerd6hm4=
20+
layer_2:layer_1-stack: dev

infra/platform/Pulumi.dev.template.yaml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ config:
1818
platform:image-namespace: sprocketbot
1919
platform:legacy-image-namespace: asaxplayinghorse
2020
platform:image-tag: dev
21+
# platform:layer_1-stack: dev
22+
# platform:layer_2-stack: dev
2123

2224
# Postgres endpoint for the **dev** database cluster (not prod).
2325
# platform:postgres-username: <dev-db-user>

0 commit comments

Comments
 (0)