@intentius/chant-lexicon-terraform 0.124.52 → 0.124.54
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/README.md +7 -6
- package/dist/__fixtures__/pr-loop/estate.component.d.ts +7 -0
- package/dist/__fixtures__/pr-loop/estate.component.d.ts.map +1 -0
- package/dist/__fixtures__/pr-loop/estate.component.js +7 -0
- package/dist/__fixtures__/report/generate.d.ts +26 -0
- package/dist/__fixtures__/report/generate.d.ts.map +1 -0
- package/dist/__fixtures__/report/generate.js +58 -0
- package/dist/applied-state.d.ts +27 -0
- package/dist/applied-state.d.ts.map +1 -0
- package/dist/applied-state.js +44 -0
- package/dist/backend-config.d.ts +53 -0
- package/dist/backend-config.d.ts.map +1 -0
- package/dist/backend-config.js +136 -0
- package/dist/behaviour/kinds.d.ts.map +1 -1
- package/dist/behaviour/kinds.js +4 -0
- package/dist/behaviour/predict.d.ts.map +1 -1
- package/dist/behaviour/predict.js +6 -2
- package/dist/behaviour/reference-catalog.d.ts +16 -5
- package/dist/behaviour/reference-catalog.d.ts.map +1 -1
- package/dist/behaviour/reference-catalog.js +16 -5
- package/dist/behaviour/request.d.ts.map +1 -1
- package/dist/behaviour/request.js +3 -2
- package/dist/changed-roots.d.ts +6 -4
- package/dist/changed-roots.d.ts.map +1 -1
- package/dist/changed-roots.js +14 -18
- package/dist/commands.d.ts.map +1 -1
- package/dist/commands.js +4 -3
- package/dist/components/capability-plugin.d.ts +65 -3
- package/dist/components/capability-plugin.d.ts.map +1 -1
- package/dist/components/capability-plugin.js +197 -13
- package/dist/components/compose-group.d.ts +145 -0
- package/dist/components/compose-group.d.ts.map +1 -0
- package/dist/components/compose-group.js +407 -0
- package/dist/components/placeholder-preview.d.ts +78 -0
- package/dist/components/placeholder-preview.d.ts.map +1 -0
- package/dist/components/placeholder-preview.js +254 -0
- package/dist/compose/apply-events.d.ts +46 -0
- package/dist/compose/apply-events.d.ts.map +1 -0
- package/dist/compose/apply-events.js +77 -0
- package/dist/compose/estate.d.ts +194 -0
- package/dist/compose/estate.d.ts.map +1 -0
- package/dist/compose/estate.js +363 -0
- package/dist/compose/hcl.d.ts +99 -0
- package/dist/compose/hcl.d.ts.map +1 -0
- package/dist/compose/hcl.js +302 -0
- package/dist/compose/module-address.d.ts +24 -0
- package/dist/compose/module-address.d.ts.map +1 -0
- package/dist/compose/module-address.js +43 -0
- package/dist/compose/root.d.ts +127 -0
- package/dist/compose/root.d.ts.map +1 -0
- package/dist/compose/root.js +586 -0
- package/dist/compose/run.d.ts +183 -0
- package/dist/compose/run.d.ts.map +1 -0
- package/dist/compose/run.js +447 -0
- package/dist/compose/slice.d.ts +102 -0
- package/dist/compose/slice.d.ts.map +1 -0
- package/dist/compose/slice.js +249 -0
- package/dist/compose/state-address.d.ts +28 -0
- package/dist/compose/state-address.d.ts.map +1 -0
- package/dist/compose/state-address.js +154 -0
- package/dist/compose/state-merge.d.ts +52 -0
- package/dist/compose/state-merge.d.ts.map +1 -0
- package/dist/compose/state-merge.js +135 -0
- package/dist/compose.d.ts +179 -0
- package/dist/compose.d.ts.map +1 -0
- package/dist/compose.js +482 -0
- package/dist/composites/terraform-apply-op.d.ts.map +1 -1
- package/dist/composites/terraform-apply-op.js +7 -3
- package/dist/config.d.ts +59 -13
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +43 -9
- package/dist/describe-resources.d.ts +74 -12
- package/dist/describe-resources.d.ts.map +1 -1
- package/dist/describe-resources.js +374 -66
- package/dist/drift-read.d.ts +33 -0
- package/dist/drift-read.d.ts.map +1 -0
- package/dist/drift-read.js +243 -0
- package/dist/drift-record.d.ts +147 -0
- package/dist/drift-record.d.ts.map +1 -0
- package/dist/drift-record.js +383 -0
- package/dist/hcl/edges.d.ts.map +1 -1
- package/dist/hcl/edges.js +24 -1
- package/dist/hcl/files.d.ts +61 -0
- package/dist/hcl/files.d.ts.map +1 -0
- package/dist/hcl/files.js +221 -0
- package/dist/hcl/instances.d.ts +82 -0
- package/dist/hcl/instances.d.ts.map +1 -0
- package/dist/hcl/instances.js +390 -0
- package/dist/hcl/parse.d.ts +81 -9
- package/dist/hcl/parse.d.ts.map +1 -1
- package/dist/hcl/parse.js +114 -16
- package/dist/hcl/roots.d.ts.map +1 -1
- package/dist/hcl/roots.js +5 -0
- package/dist/hcl/suppressions.d.ts.map +1 -1
- package/dist/hcl/suppressions.js +8 -2
- package/dist/index.d.ts +11 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +21 -2
- package/dist/integrity.json +3 -3
- package/dist/live-plan-reasons.d.ts +21 -0
- package/dist/live-plan-reasons.d.ts.map +1 -0
- package/dist/live-plan-reasons.js +47 -0
- package/dist/lsp/option-keys.d.ts.map +1 -1
- package/dist/lsp/option-keys.js +2 -0
- package/dist/manifest.json +1 -1
- package/dist/op/activities/index.d.ts +6 -2
- package/dist/op/activities/index.d.ts.map +1 -1
- package/dist/op/activities/index.js +5 -1
- package/dist/op/activities/live-detect.d.ts +4 -3
- package/dist/op/activities/live-detect.d.ts.map +1 -1
- package/dist/op/activities/live-detect.js +57 -32
- package/dist/op/activities/pin-rollout.d.ts +2 -0
- package/dist/op/activities/pin-rollout.d.ts.map +1 -1
- package/dist/op/activities/pin-rollout.js +1 -0
- package/dist/op/activities/terraform.d.ts +153 -5
- package/dist/op/activities/terraform.d.ts.map +1 -1
- package/dist/op/activities/terraform.js +205 -20
- package/dist/op/activity-contracts.d.ts +27 -0
- package/dist/op/activity-contracts.d.ts.map +1 -1
- package/dist/op/activity-contracts.js +19 -1
- package/dist/op/builders.d.ts +7 -1
- package/dist/op/builders.d.ts.map +1 -1
- package/dist/op/builders.js +9 -0
- package/dist/pin/edit.d.ts.map +1 -1
- package/dist/pin/edit.js +35 -0
- package/dist/pin/rollout.d.ts +2 -0
- package/dist/pin/rollout.d.ts.map +1 -1
- package/dist/pin/rollout.js +14 -11
- package/dist/plan-shape.d.ts +30 -0
- package/dist/plan-shape.d.ts.map +1 -0
- package/dist/plan-shape.js +125 -0
- package/dist/plugin.d.ts.map +1 -1
- package/dist/plugin.js +32 -18
- package/dist/report.d.ts +15 -6
- package/dist/report.d.ts.map +1 -1
- package/dist/report.js +28 -55
- package/dist/skills/chant-terraform.md +1 -1
- package/dist/state/azure-blob.d.ts +68 -0
- package/dist/state/azure-blob.d.ts.map +1 -0
- package/dist/state/azure-blob.js +201 -0
- package/dist/state/backend.d.ts +158 -0
- package/dist/state/backend.d.ts.map +1 -0
- package/dist/state/backend.js +406 -0
- package/dist/state/exec.d.ts +39 -0
- package/dist/state/exec.d.ts.map +1 -0
- package/dist/state/exec.js +80 -0
- package/dist/state/gcs.d.ts +62 -0
- package/dist/state/gcs.d.ts.map +1 -0
- package/dist/state/gcs.js +224 -0
- package/dist/state/index.d.ts +15 -0
- package/dist/state/index.d.ts.map +1 -0
- package/dist/state/index.js +14 -0
- package/dist/state/locks.d.ts +105 -0
- package/dist/state/locks.d.ts.map +1 -0
- package/dist/state/locks.js +130 -0
- package/dist/state/object-store.d.ts +37 -0
- package/dist/state/object-store.d.ts.map +1 -0
- package/dist/state/object-store.js +20 -0
- package/dist/state/root-states.d.ts +131 -0
- package/dist/state/root-states.d.ts.map +1 -0
- package/dist/state/root-states.js +241 -0
- package/dist/state/s3.d.ts +68 -0
- package/dist/state/s3.d.ts.map +1 -0
- package/dist/state/s3.js +170 -0
- package/dist/state/store.d.ts +51 -0
- package/dist/state/store.d.ts.map +1 -0
- package/dist/state/store.js +185 -0
- package/dist/terragrunt/affected.d.ts.map +1 -1
- package/dist/terragrunt/affected.js +2 -1
- package/package.json +7 -3
- package/src/__fixtures__/ACCEPTANCE.md +69 -7
- package/src/__fixtures__/compose/apply-failed-in-app.jsonl +12 -0
- package/src/__fixtures__/compose/state-app.json +66 -0
- package/src/__fixtures__/compose/state-edge.json +40 -0
- package/src/__fixtures__/compose/state-net.json +58 -0
- package/src/__fixtures__/compose/three-app.plan.json +184 -0
- package/src/__fixtures__/compose/three-composed.plan.json +509 -0
- package/src/__fixtures__/compose/three-edge.plan.json +144 -0
- package/src/__fixtures__/compose/three-net.plan.json +174 -0
- package/src/__fixtures__/compose/unknown-composed.plan.json +228 -0
- package/src/__fixtures__/compose/working-after-apply.json +145 -0
- package/src/__fixtures__/config-blocks/app/main.tf +61 -0
- package/src/__fixtures__/config-blocks/app/modules/network/main.tf +4 -0
- package/src/__fixtures__/config-blocks/app-json/main.tf.json +39 -0
- package/src/__fixtures__/config-files/shadow/main.tf +3 -0
- package/src/__fixtures__/config-files/shadow/main.tofu +3 -0
- package/src/__fixtures__/config-files/shadow/other.tf +3 -0
- package/src/__fixtures__/config-files/tf/main.tf +11 -0
- package/src/__fixtures__/config-files/tf-json/main.tf.json +18 -0
- package/src/__fixtures__/config-files/tofu/main.tofu +11 -0
- package/src/__fixtures__/config-files/tofu-json/main.tofu.json +18 -0
- package/src/__fixtures__/config-files/tofu-only/main.tofu +3 -0
- package/src/__fixtures__/drift-record/README.md +11 -0
- package/src/__fixtures__/drift-record/live-plan-sections.json +27 -0
- package/src/__fixtures__/instance-forms/app/main.tf +110 -0
- package/src/__fixtures__/instance-forms/app/modules/svc/main.tf +3 -0
- package/src/__fixtures__/instance-vars/app/main.tf +52 -0
- package/src/__fixtures__/instance-vars/app/modules/app/main.tf +12 -0
- package/src/__fixtures__/instance-vars/app/modules/edge/main.tf +3 -0
- package/src/__fixtures__/instance-vars/app/terraform.tfvars +1 -0
- package/src/__fixtures__/live-module-keyed/live-graph.json +259 -0
- package/src/__fixtures__/live-module-keyed/live-plan.json +87 -0
- package/src/__fixtures__/live-module-keyed/root/estate.chdf.hcl +1 -0
- package/src/__fixtures__/live-module-keyed/root/main.tf +21 -0
- package/src/__fixtures__/live-module-keyed/root/modules/app/main.tf +17 -0
- package/src/__fixtures__/live-module-keyed/root/modules/edge/main.tf +7 -0
- package/src/__fixtures__/live-module-keyed/root/versions.tf +30 -0
- package/src/__fixtures__/live-module-keyed/show-state.json +146 -0
- package/src/__fixtures__/pr-loop/README.md +50 -0
- package/src/__fixtures__/pr-loop/chant.config.json +13 -0
- package/src/__fixtures__/pr-loop/estate.component.ts +10 -0
- package/src/__fixtures__/pr-loop/roots/a/main.tf +11 -0
- package/src/__fixtures__/pr-loop/roots/app/main.tf +19 -0
- package/src/__fixtures__/pr-loop/roots/b/main.tf +7 -0
- package/src/__fixtures__/pr-loop/roots/dns/main.tf +3 -0
- package/src/__fixtures__/pr-loop/roots/net/main.tf +7 -0
- package/src/__fixtures__/report/applied.show.json +51 -0
- package/src/__fixtures__/report/generate.ts +63 -0
- package/src/__fixtures__/report/plan.show.json +200 -0
- package/src/__fixtures__/report/tf-apply/change-set.json +170 -0
- package/src/__fixtures__/report/tf-apply/report.json +338 -0
- package/src/__fixtures__/report/tf-plan/change-set.json +170 -0
- package/src/__fixtures__/report/tf-plan/report.json +320 -0
- package/src/__fixtures__/three-cloud-azure.graph.json +290 -0
- package/src/applied-state.ts +52 -0
- package/src/backend-config.test.ts +105 -0
- package/src/backend-config.ts +133 -0
- package/src/behaviour/kinds.ts +4 -0
- package/src/behaviour/predict.ts +5 -2
- package/src/behaviour/reference-catalog.plugin.test.ts +65 -0
- package/src/behaviour/reference-catalog.ts +16 -5
- package/src/behaviour/request.ts +3 -2
- package/src/change-set-instances.test.ts +98 -0
- package/src/changed-roots.ts +14 -16
- package/src/commands.ts +4 -3
- package/src/components/capability-plugin.test.ts +172 -5
- package/src/components/capability-plugin.ts +212 -11
- package/src/components/change-set-graph.e2e.test.ts +11 -5
- package/src/components/compose-group.test.ts +486 -0
- package/src/components/compose-group.ts +489 -0
- package/src/components/demo-composed-roots.e2e.test.ts +440 -0
- package/src/components/member-outputs.test.ts +76 -0
- package/src/components/placeholder-preview.test.ts +147 -0
- package/src/components/placeholder-preview.ts +257 -0
- package/src/components/pr-loop-compose.tofu.e2e.test.ts +363 -0
- package/src/components/pr-loop.tofu.test.ts +112 -56
- package/src/compose/apply-events.test.ts +62 -0
- package/src/compose/apply-events.ts +100 -0
- package/src/compose/estate.choudoufu.e2e.test.ts +112 -0
- package/src/compose/estate.test.ts +421 -0
- package/src/compose/estate.ts +443 -0
- package/src/compose/hcl.ts +311 -0
- package/src/compose/module-address.ts +49 -0
- package/src/compose/root.test.ts +416 -0
- package/src/compose/root.ts +592 -0
- package/src/compose/run.test.ts +440 -0
- package/src/compose/run.tofu.test.ts +176 -0
- package/src/compose/run.ts +527 -0
- package/src/compose/slice.test.ts +184 -0
- package/src/compose/slice.ts +290 -0
- package/src/compose/state-address.ts +157 -0
- package/src/compose/state-merge.test.ts +131 -0
- package/src/compose/state-merge.ts +148 -0
- package/src/compose.test.ts +248 -0
- package/src/compose.ts +627 -0
- package/src/composites/terraform-apply-op.test.ts +9 -0
- package/src/composites/terraform-apply-op.ts +7 -3
- package/src/config-file-listers.test.ts +265 -0
- package/src/config.ts +44 -9
- package/src/describe-resources.engine-facts.test.ts +412 -0
- package/src/describe-resources.live-module-keyed.test.ts +290 -0
- package/src/describe-resources.ts +416 -70
- package/src/drift-read.ts +284 -0
- package/src/drift-record.test.ts +223 -0
- package/src/drift-record.ts +455 -0
- package/src/hcl/config-blocks.test.ts +174 -0
- package/src/hcl/edges.ts +21 -1
- package/src/hcl/files.ts +234 -0
- package/src/hcl/instance-forms.test.ts +94 -0
- package/src/hcl/instances.test.ts +137 -0
- package/src/hcl/instances.ts +422 -0
- package/src/hcl/parse.test.ts +139 -1
- package/src/hcl/parse.ts +149 -16
- package/src/hcl/roots.ts +6 -0
- package/src/hcl/suppressions.ts +8 -2
- package/src/index.ts +76 -0
- package/src/live-plan-reasons.ts +54 -0
- package/src/lsp/completions.test.ts +1 -1
- package/src/lsp/option-keys.ts +2 -0
- package/src/op/activities/choudoufu-plan-set-op.test.ts +111 -0
- package/src/op/activities/index.ts +9 -0
- package/src/op/activities/live-detect.ts +55 -26
- package/src/op/activities/pin-rollout.ts +3 -0
- package/src/op/activities/registry.test.ts +2 -1
- package/src/op/activities/terraform.test.ts +55 -0
- package/src/op/activities/terraform.ts +266 -22
- package/src/op/activity-contracts.test.ts +1 -0
- package/src/op/activity-contracts.ts +24 -1
- package/src/op/builders.ts +14 -0
- package/src/pin/bundle.test.ts +2 -0
- package/src/pin/edit.ts +30 -0
- package/src/pin/rollout.ts +16 -11
- package/src/plan-shape.test.ts +148 -0
- package/src/plan-shape.ts +128 -0
- package/src/plugin.ts +33 -19
- package/src/report.test.ts +82 -1
- package/src/report.ts +31 -54
- package/src/signal-only-root.test.ts +72 -0
- package/src/skills/chant-terraform.md +1 -1
- package/src/state/azure-blob.ts +223 -0
- package/src/state/backend-verdict.test.ts +187 -0
- package/src/state/backend.test.ts +127 -0
- package/src/state/backend.ts +488 -0
- package/src/state/exec.ts +111 -0
- package/src/state/gcs.ts +254 -0
- package/src/state/index.ts +15 -0
- package/src/state/locks.test.ts +84 -0
- package/src/state/locks.ts +201 -0
- package/src/state/object-store.ts +35 -0
- package/src/state/root-states-floci.e2e.test.ts +66 -0
- package/src/state/root-states.test.ts +462 -0
- package/src/state/root-states.ts +309 -0
- package/src/state/s3.ts +193 -0
- package/src/state/store.ts +225 -0
- package/src/terragrunt/affected.ts +2 -1
- package/src/workspace-kinds.test.ts +4 -17
- package/workspace-kinds.json +1 -24
- package/dist/workspace-member.d.ts +0 -30
- package/dist/workspace-member.d.ts.map +0 -1
- package/dist/workspace-member.js +0 -91
- package/schemas/pulumi.schema.json +0 -34
- package/src/testdata/pulumi-member/Pulumi.yaml +0 -2
- package/src/testdata/pulumi-member/stack-export.json +0 -53
- package/src/testdata/pulumi-unexported/Pulumi.yaml +0 -2
- package/src/workspace-member.test.ts +0 -89
- package/src/workspace-member.ts +0 -126
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import type { LockableState } from "./backend.js";
|
|
2
|
+
import { type StoreFetch } from "./object-store.js";
|
|
3
|
+
/** The lock a state's backend holds: the ID `force-unlock` takes, and the lock info the binary (or a run) wrote. */
|
|
4
|
+
export interface LockHolder {
|
|
5
|
+
id: string;
|
|
6
|
+
/** The lock info as written, JSON. */
|
|
7
|
+
info: string;
|
|
8
|
+
}
|
|
9
|
+
/** A state where it is, for what locks it and keeps beside it. */
|
|
10
|
+
export interface StateStore {
|
|
11
|
+
readonly backend: LockableState["backend"];
|
|
12
|
+
/** Where the state is. */
|
|
13
|
+
readonly location: string;
|
|
14
|
+
/** Where its lock is: the lock object, or the blob whose lease is the lock. */
|
|
15
|
+
readonly lockLocation: string;
|
|
16
|
+
/** The lock the backend holds now, or undefined. */
|
|
17
|
+
heldLock(): Promise<LockHolder | undefined>;
|
|
18
|
+
/** Take the state's lock with `info`, the way the backend takes it: false when it is held. */
|
|
19
|
+
lock(info: string): Promise<boolean>;
|
|
20
|
+
/** Release the lock `lock` took, or the one `adopt` took over. */
|
|
21
|
+
unlock(): Promise<void>;
|
|
22
|
+
/**
|
|
23
|
+
* Write a new state under the lock, for a backend whose lock keeps the
|
|
24
|
+
* binary from writing (azurerm's lease); undefined for a backend the
|
|
25
|
+
* binary writes with `-lock=false` while the run holds the lock.
|
|
26
|
+
*/
|
|
27
|
+
write?: (body: string) => Promise<void>;
|
|
28
|
+
/**
|
|
29
|
+
* The object beside the state whose key is the state's with `suffix` after
|
|
30
|
+
* it, in the same bucket, container or directory, under the state's own
|
|
31
|
+
* access controls: read (undefined when there is none), written, removed.
|
|
32
|
+
*/
|
|
33
|
+
readBeside(suffix: string): Promise<string | undefined>;
|
|
34
|
+
writeBeside(suffix: string, body: string): Promise<void>;
|
|
35
|
+
removeBeside(suffix: string): Promise<void>;
|
|
36
|
+
/** Where the object beside the state with `suffix` is, for messages. */
|
|
37
|
+
besideLocation(suffix: string): string;
|
|
38
|
+
/**
|
|
39
|
+
* Take over a lock this store finds held, which an earlier run of the same
|
|
40
|
+
* operation left held on purpose: `unlock` then releases it. A lease
|
|
41
|
+
* (azurerm) is taken over by its ID, the others need nothing.
|
|
42
|
+
*/
|
|
43
|
+
adopt(held: LockHolder): void;
|
|
44
|
+
}
|
|
45
|
+
/** The ID in a lock info's JSON, or "" when it names none. */
|
|
46
|
+
export declare function lockId(text: string): string;
|
|
47
|
+
/** The metadata an azurerm backend keeps a lock's info in, base64 JSON, on the leased blob. */
|
|
48
|
+
export declare const LOCK_METADATA = "terraformlockid";
|
|
49
|
+
/** The store a state is in, opened with the credentials stateObject chose. `dir` is the root a local path is relative to. */
|
|
50
|
+
export declare function stateStore(o: LockableState, dir: string, fetchFn?: StoreFetch): StateStore;
|
|
51
|
+
//# sourceMappingURL=store.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../../src/state/store.ts"],"names":[],"mappings":"AAyBA,OAAO,KAAK,EAAoC,aAAa,EAAW,MAAM,WAAW,CAAC;AAE1F,OAAO,EAAc,KAAK,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAG7D,oHAAoH;AACpH,MAAM,WAAW,UAAU;IACzB,EAAE,EAAE,MAAM,CAAC;IACX,sCAAsC;IACtC,IAAI,EAAE,MAAM,CAAC;CACd;AAED,kEAAkE;AAClE,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,OAAO,EAAE,aAAa,CAAC,SAAS,CAAC,CAAC;IAC3C,0BAA0B;IAC1B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,+EAA+E;IAC/E,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,oDAAoD;IACpD,QAAQ,IAAI,OAAO,CAAC,UAAU,GAAG,SAAS,CAAC,CAAC;IAC5C,8FAA8F;IAC9F,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IACrC,kEAAkE;IAClE,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACxB;;;;OAIG;IACH,KAAK,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACxC;;;;OAIG;IACH,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAAC;IACxD,WAAW,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACzD,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC5C,wEAAwE;IACxE,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC;IACvC;;;;OAIG;IACH,KAAK,CAAC,IAAI,EAAE,UAAU,GAAG,IAAI,CAAC;CAC/B;AAED,8DAA8D;AAC9D,wBAAgB,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAO3C;AAiDD,+FAA+F;AAC/F,eAAO,MAAM,aAAa,oBAAoB,CAAC;AAsF/C,6HAA6H;AAC7H,wBAAgB,UAAU,CAAC,CAAC,EAAE,aAAa,EAAE,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,UAAU,GAAG,UAAU,CAK1F"}
|
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A state where it is, opened for its lock and for what a run keeps beside
|
|
3
|
+
* it. Each backend locks its own way:
|
|
4
|
+
*
|
|
5
|
+
* s3 the lock file `use_lockfile` takes, `<key>.tflock`, written only
|
|
6
|
+
* when absent
|
|
7
|
+
* gcs the lock object `<prefix>/<workspace>.tflock`, written only when
|
|
8
|
+
* absent; the ID `force-unlock` takes is its generation
|
|
9
|
+
* azurerm a lease on the state blob, with the lock info base64 in its
|
|
10
|
+
* `terraformlockid` metadata; the binary cannot write the blob
|
|
11
|
+
* while chant holds the lease, so the store writes it
|
|
12
|
+
* local a lock file `<path>.tflock` beside the state, created only when
|
|
13
|
+
* absent. It keeps another chant run out; the binary's own local
|
|
14
|
+
* lock is a file lock it takes per command, so the run writes
|
|
15
|
+
* with `-lock=false` while it holds this one. A bare
|
|
16
|
+
* `terraform apply` on the same checkout at the same time is not
|
|
17
|
+
* kept out. Ruled on #4481 (ruling 4, 2026-10-25): chant's own
|
|
18
|
+
* lock file, no Terraform lock-info file, local backends allowed.
|
|
19
|
+
*
|
|
20
|
+
* Lifted from terragucci's `backend.ts` (c493e0e): `StateStore`, `s3Store`,
|
|
21
|
+
* `gcsStore` and `azureStore`, plus a local store and `removeBeside`.
|
|
22
|
+
*/
|
|
23
|
+
import { existsSync, mkdirSync, readFileSync, rmSync, writeFileSync } from "node:fs";
|
|
24
|
+
import { dirname, isAbsolute, join } from "node:path";
|
|
25
|
+
import { AzureBlobClient } from "./azure-blob.js";
|
|
26
|
+
import { GcsClient } from "./gcs.js";
|
|
27
|
+
import { StoreError } from "./object-store.js";
|
|
28
|
+
import { S3Client } from "./s3.js";
|
|
29
|
+
/** The ID in a lock info's JSON, or "" when it names none. */
|
|
30
|
+
export function lockId(text) {
|
|
31
|
+
try {
|
|
32
|
+
const v = JSON.parse(text);
|
|
33
|
+
return typeof v.ID === "string" ? v.ID : "";
|
|
34
|
+
}
|
|
35
|
+
catch {
|
|
36
|
+
return "";
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
const JSON_TYPE = "application/json";
|
|
40
|
+
/** The S3 state, locked by the lock file `use_lockfile` takes. */
|
|
41
|
+
function s3Store(o, fetchFn) {
|
|
42
|
+
const client = new S3Client(o.target, fetchFn);
|
|
43
|
+
const lockKey = `${o.key}.tflock`;
|
|
44
|
+
return {
|
|
45
|
+
backend: "s3",
|
|
46
|
+
location: `s3://${o.bucket}/${o.key}`,
|
|
47
|
+
lockLocation: `s3://${o.bucket}/${lockKey}`,
|
|
48
|
+
heldLock: async () => {
|
|
49
|
+
const text = await client.get(lockKey);
|
|
50
|
+
return text === undefined ? undefined : { id: lockId(text), info: text };
|
|
51
|
+
},
|
|
52
|
+
lock: (info) => client.putIfAbsent(lockKey, info, JSON_TYPE),
|
|
53
|
+
unlock: () => client.remove(lockKey),
|
|
54
|
+
readBeside: (suffix) => client.get(`${o.key}${suffix}`),
|
|
55
|
+
writeBeside: (suffix, body) => client.put(`${o.key}${suffix}`, body, JSON_TYPE),
|
|
56
|
+
removeBeside: (suffix) => client.remove(`${o.key}${suffix}`),
|
|
57
|
+
besideLocation: (suffix) => `s3://${o.bucket}/${o.key}${suffix}`,
|
|
58
|
+
adopt: () => { },
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
/** The GCS state, locked by `<prefix>/<workspace>.tflock`, whose generation is the lock's ID. */
|
|
62
|
+
function gcsStore(o, fetchFn) {
|
|
63
|
+
const client = new GcsClient(o.target, fetchFn);
|
|
64
|
+
return {
|
|
65
|
+
backend: "gcs",
|
|
66
|
+
location: `gs://${o.bucket}/${o.key}`,
|
|
67
|
+
lockLocation: `gs://${o.bucket}/${o.lock}`,
|
|
68
|
+
heldLock: async () => {
|
|
69
|
+
const head = await client.head(o.lock);
|
|
70
|
+
const info = head.exists ? await client.get(o.lock) : undefined;
|
|
71
|
+
if (!head.exists || info === undefined)
|
|
72
|
+
return undefined;
|
|
73
|
+
return { id: head.generation ?? lockId(info), info };
|
|
74
|
+
},
|
|
75
|
+
lock: (info) => client.putIfAbsent(o.lock, info, JSON_TYPE),
|
|
76
|
+
unlock: () => client.remove(o.lock),
|
|
77
|
+
readBeside: (suffix) => client.get(`${o.key}${suffix}`),
|
|
78
|
+
writeBeside: (suffix, body) => client.put(`${o.key}${suffix}`, body, JSON_TYPE),
|
|
79
|
+
removeBeside: (suffix) => client.remove(`${o.key}${suffix}`),
|
|
80
|
+
besideLocation: (suffix) => `gs://${o.bucket}/${o.key}${suffix}`,
|
|
81
|
+
adopt: () => { },
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
/** The metadata an azurerm backend keeps a lock's info in, base64 JSON, on the leased blob. */
|
|
85
|
+
export const LOCK_METADATA = "terraformlockid";
|
|
86
|
+
/** The azurerm state blob, locked by a lease on it with the lock info in its metadata. */
|
|
87
|
+
function azureStore(o, fetchFn) {
|
|
88
|
+
const client = new AzureBlobClient({ account: o.account, container: o.container, endpoint: o.endpoint, ...o.auth }, fetchFn);
|
|
89
|
+
let leaseId;
|
|
90
|
+
const at = `az://${o.account}/${o.container}/${o.key}`;
|
|
91
|
+
return {
|
|
92
|
+
backend: "azurerm",
|
|
93
|
+
location: at,
|
|
94
|
+
lockLocation: at,
|
|
95
|
+
heldLock: async () => {
|
|
96
|
+
const head = await client.head(o.key);
|
|
97
|
+
if (!head.exists || head.leaseState !== "leased")
|
|
98
|
+
return undefined;
|
|
99
|
+
const meta = head.metadata[LOCK_METADATA];
|
|
100
|
+
const info = meta ? Buffer.from(meta, "base64").toString("utf-8") : "";
|
|
101
|
+
return { id: lockId(info), info };
|
|
102
|
+
},
|
|
103
|
+
lock: async (info) => {
|
|
104
|
+
const id = lockId(info);
|
|
105
|
+
// The backend leases a blob that is there: a state with none yet gets an empty one first, as the backend makes it.
|
|
106
|
+
if (!(await client.head(o.key)).exists)
|
|
107
|
+
await client.putBlob(o.key, "", JSON_TYPE, { ifNoneMatch: true });
|
|
108
|
+
if (!(await client.lease(o.key, "acquire", id)))
|
|
109
|
+
return false;
|
|
110
|
+
leaseId = id;
|
|
111
|
+
await client.setMetadata(o.key, { [LOCK_METADATA]: Buffer.from(info).toString("base64") }, id);
|
|
112
|
+
return true;
|
|
113
|
+
},
|
|
114
|
+
unlock: async () => {
|
|
115
|
+
if (!leaseId)
|
|
116
|
+
return;
|
|
117
|
+
const id = leaseId;
|
|
118
|
+
await client.setMetadata(o.key, {}, id);
|
|
119
|
+
await client.lease(o.key, "release", id);
|
|
120
|
+
leaseId = undefined;
|
|
121
|
+
},
|
|
122
|
+
write: async (body) => {
|
|
123
|
+
if (!leaseId)
|
|
124
|
+
throw new StoreError(`${at} is written under its lease, and none is held`);
|
|
125
|
+
// As the backend writes it: a snapshot first when it takes snapshots, and the lock info kept on the blob.
|
|
126
|
+
if (o.snapshot && (await client.head(o.key)).exists)
|
|
127
|
+
await client.snapshot(o.key);
|
|
128
|
+
const meta = (await client.head(o.key)).metadata;
|
|
129
|
+
await client.putBlob(o.key, body, JSON_TYPE, { leaseId, metadata: meta });
|
|
130
|
+
},
|
|
131
|
+
readBeside: (suffix) => client.get(`${o.key}${suffix}`),
|
|
132
|
+
writeBeside: async (suffix, body) => void (await client.putBlob(`${o.key}${suffix}`, body, JSON_TYPE)),
|
|
133
|
+
removeBeside: (suffix) => client.remove(`${o.key}${suffix}`),
|
|
134
|
+
besideLocation: (suffix) => `${at}${suffix}`,
|
|
135
|
+
adopt: (held) => {
|
|
136
|
+
leaseId = held.id;
|
|
137
|
+
},
|
|
138
|
+
};
|
|
139
|
+
}
|
|
140
|
+
/** A local state, locked by `<path>.tflock` created only when absent. `dir` is the root the path is relative to. */
|
|
141
|
+
function localStore(o, dir) {
|
|
142
|
+
const file = isAbsolute(o.path) ? o.path : join(dir, o.path);
|
|
143
|
+
const lockFile = `${file}.tflock`;
|
|
144
|
+
const read = (f) => (existsSync(f) ? readFileSync(f, "utf-8") : undefined);
|
|
145
|
+
return {
|
|
146
|
+
backend: "local",
|
|
147
|
+
location: file,
|
|
148
|
+
lockLocation: lockFile,
|
|
149
|
+
heldLock: async () => {
|
|
150
|
+
const text = read(lockFile);
|
|
151
|
+
return text === undefined ? undefined : { id: lockId(text), info: text };
|
|
152
|
+
},
|
|
153
|
+
lock: async (info) => {
|
|
154
|
+
mkdirSync(dirname(lockFile), { recursive: true });
|
|
155
|
+
try {
|
|
156
|
+
writeFileSync(lockFile, info, { flag: "wx" });
|
|
157
|
+
return true;
|
|
158
|
+
}
|
|
159
|
+
catch (e) {
|
|
160
|
+
if (e.code === "EEXIST")
|
|
161
|
+
return false;
|
|
162
|
+
throw e;
|
|
163
|
+
}
|
|
164
|
+
},
|
|
165
|
+
unlock: async () => rmSync(lockFile, { force: true }),
|
|
166
|
+
readBeside: async (suffix) => read(`${file}${suffix}`),
|
|
167
|
+
writeBeside: async (suffix, body) => {
|
|
168
|
+
mkdirSync(dirname(file), { recursive: true });
|
|
169
|
+
writeFileSync(`${file}${suffix}`, body);
|
|
170
|
+
},
|
|
171
|
+
removeBeside: async (suffix) => rmSync(`${file}${suffix}`, { force: true }),
|
|
172
|
+
besideLocation: (suffix) => `${file}${suffix}`,
|
|
173
|
+
adopt: () => { },
|
|
174
|
+
};
|
|
175
|
+
}
|
|
176
|
+
/** The store a state is in, opened with the credentials stateObject chose. `dir` is the root a local path is relative to. */
|
|
177
|
+
export function stateStore(o, dir, fetchFn) {
|
|
178
|
+
if (o.backend === "s3")
|
|
179
|
+
return s3Store(o, fetchFn);
|
|
180
|
+
if (o.backend === "gcs")
|
|
181
|
+
return gcsStore(o, fetchFn);
|
|
182
|
+
if (o.backend === "azurerm")
|
|
183
|
+
return azureStore(o, fetchFn);
|
|
184
|
+
return localStore(o, dir);
|
|
185
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"affected.d.ts","sourceRoot":"","sources":["../../src/terragrunt/affected.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAKH,OAAO,EAAqE,KAAK,qBAAqB,EAAE,KAAK,cAAc,EAAE,MAAM,SAAS,CAAC;AAC7I,OAAO,EAAmE,KAAK,oBAAoB,EAAE,MAAM,OAAO,CAAC;AAGnH,8BAA8B;AAC9B,MAAM,MAAM,sBAAsB;AAChC,2CAA2C;AACzC,YAAY;AACd,uHAAuH;GACrH,SAAS;AACX,uFAAuF;GACrF,aAAa;AACf,mEAAmE;GACjE,aAAa;AACf,0EAA0E;GACxE,gBAAgB,CAAC;AAErB,MAAM,WAAW,wBAAwB;IACvC,IAAI,EAAE,sBAAsB,CAAC;IAC7B,8HAA8H;IAC9H,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,4GAA4G;IAC5G,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,sBAAsB;IACrC,gDAAgD;IAChD,IAAI,EAAE,MAAM,CAAC;IACb,sGAAsG;IACtG,OAAO,EAAE,wBAAwB,EAAE,CAAC;CACrC;AAED,MAAM,WAAW,kBAAkB;IACjC,0CAA0C;IAC1C,KAAK,EAAE,sBAAsB,EAAE,CAAC;IAChC,8IAA8I;IAC9I,KAAK,EAAE,MAAM,EAAE,CAAC;CACjB;AAED,MAAM,WAAW,uBAAuB;IACtC,iGAAiG;IACjG,GAAG,EAAE,MAAM,CAAC;IACZ,0EAA0E;IAC1E,KAAK,EAAE,SAAS,cAAc,EAAE,CAAC;IACjC,mEAAmE;IACnE,kBAAkB,EAAE,SAAS,MAAM,EAAE,CAAC;IACtC,mHAAmH;IACnH,YAAY,EAAE,SAAS,MAAM,EAAE,CAAC;CACjC;AAQD,8GAA8G;AAC9G,wBAAgB,0BAA0B,CAAC,OAAO,EAAE;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,qBAAqB,GAAG,MAAM,EAAE,CAYrH;AAED,6FAA6F;AAC7F,wBAAgB,0BAA0B,CAAC,OAAO,EAAE;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,MAAM,EAAE,CAE7F;AAED,mJAAmJ;AACnJ,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,cAAc,GAAG,MAAM,EAAE,CAOnE;AAED,oGAAoG;AACpG,MAAM,WAAW,oBAAoB;IACnC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,mGAAmG;IACnG,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,0DAA0D;IAC1D,SAAS,EAAE,MAAM,CAAC;CACnB;AAED;;;;;;GAMG;AACH,wBAAgB,uBAAuB,CAAC,GAAG,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,oBAAoB,EAAE,CAoB5G;AAmCD,4FAA4F;AAC5F,wBAAgB,wBAAwB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,EAAE,CAiB9D;AAQD;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,uBAAuB,GAAG,kBAAkB,
|
|
1
|
+
{"version":3,"file":"affected.d.ts","sourceRoot":"","sources":["../../src/terragrunt/affected.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAKH,OAAO,EAAqE,KAAK,qBAAqB,EAAE,KAAK,cAAc,EAAE,MAAM,SAAS,CAAC;AAC7I,OAAO,EAAmE,KAAK,oBAAoB,EAAE,MAAM,OAAO,CAAC;AAGnH,8BAA8B;AAC9B,MAAM,MAAM,sBAAsB;AAChC,2CAA2C;AACzC,YAAY;AACd,uHAAuH;GACrH,SAAS;AACX,uFAAuF;GACrF,aAAa;AACf,mEAAmE;GACjE,aAAa;AACf,0EAA0E;GACxE,gBAAgB,CAAC;AAErB,MAAM,WAAW,wBAAwB;IACvC,IAAI,EAAE,sBAAsB,CAAC;IAC7B,8HAA8H;IAC9H,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,4GAA4G;IAC5G,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,sBAAsB;IACrC,gDAAgD;IAChD,IAAI,EAAE,MAAM,CAAC;IACb,sGAAsG;IACtG,OAAO,EAAE,wBAAwB,EAAE,CAAC;CACrC;AAED,MAAM,WAAW,kBAAkB;IACjC,0CAA0C;IAC1C,KAAK,EAAE,sBAAsB,EAAE,CAAC;IAChC,8IAA8I;IAC9I,KAAK,EAAE,MAAM,EAAE,CAAC;CACjB;AAED,MAAM,WAAW,uBAAuB;IACtC,iGAAiG;IACjG,GAAG,EAAE,MAAM,CAAC;IACZ,0EAA0E;IAC1E,KAAK,EAAE,SAAS,cAAc,EAAE,CAAC;IACjC,mEAAmE;IACnE,kBAAkB,EAAE,SAAS,MAAM,EAAE,CAAC;IACtC,mHAAmH;IACnH,YAAY,EAAE,SAAS,MAAM,EAAE,CAAC;CACjC;AAQD,8GAA8G;AAC9G,wBAAgB,0BAA0B,CAAC,OAAO,EAAE;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,qBAAqB,GAAG,MAAM,EAAE,CAYrH;AAED,6FAA6F;AAC7F,wBAAgB,0BAA0B,CAAC,OAAO,EAAE;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,MAAM,EAAE,CAE7F;AAED,mJAAmJ;AACnJ,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,cAAc,GAAG,MAAM,EAAE,CAOnE;AAED,oGAAoG;AACpG,MAAM,WAAW,oBAAoB;IACnC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,mGAAmG;IACnG,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,0DAA0D;IAC1D,SAAS,EAAE,MAAM,CAAC;CACnB;AAED;;;;;;GAMG;AACH,wBAAgB,uBAAuB,CAAC,GAAG,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,oBAAoB,EAAE,CAoB5G;AAmCD,4FAA4F;AAC5F,wBAAgB,wBAAwB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,EAAE,CAiB9D;AAQD;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,uBAAuB,GAAG,kBAAkB,CA8ErF;AAED,sDAAsD;AACtD,wBAAgB,gCAAgC,CAAC,MAAM,EAAE,wBAAwB,GAAG,MAAM,CAczF;AAED,MAAM,WAAW,6BAA8B,SAAQ,oBAAoB,EAAE,qBAAqB;IAChG,sDAAsD;IACtD,IAAI,EAAE,MAAM,CAAC;IACb,wCAAwC;IACxC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,qGAAqG;IACrG,KAAK,CAAC,EAAE,SAAS,cAAc,EAAE,CAAC;IAClC,mDAAmD;IACnD,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED,qGAAqG;AACrG,wBAAsB,sBAAsB,CAAC,OAAO,EAAE,6BAA6B,GAAG,OAAO,CAAC,kBAAkB,CAAC,CAuBhH"}
|
|
@@ -190,7 +190,8 @@ export function terragruntAffected(input) {
|
|
|
190
190
|
const moduleDirs = terragruntModuleDirs(unit);
|
|
191
191
|
const called = new Map();
|
|
192
192
|
for (const m of moduleDirs) {
|
|
193
|
-
|
|
193
|
+
// Terragrunt runs tofu when it is installed, so a module's `.tofu` files count (chant#4457).
|
|
194
|
+
for (const d of rootWatchPaths(input.dir, { dir: m }, "tofu"))
|
|
194
195
|
if (!moduleDirs.includes(d) && !called.has(d))
|
|
195
196
|
called.set(d, m);
|
|
196
197
|
}
|
package/package.json
CHANGED
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@intentius/chant-lexicon-terraform",
|
|
3
|
-
"version": "0.124.
|
|
3
|
+
"version": "0.124.54",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"files": [
|
|
6
6
|
"src/",
|
|
7
7
|
"dist/",
|
|
8
|
-
"schemas/",
|
|
9
8
|
"workspace-kinds.json"
|
|
10
9
|
],
|
|
11
10
|
"exports": {
|
|
@@ -40,6 +39,11 @@
|
|
|
40
39
|
"types": "./dist/terragrunt/index.d.ts",
|
|
41
40
|
"default": "./dist/terragrunt/index.js"
|
|
42
41
|
},
|
|
42
|
+
"./state": {
|
|
43
|
+
"development": "./src/state/index.ts",
|
|
44
|
+
"types": "./dist/state/index.d.ts",
|
|
45
|
+
"default": "./dist/state/index.js"
|
|
46
|
+
},
|
|
43
47
|
"./lint/post-synth": {
|
|
44
48
|
"development": "./src/lint/post-synth/index.ts",
|
|
45
49
|
"types": "./dist/lint/post-synth/index.d.ts",
|
|
@@ -68,7 +72,7 @@
|
|
|
68
72
|
"access": "public"
|
|
69
73
|
},
|
|
70
74
|
"peerDependencies": {
|
|
71
|
-
"@intentius/chant": "^0.124.
|
|
75
|
+
"@intentius/chant": "^0.124.54",
|
|
72
76
|
"zod": "^4.3.6"
|
|
73
77
|
},
|
|
74
78
|
"description": "terraform lexicon for chant, existing Terraform root modules as declarable entities",
|
|
@@ -1,14 +1,17 @@
|
|
|
1
1
|
# What the gated acceptance suites have actually run against
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Eleven `describe` blocks across eight files run this lexicon against a real
|
|
4
4
|
binary rather than a fixture, and every one of them skips rather than fails
|
|
5
5
|
when its dependency is absent. A skip is silent by design, so without this
|
|
6
6
|
file nothing in the tree says which of them has ever passed, against what, or
|
|
7
7
|
when. The evidence had been living in PR prose (`#2157` for the live apply
|
|
8
8
|
pair), which no reader of the suite can see.
|
|
9
9
|
|
|
10
|
-
|
|
11
|
-
|
|
10
|
+
Ten sections below cover the eleven blocks, one section per block except
|
|
11
|
+
section 6, where `plan-read.acceptance.test.ts`'s per-binary loop makes two
|
|
12
|
+
blocks of one body. Each section says what the block proves, what gates it,
|
|
13
|
+
the command, and the last binary and emulator it is known to have passed
|
|
14
|
+
against, or "not recorded" when no run has been written down yet.
|
|
12
15
|
|
|
13
16
|
`live-estate/README.md` next door is the sibling record for the two recorded
|
|
14
17
|
documents (`../live-plan.json`, `../live-ls.json`) rather than for a suite,
|
|
@@ -31,7 +34,7 @@ same recipe one tag back
|
|
|
31
34
|
`live/smoke/docker-compose.yml` and exported as
|
|
32
35
|
`CHOUDOUFU_EMULATOR_ENDPOINT=http://localhost:<mapped port>`.
|
|
33
36
|
|
|
34
|
-
## The
|
|
37
|
+
## The eleven blocks
|
|
35
38
|
|
|
36
39
|
### 1. `TerraformApplyOp applies a real root`
|
|
37
40
|
|
|
@@ -52,7 +55,7 @@ npx vitest run lexicons/terraform/src/composites/terraform-apply-op.acceptance.t
|
|
|
52
55
|
Last passed: 2026-09-08, `Terraform v1.15.8` on `darwin_arm64`, with
|
|
53
56
|
`hashicorp/null` resolved from the public registry for the fixture's `~> 3.2`
|
|
54
57
|
constraint. No emulator is involved. Re-run by chant #2241 alongside every
|
|
55
|
-
other block
|
|
58
|
+
other block this file held then, so those four rows come from one run; #2168 had run it
|
|
56
59
|
on 2026-09-07 the same way.
|
|
57
60
|
|
|
58
61
|
### 2. `TerraformApplyOp applies a live root against choudoufu's emulator`
|
|
@@ -172,7 +175,7 @@ path, which is the only thing it exists to prove.
|
|
|
172
175
|
|
|
173
176
|
### 5. `TerraformAdoptOp reaches its gate on a checkout that has never run init`
|
|
174
177
|
|
|
175
|
-
Same file,
|
|
178
|
+
Same file, second block (#2302). One test: build `TerraformAdoptOp` and drive
|
|
176
179
|
it through `runOpLocally`, exactly as the apply Op's own acceptance suite
|
|
177
180
|
does, over a project this test creates fresh and never initializes by hand —
|
|
178
181
|
no `terraformInit` call anywhere in the block. The Op's own Init phase is what
|
|
@@ -215,7 +218,8 @@ With the Init phase back, the same run reaches its gate:
|
|
|
215
218
|
|
|
216
219
|
`../plan-read.acceptance.test.ts`, one block per binary, three tests each, over
|
|
217
220
|
the `plan-read/` fixture (built-in `terraform_data`, `local` backend, so no
|
|
218
|
-
registry, no network and no credentials).
|
|
221
|
+
registry, no network and no credentials). Four tests each now; the run recorded
|
|
222
|
+
below had three, before #4372 added the planned-create test. The first reads the plan depth
|
|
219
223
|
through `describeResources` and checks the IR attributes, `sources` reading
|
|
220
224
|
`"plan"`, no secret in the result, nothing new or changed in the root, and no
|
|
221
225
|
`chant-terraform-plan-*` directory left in the temp dir. The second holds the
|
|
@@ -263,6 +267,64 @@ by chant #4371. Proved red the same day: with `plan-observation.ts`'s
|
|
|
263
267
|
redaction put back to flagging each side by its own marks, the old secret
|
|
264
268
|
came through as `tags.token`'s `before`.
|
|
265
269
|
|
|
270
|
+
### 8. `Terragrunt units against a real terragrunt`
|
|
271
|
+
|
|
272
|
+
`terragrunt/terragrunt.acceptance.test.ts` (#3414), four tests over the
|
|
273
|
+
`terragrunt/five-units/` fixture (implicit stacks, `terraform_data` only,
|
|
274
|
+
local state under the copied fixture, so no provider download and no cloud).
|
|
275
|
+
It checks that `terragrunt` is 1.1 or later, that `discoverTerragruntUnits`
|
|
276
|
+
lists what `terragrunt find` lists less the catalog template, that each of the
|
|
277
|
+
three waves plans and applies exactly its own units and that the run report's
|
|
278
|
+
per-unit results reach the change set with no input carrying a mock, and that
|
|
279
|
+
a wave keeps to its units when a `.terragrunt-filters` file selects more.
|
|
280
|
+
|
|
281
|
+
Gated on `terragrunt` and `tofu` on PATH.
|
|
282
|
+
|
|
283
|
+
```
|
|
284
|
+
npx vitest run lexicons/terraform/src/terragrunt/terragrunt.acceptance.test.ts
|
|
285
|
+
```
|
|
286
|
+
|
|
287
|
+
Last passed: not recorded. No run of this block has been written down; the
|
|
288
|
+
maintainer records the first one here (maintainer run).
|
|
289
|
+
|
|
290
|
+
### 9. `mock outputs in Terragrunt waves against a real terragrunt`
|
|
291
|
+
|
|
292
|
+
`terragrunt/mocks.acceptance.test.ts` (#3416), one test over the same
|
|
293
|
+
`five-units/` fixture. Wave 2 is refused until wave 1 has applied, naming each
|
|
294
|
+
upstream and planning nothing. A provisional plan of wave 2 made before that
|
|
295
|
+
reads the mocks, is marked provisional, matches Terragrunt's own mock warning,
|
|
296
|
+
and is refused at apply. Once wave 1 applies, wave 2 plans on the real
|
|
297
|
+
upstream values and applies.
|
|
298
|
+
|
|
299
|
+
Gated on `terragrunt` and `tofu` on PATH.
|
|
300
|
+
|
|
301
|
+
```
|
|
302
|
+
npx vitest run lexicons/terraform/src/terragrunt/mocks.acceptance.test.ts
|
|
303
|
+
```
|
|
304
|
+
|
|
305
|
+
Last passed: not recorded. No run of this block has been written down; the
|
|
306
|
+
maintainer records the first one here (maintainer run).
|
|
307
|
+
|
|
308
|
+
### 10. `affected Terragrunt units against a real terragrunt`
|
|
309
|
+
|
|
310
|
+
`terragrunt/affected.acceptance.test.ts` (#3415), over a git copy of the
|
|
311
|
+
`terragrunt/affected/` fixture. One test checks discovery against
|
|
312
|
+
`recorded/affected-find.json`; then one test per case in
|
|
313
|
+
`__fixtures__/terragrunt/affected-cases.ts`, each made as a commit, checks that
|
|
314
|
+
Terragrunt's own `[HEAD~1...HEAD]` filter selects exactly the case's
|
|
315
|
+
`terragrunt` column (nothing, for the three supplements) and that
|
|
316
|
+
`findTerragruntAffected` returns the case's expected units and reasons. Nothing
|
|
317
|
+
is planned.
|
|
318
|
+
|
|
319
|
+
Gated on `terragrunt` and `git` on PATH. It does not need `tofu`.
|
|
320
|
+
|
|
321
|
+
```
|
|
322
|
+
npx vitest run lexicons/terraform/src/terragrunt/affected.acceptance.test.ts
|
|
323
|
+
```
|
|
324
|
+
|
|
325
|
+
Last passed: not recorded. No run of this block has been written down; the
|
|
326
|
+
maintainer records the first one here (maintainer run).
|
|
327
|
+
|
|
266
328
|
## Running everything that can run on a machine with no choudoufu
|
|
267
329
|
|
|
268
330
|
```
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
{"@level":"info","@message":"Terraform 1.10.5","@module":"terraform.ui","@timestamp":"2026-10-25T12:05:00.101000Z","terraform":"1.10.5","type":"version","ui":"1.2"}
|
|
2
|
+
{"@level":"info","@message":"module.net.terraform_data.vpc: Plan to update","@module":"terraform.ui","@timestamp":"2026-10-25T12:05:00.412000Z","change":{"resource":{"addr":"module.net.terraform_data.vpc","module":"module.net","resource":"terraform_data.vpc","implied_provider":"terraform","resource_type":"terraform_data","resource_name":"vpc","resource_key":null},"action":"update"},"type":"planned_change"}
|
|
3
|
+
{"@level":"info","@message":"module.app.terraform_data.service: Plan to create","@module":"terraform.ui","@timestamp":"2026-10-25T12:05:00.412100Z","change":{"resource":{"addr":"module.app.terraform_data.service","module":"module.app","resource":"terraform_data.service","implied_provider":"terraform","resource_type":"terraform_data","resource_name":"service","resource_key":null},"action":"create"},"type":"planned_change"}
|
|
4
|
+
{"@level":"info","@message":"module.app.module.logs.terraform_data.group: Plan to create","@module":"terraform.ui","@timestamp":"2026-10-25T12:05:00.412200Z","change":{"resource":{"addr":"module.app.module.logs.terraform_data.group","module":"module.app.module.logs","resource":"terraform_data.group","implied_provider":"terraform","resource_type":"terraform_data","resource_name":"group","resource_key":null},"action":"create"},"type":"planned_change"}
|
|
5
|
+
{"@level":"info","@message":"module.edge.terraform_data.dns: Plan to update","@module":"terraform.ui","@timestamp":"2026-10-25T12:05:00.412300Z","change":{"resource":{"addr":"module.edge.terraform_data.dns","module":"module.edge","resource":"terraform_data.dns","implied_provider":"terraform","resource_type":"terraform_data","resource_name":"dns","resource_key":null},"action":"update"},"type":"planned_change"}
|
|
6
|
+
{"@level":"info","@message":"Plan: 2 to add, 2 to change, 0 to destroy.","@module":"terraform.ui","@timestamp":"2026-10-25T12:05:00.412400Z","changes":{"add":2,"change":2,"import":0,"remove":0,"operation":"apply"},"type":"change_summary"}
|
|
7
|
+
{"@level":"info","@message":"module.net.terraform_data.vpc: Modifying... [id=6f2b6c1e-0c55-4f0b-9d4e-3a1c2b7d9e01]","@module":"terraform.ui","@timestamp":"2026-10-25T12:05:00.520000Z","hook":{"resource":{"addr":"module.net.terraform_data.vpc","module":"module.net","resource":"terraform_data.vpc","implied_provider":"terraform","resource_type":"terraform_data","resource_name":"vpc","resource_key":null},"action":"update","id_key":"id","id_value":"6f2b6c1e-0c55-4f0b-9d4e-3a1c2b7d9e01"},"type":"apply_start"}
|
|
8
|
+
{"@level":"info","@message":"module.net.terraform_data.vpc: Modifications complete after 0s [id=6f2b6c1e-0c55-4f0b-9d4e-3a1c2b7d9e01]","@module":"terraform.ui","@timestamp":"2026-10-25T12:05:00.530000Z","hook":{"resource":{"addr":"module.net.terraform_data.vpc","module":"module.net","resource":"terraform_data.vpc","implied_provider":"terraform","resource_type":"terraform_data","resource_name":"vpc","resource_key":null},"action":"update","id_key":"id","id_value":"6f2b6c1e-0c55-4f0b-9d4e-3a1c2b7d9e01","elapsed_seconds":0},"type":"apply_complete"}
|
|
9
|
+
{"@level":"info","@message":"module.app.terraform_data.service: Creating...","@module":"terraform.ui","@timestamp":"2026-10-25T12:05:00.540000Z","hook":{"resource":{"addr":"module.app.terraform_data.service","module":"module.app","resource":"terraform_data.service","implied_provider":"terraform","resource_type":"terraform_data","resource_name":"service","resource_key":null},"action":"create"},"type":"apply_start"}
|
|
10
|
+
{"@level":"error","@message":"module.app.terraform_data.service: Creation errored after 0s","@module":"terraform.ui","@timestamp":"2026-10-25T12:05:00.550000Z","hook":{"resource":{"addr":"module.app.terraform_data.service","module":"module.app","resource":"terraform_data.service","implied_provider":"terraform","resource_type":"terraform_data","resource_name":"service","resource_key":null},"action":"create","elapsed_seconds":0},"type":"apply_errored"}
|
|
11
|
+
{"@level":"error","@message":"Error: Invalid input","@module":"terraform.ui","@timestamp":"2026-10-25T12:05:00.551000Z","diagnostic":{"severity":"error","summary":"Invalid input","detail":"The service input is not a VPC id.\nCheck the vpc_id variable.","address":"module.app.terraform_data.service","range":{"filename":"../../roots/app/main.tf","start":{"line":1,"column":1,"byte":0},"end":{"line":1,"column":36,"byte":35}}},"type":"diagnostic"}
|
|
12
|
+
{"@level":"error","@message":"Error: Provider produced inconsistent final plan","@module":"terraform.ui","@timestamp":"2026-10-25T12:05:00.552000Z","diagnostic":{"severity":"error","summary":"Provider produced inconsistent final plan","detail":"This is a bug in the provider."},"type":"diagnostic"}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 4,
|
|
3
|
+
"terraform_version": "1.10.5",
|
|
4
|
+
"serial": 3,
|
|
5
|
+
"lineage": "8d4e2f1a-3b5c-4d6e-9f7a-1c2b3d4e5f60",
|
|
6
|
+
"outputs": {
|
|
7
|
+
"service_id": {
|
|
8
|
+
"value": "0b7e4a2c-93d1-4f6e-a5b8-2c1d9e3f4a77",
|
|
9
|
+
"type": "string"
|
|
10
|
+
}
|
|
11
|
+
},
|
|
12
|
+
"resources": [
|
|
13
|
+
{
|
|
14
|
+
"module": "module.logs",
|
|
15
|
+
"mode": "managed",
|
|
16
|
+
"type": "terraform_data",
|
|
17
|
+
"name": "group",
|
|
18
|
+
"provider": "provider[\"terraform.io/builtin/terraform\"]",
|
|
19
|
+
"instances": [
|
|
20
|
+
{
|
|
21
|
+
"schema_version": 0,
|
|
22
|
+
"attributes": {
|
|
23
|
+
"id": "a3c5e7f9-1b2d-4c6e-8a0b-3d5f7a9c1e2f",
|
|
24
|
+
"input": {
|
|
25
|
+
"value": "app-logs",
|
|
26
|
+
"type": "string"
|
|
27
|
+
},
|
|
28
|
+
"output": {
|
|
29
|
+
"value": "app-logs",
|
|
30
|
+
"type": "string"
|
|
31
|
+
},
|
|
32
|
+
"triggers_replace": null
|
|
33
|
+
},
|
|
34
|
+
"sensitive_attributes": [],
|
|
35
|
+
"identity_schema_version": 0
|
|
36
|
+
}
|
|
37
|
+
]
|
|
38
|
+
},
|
|
39
|
+
{
|
|
40
|
+
"mode": "managed",
|
|
41
|
+
"type": "terraform_data",
|
|
42
|
+
"name": "service",
|
|
43
|
+
"provider": "provider[\"terraform.io/builtin/terraform\"]",
|
|
44
|
+
"instances": [
|
|
45
|
+
{
|
|
46
|
+
"schema_version": 0,
|
|
47
|
+
"attributes": {
|
|
48
|
+
"id": "0b7e4a2c-93d1-4f6e-a5b8-2c1d9e3f4a77",
|
|
49
|
+
"input": {
|
|
50
|
+
"value": "6f2b6c1e-0c55-4f0b-9d4e-3a1c2b7d9e01",
|
|
51
|
+
"type": "string"
|
|
52
|
+
},
|
|
53
|
+
"output": {
|
|
54
|
+
"value": "6f2b6c1e-0c55-4f0b-9d4e-3a1c2b7d9e01",
|
|
55
|
+
"type": "string"
|
|
56
|
+
},
|
|
57
|
+
"triggers_replace": null
|
|
58
|
+
},
|
|
59
|
+
"sensitive_attributes": [],
|
|
60
|
+
"identity_schema_version": 0
|
|
61
|
+
}
|
|
62
|
+
]
|
|
63
|
+
}
|
|
64
|
+
],
|
|
65
|
+
"check_results": null
|
|
66
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 4,
|
|
3
|
+
"terraform_version": "1.10.5",
|
|
4
|
+
"serial": 12,
|
|
5
|
+
"lineage": "c0ffee00-1234-4abc-8def-0123456789ab",
|
|
6
|
+
"outputs": {
|
|
7
|
+
"name": {
|
|
8
|
+
"value": "www",
|
|
9
|
+
"type": "string"
|
|
10
|
+
}
|
|
11
|
+
},
|
|
12
|
+
"resources": [
|
|
13
|
+
{
|
|
14
|
+
"mode": "managed",
|
|
15
|
+
"type": "terraform_data",
|
|
16
|
+
"name": "dns",
|
|
17
|
+
"provider": "provider[\"terraform.io/builtin/terraform\"]",
|
|
18
|
+
"instances": [
|
|
19
|
+
{
|
|
20
|
+
"schema_version": 0,
|
|
21
|
+
"attributes": {
|
|
22
|
+
"id": "1d9a0c55-77e2-4c1b-8f3a-5b6e2d4c7a10",
|
|
23
|
+
"input": {
|
|
24
|
+
"value": "www",
|
|
25
|
+
"type": "string"
|
|
26
|
+
},
|
|
27
|
+
"output": {
|
|
28
|
+
"value": "www",
|
|
29
|
+
"type": "string"
|
|
30
|
+
},
|
|
31
|
+
"triggers_replace": null
|
|
32
|
+
},
|
|
33
|
+
"sensitive_attributes": [],
|
|
34
|
+
"identity_schema_version": 0
|
|
35
|
+
}
|
|
36
|
+
]
|
|
37
|
+
}
|
|
38
|
+
],
|
|
39
|
+
"check_results": null
|
|
40
|
+
}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 4,
|
|
3
|
+
"terraform_version": "1.10.5",
|
|
4
|
+
"serial": 7,
|
|
5
|
+
"lineage": "2b1f6c0a-6a1e-4c55-9f3d-7e0a1b2c3d4e",
|
|
6
|
+
"outputs": {
|
|
7
|
+
"vpc_id": {
|
|
8
|
+
"value": "6f2b6c1e-0c55-4f0b-9d4e-3a1c2b7d9e01",
|
|
9
|
+
"type": "string"
|
|
10
|
+
}
|
|
11
|
+
},
|
|
12
|
+
"resources": [
|
|
13
|
+
{
|
|
14
|
+
"mode": "managed",
|
|
15
|
+
"type": "terraform_data",
|
|
16
|
+
"name": "vpc",
|
|
17
|
+
"provider": "provider[\"terraform.io/builtin/terraform\"]",
|
|
18
|
+
"instances": [
|
|
19
|
+
{
|
|
20
|
+
"schema_version": 0,
|
|
21
|
+
"attributes": {
|
|
22
|
+
"id": "6f2b6c1e-0c55-4f0b-9d4e-3a1c2b7d9e01",
|
|
23
|
+
"input": {
|
|
24
|
+
"value": {
|
|
25
|
+
"cidr": "10.0.0.0/16",
|
|
26
|
+
"name": "core"
|
|
27
|
+
},
|
|
28
|
+
"type": [
|
|
29
|
+
"object",
|
|
30
|
+
{
|
|
31
|
+
"cidr": "string",
|
|
32
|
+
"name": "string"
|
|
33
|
+
}
|
|
34
|
+
]
|
|
35
|
+
},
|
|
36
|
+
"output": {
|
|
37
|
+
"value": {
|
|
38
|
+
"cidr": "10.0.0.0/16",
|
|
39
|
+
"name": "core"
|
|
40
|
+
},
|
|
41
|
+
"type": [
|
|
42
|
+
"object",
|
|
43
|
+
{
|
|
44
|
+
"cidr": "string",
|
|
45
|
+
"name": "string"
|
|
46
|
+
}
|
|
47
|
+
]
|
|
48
|
+
},
|
|
49
|
+
"triggers_replace": null
|
|
50
|
+
},
|
|
51
|
+
"sensitive_attributes": [],
|
|
52
|
+
"identity_schema_version": 0
|
|
53
|
+
}
|
|
54
|
+
]
|
|
55
|
+
}
|
|
56
|
+
],
|
|
57
|
+
"check_results": null
|
|
58
|
+
}
|