unoverse 0.1.177 → 0.1.179
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.
|
@@ -307,6 +307,33 @@ resource "aws_instance" "app" {
|
|
|
307
307
|
}
|
|
308
308
|
|
|
309
309
|
tags = { Name = "${var.name}-app" }
|
|
310
|
+
|
|
311
|
+
# THE IMAGE IS CHOSEN ONCE, AT BUILD, AND NEVER AGAIN BY ACCIDENT.
|
|
312
|
+
#
|
|
313
|
+
# `ami` is a force-replacement attribute: an instance's image cannot be swapped in place,
|
|
314
|
+
# so any change to it means DESTROY AND REBUILD, losing the 100 GB root volume and
|
|
315
|
+
# everything on it. The lookup above asks for `most_recent`, so the value feeding it
|
|
316
|
+
# changes whenever Canonical publishes, roughly monthly. Together those two facts arm a
|
|
317
|
+
# trap that fires on the first `unoverse deploy aws` after a publish, on a universe
|
|
318
|
+
# nobody has touched, with nothing in the repo to explain it.
|
|
319
|
+
#
|
|
320
|
+
# Observed 2026-08-26. BPP's box was built from ...-20260731; every deploy for four weeks
|
|
321
|
+
# got that same id back and planned nothing. Canonical published ...-20260826 at 07:52
|
|
322
|
+
# UTC, and the next deploy that morning planned to replace the server. Terraform was
|
|
323
|
+
# right and the config was wrong, and the only warning was one line in a plan that also
|
|
324
|
+
# said "Changing".
|
|
325
|
+
#
|
|
326
|
+
# An EXISTING universe now keeps the image it was built on; a NEW one still takes
|
|
327
|
+
# whatever is current when it is created, because the lookup is untouched and only drift
|
|
328
|
+
# is ignored. The trade is deliberate: nothing upgrades the OS for you. Patch in place
|
|
329
|
+
# with apt, and move to a newer image by rebuilding on purpose — a decision, rather than
|
|
330
|
+
# a side effect of deploying on the wrong day.
|
|
331
|
+
#
|
|
332
|
+
# DigitalOcean needs none of this: its droplet names a fixed slug (`ubuntu-22-04-x64`),
|
|
333
|
+
# a literal in the file that cannot drift.
|
|
334
|
+
lifecycle {
|
|
335
|
+
ignore_changes = [ami]
|
|
336
|
+
}
|
|
310
337
|
}
|
|
311
338
|
|
|
312
339
|
resource "aws_eip" "app" {
|
package/package.json
CHANGED
|
@@ -705,18 +705,20 @@ for (const orgDir of [DS, ...orgDirs]) {
|
|
|
705
705
|
if (hookYaml && !Array.isArray(readDef(mf).allowedHosts))
|
|
706
706
|
report("error", mf, `${custom} makes requests, so this manifest must declare "allowedHosts". Deny by default: no list, no network`);
|
|
707
707
|
|
|
708
|
-
// A NAME
|
|
709
|
-
//
|
|
710
|
-
//
|
|
711
|
-
//
|
|
712
|
-
//
|
|
708
|
+
// A credential is a NAME (owner ruling 2026-08-26): it references a value that
|
|
709
|
+
// exists in the universe or does not, and shipping NEVER blocks on it — the gap is
|
|
710
|
+
// a WARNING here and a loud runtime warning when the hook runs without it
|
|
711
|
+
// (resolveCredentials says so on every keyless run). A missing DEFINITION only
|
|
712
|
+
// means no package offers a pre-built entry form; the value can still be provided.
|
|
713
|
+
// This was an org-blocking error until it stopped a yasisland deploy over a form
|
|
714
|
+
// nobody needed that day.
|
|
713
715
|
if (credentialDefs.size)
|
|
714
716
|
for (const cname of Array.isArray(readDef(mf).credentials) ? readDef(mf).credentials : [])
|
|
715
717
|
if (!credentialDefs.has(String(cname)))
|
|
716
718
|
report(
|
|
717
|
-
"
|
|
719
|
+
"warn",
|
|
718
720
|
mf,
|
|
719
|
-
`credential "${cname}" has no definition in any installed node package, so
|
|
721
|
+
`credential "${cname}" has no definition in any installed node package, so no pre-built form exists to enter it — the hook will run without it until a value is provided. Installed definitions: ${[...credentialDefs].sort().join(", ")}`,
|
|
720
722
|
);
|
|
721
723
|
|
|
722
724
|
}
|