You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: jekyll/_posts/2025-11-29-vibe-coding-cloud-protocol.md
+94-28Lines changed: 94 additions & 28 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -33,7 +33,7 @@ This post is Part 3 of my journey to fix it.
33
33
***Part 2:**[Vibe Coding to Production: The Case for a Two-Stage Pipeline](/2025/10/13/two-stage-deployment-playbook/) (The Workflow)
34
34
***Part 3 (This Post):** The Execution.
35
35
36
-
Here is the **Ship.Fail Protocol**: The exact naming and tagging system I use to run my entire cloud empire of one.
36
+
Here is the **Ship.Fail Protocol**: the exact naming and tagging system I use to run my entire cloud empire of one.
37
37
38
38
---
39
39
@@ -45,10 +45,12 @@ It sounded smart on paper. In reality, it was a disaster.
45
45
46
46
As a solo founder, I don't have a Finance Department fighting with an Engineering Department. **I am both.** The entity paying the bill is the same entity writing the code.
47
47
48
-
So I collapsed the complexity. I realized that for us—the builders, the hackers, the solo founders—**The Two Trees are actually one.**
48
+
So I collapsed the complexity. I realized that for us—the builders, the hackers, the solo founders—**the two trees are actually one.**
49
49
50
50
We don't need a "Finance View" and an "Ops View." We need a **Unified Tree**. A single vertical line that connects the credit card to the code.
51
51
52
+
(In earlier posts, I called these top-level buckets **Umbrellas**. In this post, I’ll call them **Portfolios**. Same idea, slightly nicer word.)
53
+
52
54
---
53
55
54
56
## 2. The Blueprint: One Hierarchy to Rule Them All
|**3**|**Project**| A named workload like Zixia, Thoth, ReMic. In PreAngel it maps 1:1 to an Azure (subscription). In Ship.Fail it is implemented as a family of Resource Groups inside a shared lab Azure (subscription). | Azure subscription (PreAngel) / Resource Group family in a shared Azure subscription (Ship.Fail) |
127
-
|**4**|**Resource Group**| A logical container for a specific Stage (`dev`/`prod`) and Component (`web`/`api`) | Resource group |
128
-
|**5**|**Resource**| The actual thing: VM, DB, storage account, function, key vault, etc. | Resource |
131
+
| Level | My Name | What it means to ME | Azure Term (Reference Only) |
|**3**|**Project**| A named workload like Zixia, Thoth, ReMic. In PreAngel: maps 1:1 to an Azure (subscription). In Ship.Fail: implemented as a family of Resource Groups inside a shared lab Azure (subscription). | Azure subscription (PreAngel) / Resource Group family in a shared Azure subscription (Ship.Fail) |
136
+
|**4**|**Stage**|`dev` or `prod`. A concept encoded in names + tags, not a separate Azure object. | Environment concept (naming pattern / tag) |
137
+
|**5**|**Resource Group**| A logical component inside a Project + Stage, like `web`, `api`, `data`, or `tools`. | Resource group |
138
+
|**6**|**Resource**| The actual thing: VM, DB, storage account, function, key vault, etc. | Resource |
129
139
130
140
**The Golden Rule:** After this table, I almost never say "subscription" out loud. I speak in **Portfolios** and **Projects**, and only mention Azure terms in parentheses when I really need to.
131
141
142
+
### Stage Is Virtual (On Purpose)
143
+
144
+
Stage (`dev` / `prod`) is not a separate Azure object. You will never see a "Stage" blade in the portal.
145
+
146
+
Instead, Stage is:
147
+
148
+
* a field in the **name** of Resource Groups and Resources, and
149
+
* a **tag value** that tools and dashboards can filter on.
150
+
151
+
This is why the Unified Tree keeps Stage as its own level conceptually, even though the portal only shows it as part of names and tags.
152
+
132
153
### Same Tree, Two Implementations (Ship.Fail vs PreAngel)
133
154
134
155
Here’s the twist that makes everything click:
135
156
136
157
The **Unified Tree** is always the same in my head:
137
158
138
-
> Company → Portfolio → Project → Resource Group → Resource
159
+
> Company → Portfolio → Project → Resource Group (w/Stage) → Resource
139
160
140
161
But it is **implemented differently** for my two main portfolios:
141
162
142
163
***PreAngel (Production Portfolio)**
143
164
144
165
***Project = Azure (subscription).**
145
166
* Each serious product (like Zixia) gets its own Project at the subscription level.
146
-
* Inside that, I create Resource Groups for `dev` and `prod`stages + components (`web`, `api`, `data`, ...).
167
+
* Inside that, I create Resource Groups for `dev` and `prod`plus components (`web`, `api`, `data`, ...).
147
168
***Ship.Fail (Experiment Portfolio)**
148
169
149
170
* Everything is **leveled down by one notch** to keep life simple.
@@ -154,13 +175,13 @@ You can visualize it like this:
154
175
155
176
```text
156
177
PreAngel (Production)
157
-
Company → Portfolio → Project → Resource Group → Resource
178
+
Company → Portfolio → Project → Resource Group (w/Stage) → Resource
158
179
^
159
180
|
160
181
Azure (subscription)
161
182
162
183
Ship.Fail (Experiments)
163
-
Company → Portfolio → Project → Resource Group → Resource
184
+
Company → Portfolio → Project → Resource Group (w/Stage) → Resource
164
185
^ ^
165
186
| |
166
187
Azure (subscription) Project implemented as a Resource Group family
@@ -232,6 +253,8 @@ This is where the magic happens. The Resource Group name encodes the entire line
232
253
rg-<portfolio>-<project>-<stage>-<component?>
233
254
```
234
255
256
+
Examples:
257
+
235
258
*`rg-shipfail-remic-dev-web`
236
259
*`rg-preangel-zixia-prod-data`
237
260
@@ -263,15 +286,47 @@ Type-first gives me a nice property when I sort by name:
263
286
* all `db-*` resources group together,
264
287
* and my eyes can skim quickly.
265
288
289
+
### A Before → After Rename Example
290
+
291
+
Here’s how this looks in practice on a messy real-world example.
292
+
293
+
**Before:**
294
+
295
+
* Resource Group: `Default-Web-WestUS`
296
+
* Storage Account: `mystorage123`
297
+
298
+
Three months later, I have *no idea* what either of those are.
299
+
300
+
**After:**
301
+
302
+
```text
303
+
Resource Group: rg-shipfail-remic-dev-web
304
+
Storage Account: st-shipfail-remic-dev-web
305
+
Tags:
306
+
Portfolio = ShipFail
307
+
Project = ReMic
308
+
Stage = dev
309
+
Component = web
310
+
```
311
+
312
+
Now the same pair of resources tells me, at a glance:
313
+
314
+
* this is part of the **ReMic** Project,
315
+
* under the **Ship.Fail** portfolio,
316
+
* in the **dev** stage,
317
+
* in the **web** component.
318
+
319
+
I don’t need a wiki, a spreadsheet, or a memory palace. The name *is* the documentation.
320
+
266
321
---
267
322
268
-
## 5. Networking in This Model: Shared vs Dedicated
323
+
## 5. Do I Need Separate VNets for Every Project?
269
324
270
325
One important constraint from the cloud world: a virtual network (VNet) lives inside **one** Azure (subscription). It can be peered to others, but it cannot be “shared” across subscriptions without extra setup.
271
326
272
327
Instead of fighting this, I embraced it in the design:
273
328
274
-
***Ship.Fail:**
329
+
***Ship.Fail (experiments):**
275
330
276
331
* Uses **one shared lab subscription** for all experiments.
277
332
* Inside it, I create **one VNet per region**, like:
@@ -282,7 +337,8 @@ Instead of fighting this, I embraced it in the design:
282
337
*`snet-shipfail-dev-default`
283
338
*`snet-shipfail-prod-default`
284
339
* All Projects under Ship.Fail (Thoth, ReMic, etc.) reuse this same VNet and its subnets.
285
-
***PreAngel:**
340
+
341
+
***PreAngel (production):**
286
342
287
343
* Each production Project usually gets its **own** VNet inside its own subscription, like:
288
344
@@ -348,10 +404,12 @@ Company: PreAngel LLC
348
404
* ReMic now gets its own dedicated VNet, e.g. `vnet-preangel-remic-wus3`.
349
405
* I can migrate or redeploy workloads from the Ship.Fail lab into this new home.
350
406
407
+
In practice, “graduation” often means **redeploying infrastructure using IaC** (Terraform, Bicep, ARM) into the new subscription, rather than literally clicking "Move" on every resource. But the naming and tagging stay the same, so the promotion feels natural.
408
+
351
409
The mental model is the same. The only changes are:
352
410
353
411
*`Portfolio` value: from `ShipFail` → `PreAngel`.
354
-
*physical level where the Project lives: from Resource Group family inside a shared subscription → its own subscription.
412
+
*Physical level where the Project lives: from Resource Group family inside a shared subscription → its own subscription.
355
413
356
414
That’s how graduation works in this protocol.
357
415
@@ -406,40 +464,48 @@ Now, when I want to know *"How much am I spending on all my `dev` stages combine
406
464
407
465
---
408
466
409
-
## 8. Your Turn: The Cleanup Checklist
467
+
## 8. How Do I Actually Start Cleaning This Up Tomorrow?
410
468
411
469
Ready to turn your graveyard into a machine? Here is the exact checklist I used. Steal it.
412
470
413
471
1.**Define Your Portfolios.**
414
472
Commit to 2–3 high-level contexts. (For me: `PreAngel`, `ShipFail`, `ToBeMigrated`.)
473
+
415
474
2.**Decide Implementation Per Portfolio.**
416
475
417
476
* For your “serious” portfolio (like PreAngel), let each Project be its own Azure (subscription).
418
477
* For your “lab” portfolio (like Ship.Fail), pick one shared lab Azure (subscription) and implement Projects as families of Resource Groups inside it.
478
+
419
479
3.**Inventory Your Projects.**
420
480
List every Project you care about today and give it a clear name: `prj-<portfolio>-<project>`.
481
+
421
482
4.**Create the Containers.**
422
483
For each Project:
423
484
424
485
* In PreAngel-style portfolios: create or rename the Azure (subscription) accordingly, then create Resource Groups using the `rg-...` pattern.
425
486
* In Ship.Fail-style portfolios: create Resource Groups directly in the lab subscription using the `rg-...` pattern.
487
+
426
488
5.**The Great Migration.**
427
489
Move resources into their new homes. If something doesn’t obviously belong to a Project and Stage, that’s a red flag.
490
+
428
491
6.**The Purge.**
429
492
If you find a resource that doesn't fit into your new tree... **delete it.** If you can't name it, you don't need it.
493
+
430
494
7.**Tag Everything.**
431
495
No exceptions. Portfolio, Project, Stage, Component.
432
496
497
+
If you only have 30 minutes, pick **one** Project (for me, it was ReMic), apply the naming + tags + VNet model just to that, and stop. Even that small slice of clarity feels shockingly good.
498
+
433
499
---
434
500
435
-
## 9. Final Thought: Cognitive Freedom
501
+
## 9. Final Thought: Cognitive Freedom for a Company of One
436
502
437
503
This might look like a post about naming conventions. It’s not.
438
504
439
505
**It is a post about cognitive freedom.**
440
506
441
507
When your cloud environment matches your mental model, the friction disappears. You stop worrying about "phantom costs" and "zombie VMs." You stop hesitating before you deploy.
442
508
443
-
You reclaim that mental energy and pour it back into what matters: **Building.**
509
+
For a company of one, your cloud is more than infrastructure. It’s an exoskeleton for your brain. If it’s noisy and confusing, it drags you down. If it’s clean and aligned with how you think, it amplifies you.
444
510
445
511
So go ahead. Steal this protocol. Rename your world. Let your experiments live in Ship.Fail, let your winners graduate to PreAngel, and get back to shipping.
0 commit comments