@intentius/chant-lexicon-terraform 0.57.0
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 +53 -0
- package/dist/codegen/docs-cli.d.ts +3 -0
- package/dist/codegen/docs-cli.d.ts.map +1 -0
- package/dist/codegen/docs.d.ts +11 -0
- package/dist/codegen/docs.d.ts.map +1 -0
- package/dist/codegen/generate-cli.d.ts +3 -0
- package/dist/codegen/generate-cli.d.ts.map +1 -0
- package/dist/codegen/generate.d.ts +28 -0
- package/dist/codegen/generate.d.ts.map +1 -0
- package/dist/codegen/package.d.ts +17 -0
- package/dist/codegen/package.d.ts.map +1 -0
- package/dist/composites/terraform-apply-op.d.ts +88 -0
- package/dist/composites/terraform-apply-op.d.ts.map +1 -0
- package/dist/composites/terraform-watch-op.d.ts +124 -0
- package/dist/composites/terraform-watch-op.d.ts.map +1 -0
- package/dist/config.d.ts +83 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/describe-resources.d.ts +127 -0
- package/dist/describe-resources.d.ts.map +1 -0
- package/dist/generated/index.d.ts +2 -0
- package/dist/generated/index.d.ts.map +1 -0
- package/dist/hcl/parse.d.ts +87 -0
- package/dist/hcl/parse.d.ts.map +1 -0
- package/dist/hcl/roots.d.ts +37 -0
- package/dist/hcl/roots.d.ts.map +1 -0
- package/dist/index.d.ts +12 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/integrity.json +12 -0
- package/dist/lint/audit-catalog.d.ts +12 -0
- package/dist/lint/audit-catalog.d.ts.map +1 -0
- package/dist/lint/audit-lineage.d.ts +21 -0
- package/dist/lint/audit-lineage.d.ts.map +1 -0
- package/dist/lint/post-synth/index.d.ts +3 -0
- package/dist/lint/post-synth/index.d.ts.map +1 -0
- package/dist/lint/post-synth/tf001.d.ts +17 -0
- package/dist/lint/post-synth/tf001.d.ts.map +1 -0
- package/dist/lint/rules/index.d.ts +5 -0
- package/dist/lint/rules/index.d.ts.map +1 -0
- package/dist/lint/rules/plan-before-apply.d.ts +30 -0
- package/dist/lint/rules/plan-before-apply.d.ts.map +1 -0
- package/dist/lsp/completions.d.ts +26 -0
- package/dist/lsp/completions.d.ts.map +1 -0
- package/dist/lsp/context.d.ts +70 -0
- package/dist/lsp/context.d.ts.map +1 -0
- package/dist/lsp/hover.d.ts +12 -0
- package/dist/lsp/hover.d.ts.map +1 -0
- package/dist/lsp/option-keys.d.ts +34 -0
- package/dist/lsp/option-keys.d.ts.map +1 -0
- package/dist/manifest.json +6 -0
- package/dist/meta.json +1 -0
- package/dist/okf/index.md +8 -0
- package/dist/okf/rules/TF001.md +11 -0
- package/dist/okf/rules/TF101.md +11 -0
- package/dist/op/activities/index.d.ts +22 -0
- package/dist/op/activities/index.d.ts.map +1 -0
- package/dist/op/activities/terraform.d.ts +213 -0
- package/dist/op/activities/terraform.d.ts.map +1 -0
- package/dist/op/builders.d.ts +56 -0
- package/dist/op/builders.d.ts.map +1 -0
- package/dist/package-cli.d.ts +3 -0
- package/dist/package-cli.d.ts.map +1 -0
- package/dist/plugin.d.ts +11 -0
- package/dist/plugin.d.ts.map +1 -0
- package/dist/rules/plan-before-apply.ts +143 -0
- package/dist/rules/tf001.ts +66 -0
- package/dist/serializer.d.ts +19 -0
- package/dist/serializer.d.ts.map +1 -0
- package/dist/skills/chant-terraform.md +92 -0
- package/dist/state-ownership.d.ts +27 -0
- package/dist/state-ownership.d.ts.map +1 -0
- package/dist/types/index.d.ts +2 -0
- package/dist/validate-cli.d.ts +3 -0
- package/dist/validate-cli.d.ts.map +1 -0
- package/dist/validate.d.ts +15 -0
- package/dist/validate.d.ts.map +1 -0
- package/package.json +75 -0
- package/src/__fixtures__/no-backend/main.tf +24 -0
- package/src/__fixtures__/show-state.json +68 -0
- package/src/__fixtures__/with-backend/main.tf +28 -0
- package/src/__fixtures__/with-module/main.tf +49 -0
- package/src/__fixtures__/with-module/modules/inner/main.tf +5 -0
- package/src/codegen/docs-cli.ts +4 -0
- package/src/codegen/docs.ts +50 -0
- package/src/codegen/generate-cli.ts +10 -0
- package/src/codegen/generate.ts +68 -0
- package/src/codegen/package.ts +50 -0
- package/src/composites/terraform-apply-op.acceptance.test.ts +138 -0
- package/src/composites/terraform-apply-op.test.ts +193 -0
- package/src/composites/terraform-apply-op.ts +166 -0
- package/src/composites/terraform-watch-op.test.ts +184 -0
- package/src/composites/terraform-watch-op.ts +204 -0
- package/src/config.ts +76 -0
- package/src/describe-resources.test.ts +342 -0
- package/src/describe-resources.ts +357 -0
- package/src/generated/index.d.ts +2 -0
- package/src/generated/index.ts +4 -0
- package/src/generated/lexicon-terraform.json +1 -0
- package/src/hcl/parse.ts +235 -0
- package/src/hcl/roots.ts +67 -0
- package/src/index.ts +65 -0
- package/src/lint/audit-catalog.ts +30 -0
- package/src/lint/audit-lineage.ts +21 -0
- package/src/lint/audit.test.ts +45 -0
- package/src/lint/post-synth/index.ts +7 -0
- package/src/lint/post-synth/post-synth.test.ts +95 -0
- package/src/lint/post-synth/tf001.ts +66 -0
- package/src/lint/rules/index.ts +7 -0
- package/src/lint/rules/plan-before-apply.test.ts +111 -0
- package/src/lint/rules/plan-before-apply.ts +143 -0
- package/src/lsp/completions.test.ts +120 -0
- package/src/lsp/completions.ts +101 -0
- package/src/lsp/context.test.ts +152 -0
- package/src/lsp/context.ts +349 -0
- package/src/lsp/hover.test.ts +82 -0
- package/src/lsp/hover.ts +44 -0
- package/src/lsp/option-keys.ts +106 -0
- package/src/op/activities/index.ts +48 -0
- package/src/op/activities/registry.test.ts +29 -0
- package/src/op/activities/terraform.test.ts +445 -0
- package/src/op/activities/terraform.ts +469 -0
- package/src/op/builders.test.ts +90 -0
- package/src/op/builders.ts +96 -0
- package/src/package-cli.ts +21 -0
- package/src/plugin.test.ts +271 -0
- package/src/plugin.ts +157 -0
- package/src/serializer.test.ts +26 -0
- package/src/serializer.ts +26 -0
- package/src/skills/chant-terraform.md +92 -0
- package/src/state-ownership.ts +32 -0
- package/src/validate-cli.ts +5 -0
- package/src/validate.ts +28 -0
package/README.md
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
# @intentius/chant-lexicon-terraform
|
|
2
|
+
|
|
3
|
+
Terraform lexicon plugin for [chant](https://github.com/intentius/chant).
|
|
4
|
+
|
|
5
|
+
Unlike the lexicons that generate typed resource classes from an upstream
|
|
6
|
+
schema, this one reads the HCL an estate already has. Name your root modules in
|
|
7
|
+
`chant.config.ts` and each `.tf` block joins the build as an entity, so the
|
|
8
|
+
post-synth checks and `chant audit` can see the root without anything being
|
|
9
|
+
written back over it.
|
|
10
|
+
|
|
11
|
+
```ts
|
|
12
|
+
// chant.config.ts
|
|
13
|
+
import type { ChantConfig } from "@intentius/chant/config";
|
|
14
|
+
import "@intentius/chant-lexicon-terraform";
|
|
15
|
+
|
|
16
|
+
export default {
|
|
17
|
+
lexicons: ["terraform"],
|
|
18
|
+
terraform: {
|
|
19
|
+
binary: "terraform", // or "tofu"
|
|
20
|
+
roots: {
|
|
21
|
+
app: { dir: "./terraform", workspace: "prod", varFiles: ["prod.tfvars"] },
|
|
22
|
+
},
|
|
23
|
+
},
|
|
24
|
+
} satisfies ChantConfig;
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
`dir` resolves against the project root, the directory holding
|
|
28
|
+
`chant.config.ts`. A root that does not exist, or a `.tf` the parser refuses, is
|
|
29
|
+
a build warning and no entities for that root, never a failure.
|
|
30
|
+
|
|
31
|
+
## Getting started
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
# Assemble dist/ (there is no upstream spec to fetch)
|
|
35
|
+
npm run bundle
|
|
36
|
+
|
|
37
|
+
# Validate the generated artifacts
|
|
38
|
+
just validate
|
|
39
|
+
|
|
40
|
+
# Generate the docs site
|
|
41
|
+
just docs
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
## Project structure
|
|
45
|
+
|
|
46
|
+
- `src/plugin.ts`, the LexiconPlugin, including the `buildRoots()` hook
|
|
47
|
+
- `src/config.ts`, the `terraform` config namespace and its `ChantConfig` augmentation
|
|
48
|
+
- `src/hcl/parse.ts`, one entity per HCL block, from a directory or from `chant audit`'s joined-file form
|
|
49
|
+
- `src/hcl/roots.ts`, the per-root render `buildRoots()` delegates to
|
|
50
|
+
- `src/serializer.ts`, a deliberate no-op: the `.tf` files are the artifact
|
|
51
|
+
- `src/lint/rules/`, source-level lint rules
|
|
52
|
+
- `src/lint/post-synth/`, checks over the parsed roots (TF001 and up)
|
|
53
|
+
- `src/lsp/`, LSP completions and hover
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"docs-cli.d.ts","sourceRoot":"","sources":["../../src/codegen/docs-cli.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Generate the docs site for the terraform lexicon.
|
|
3
|
+
*
|
|
4
|
+
* `basePath` is what the unified site at /chant needs so assets and internal
|
|
5
|
+
* links resolve once this site is copied under it (scripts/build-docs.test.ts
|
|
6
|
+
* asserts it). Authored pages come from `docs/pages/` by default.
|
|
7
|
+
*/
|
|
8
|
+
export declare function generateDocs(options?: {
|
|
9
|
+
verbose?: boolean;
|
|
10
|
+
}): Promise<void>;
|
|
11
|
+
//# sourceMappingURL=docs.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"docs.d.ts","sourceRoot":"","sources":["../../src/codegen/docs.ts"],"names":[],"mappings":"AAsBA;;;;;;GAMG;AACH,wBAAsB,YAAY,CAAC,OAAO,CAAC,EAAE;IAAE,OAAO,CAAC,EAAE,OAAO,CAAA;CAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAoBjF"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"generate-cli.d.ts","sourceRoot":"","sources":["../../src/codegen/generate-cli.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Generation for the terraform lexicon: there is nothing to generate.
|
|
3
|
+
*
|
|
4
|
+
* Every other lexicon fetches one upstream schema and emits typed resource
|
|
5
|
+
* classes from it. Terraform has no such thing. Its resource surface lives in
|
|
6
|
+
* provider registries, one schema per provider and per version, and this
|
|
7
|
+
* lexicon does not model it: an estate's `.tf` files are read as they are
|
|
8
|
+
* (see `../hcl/parse.ts`) and the blocks become entities with their bodies
|
|
9
|
+
* carried verbatim. So `core`'s `generatePipeline` is not called at all, and
|
|
10
|
+
* this returns the empty result the packaging pipeline needs to assemble a
|
|
11
|
+
* bundle.
|
|
12
|
+
*
|
|
13
|
+
* The registry is still written, empty, because `validate` reads it and
|
|
14
|
+
* `writeBundleSpec` derives `dist/meta.json` from it. An empty registry is the
|
|
15
|
+
* honest statement that this lexicon exports no generated resource classes.
|
|
16
|
+
*/
|
|
17
|
+
import type { GenerateResult } from "@intentius/chant/codegen/generate";
|
|
18
|
+
/** Filename of the generated registry, read back by `../validate.ts`. */
|
|
19
|
+
export declare const LEXICON_JSON_FILENAME = "lexicon-terraform.json";
|
|
20
|
+
export declare function generate(options?: {
|
|
21
|
+
verbose?: boolean;
|
|
22
|
+
force?: boolean;
|
|
23
|
+
}): Promise<GenerateResult>;
|
|
24
|
+
/**
|
|
25
|
+
* Write generated files to the package directory.
|
|
26
|
+
*/
|
|
27
|
+
export declare function writeGeneratedFiles(result: GenerateResult, pkgDir?: string): void;
|
|
28
|
+
//# sourceMappingURL=generate.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"generate.d.ts","sourceRoot":"","sources":["../../src/codegen/generate.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAGH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,mCAAmC,CAAC;AAIxE,yEAAyE;AACzE,eAAO,MAAM,qBAAqB,2BAA2B,CAAC;AAY9D,wBAAsB,QAAQ,CAAC,OAAO,CAAC,EAAE;IAAE,OAAO,CAAC,EAAE,OAAO,CAAC;IAAC,KAAK,CAAC,EAAE,OAAO,CAAA;CAAE,GAAG,OAAO,CAAC,cAAc,CAAC,CAgBxG;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,cAAc,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAWjF"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Package the terraform lexicon for distribution.
|
|
3
|
+
*/
|
|
4
|
+
export declare function packageLexicon(options?: {
|
|
5
|
+
verbose?: boolean;
|
|
6
|
+
force?: boolean;
|
|
7
|
+
}): Promise<{
|
|
8
|
+
spec: import("packages/core/src").BundleSpec;
|
|
9
|
+
stats: {
|
|
10
|
+
resources: number;
|
|
11
|
+
properties: number;
|
|
12
|
+
enums: number;
|
|
13
|
+
ruleCount: number;
|
|
14
|
+
skillCount: number;
|
|
15
|
+
};
|
|
16
|
+
}>;
|
|
17
|
+
//# sourceMappingURL=package.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"package.d.ts","sourceRoot":"","sources":["../../src/codegen/package.ts"],"names":[],"mappings":"AA0BA;;GAEG;AACH,wBAAsB,cAAc,CAAC,OAAO,CAAC,EAAE;IAAE,OAAO,CAAC,EAAE,OAAO,CAAC;IAAC,KAAK,CAAC,EAAE,OAAO,CAAA;CAAE;;;;;;;;;GAoBpF"}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TerraformApplyOp composite (#2086) — init, plan, approve, apply for one root
|
|
3
|
+
* module named in `terraform.roots`.
|
|
4
|
+
*
|
|
5
|
+
* Authority stays with terraform: chant runs the binary, reads its plan, and
|
|
6
|
+
* hands the same saved plan to apply. The Apply step never re-plans, because
|
|
7
|
+
* it takes the Plan step's own `planFile` as a `StepOutputRef` — whatever was
|
|
8
|
+
* approved is what runs.
|
|
9
|
+
*
|
|
10
|
+
* Phases: Init, Plan, Gate, Apply.
|
|
11
|
+
*
|
|
12
|
+
* The gate is durable-runtime work, so an Op that emits one needs Temporal;
|
|
13
|
+
* `packages/core/src/op/local-executor.ts` refuses any Op containing a gate.
|
|
14
|
+
* `gate: "never"` is what makes the Op runnable with `chant run` locally.
|
|
15
|
+
*
|
|
16
|
+
* @example
|
|
17
|
+
* ```typescript
|
|
18
|
+
* import { TerraformApplyOp } from "@intentius/chant-lexicon-terraform";
|
|
19
|
+
*
|
|
20
|
+
* export const { op } = TerraformApplyOp({ name: "app-apply", root: "app" });
|
|
21
|
+
* ```
|
|
22
|
+
*/
|
|
23
|
+
import { OpResource } from "@intentius/chant/op";
|
|
24
|
+
/**
|
|
25
|
+
* When to pause for a human before applying.
|
|
26
|
+
*
|
|
27
|
+
* `GateStep` (`packages/core/src/op/types.ts`) carries a signal name, a
|
|
28
|
+
* timeout and a description, and nothing conditional — so `"on-destroy"`
|
|
29
|
+
* cannot branch at build time on a count the plan only produces at run time.
|
|
30
|
+
* The workable v1 is that `"on-destroy"` and `"always"` emit the same Gate
|
|
31
|
+
* phase, and the approver is told what is at stake instead: the phase reports
|
|
32
|
+
* the plan's `destroys` count as the `Destroys` search attribute before it
|
|
33
|
+
* waits, and the gate description says so. A gate that skips itself when the
|
|
34
|
+
* plan turns out additive is a new step kind, out of scope here.
|
|
35
|
+
*/
|
|
36
|
+
export type TerraformGateMode = "on-destroy" | "always" | "never";
|
|
37
|
+
export interface TerraformApplyOpConfig {
|
|
38
|
+
/** Op name (kebab-case). Also the default task queue and gate signal suffix. */
|
|
39
|
+
name: string;
|
|
40
|
+
/** Key into the project's `terraform.roots`. The root carries dir, workspace, var files and backend config. */
|
|
41
|
+
root: string;
|
|
42
|
+
/** Plan file written by Plan and consumed by Apply, relative to the root dir. Default: `chant.tfplan`. */
|
|
43
|
+
planFile?: string;
|
|
44
|
+
/**
|
|
45
|
+
* When to emit the approval gate. Default: `"on-destroy"`. See
|
|
46
|
+
* {@link TerraformGateMode} for why `"on-destroy"` and `"always"` build the
|
|
47
|
+
* same phase.
|
|
48
|
+
*/
|
|
49
|
+
gate?: TerraformGateMode;
|
|
50
|
+
/** Gate signal name. Default: `approve-<name>`, as `ApplyOp` does. */
|
|
51
|
+
signalName?: string;
|
|
52
|
+
/** Temporal duration the gate waits before timing out. Default: core's own (48h). */
|
|
53
|
+
gateTimeout?: string;
|
|
54
|
+
/** Override the gate description shown to the approver. */
|
|
55
|
+
gateDescription?: string;
|
|
56
|
+
/** `-upgrade` on the Init step: re-resolve provider and module versions. */
|
|
57
|
+
upgrade?: boolean;
|
|
58
|
+
/**
|
|
59
|
+
* Directory each step starts the `chant.config.*` search from, which is
|
|
60
|
+
* what `terraform.roots` and the root's relative `dir` resolve against.
|
|
61
|
+
* Default: the running process's cwd, which is the project root under
|
|
62
|
+
* `chant run`.
|
|
63
|
+
*/
|
|
64
|
+
cwd?: string;
|
|
65
|
+
/**
|
|
66
|
+
* Saga-style rollback on a failed apply, run as an `onFailure` phase.
|
|
67
|
+
*
|
|
68
|
+
* Terraform has no automatic rollback: a half-applied plan is undone by
|
|
69
|
+
* planning and applying the inverse, which is a decision about the estate
|
|
70
|
+
* rather than something chant can synthesize. So compensation here is
|
|
71
|
+
* total or refused, the same stance `ApplyOp` takes (`lexicons/temporal/src/
|
|
72
|
+
* composites/apply-op.ts`) — `true`, or an object with no `command`, throws
|
|
73
|
+
* when the Op is built, naming the Op, rather than warning at the moment a
|
|
74
|
+
* rollback is already needed. Supply `compensate: { command: "..." }` with a
|
|
75
|
+
* rollback of your own, or leave it unset.
|
|
76
|
+
*/
|
|
77
|
+
compensate?: boolean | {
|
|
78
|
+
command?: string;
|
|
79
|
+
};
|
|
80
|
+
/** Override the task queue. Defaults to `name`. */
|
|
81
|
+
taskQueue?: string;
|
|
82
|
+
}
|
|
83
|
+
export interface TerraformApplyOpResources {
|
|
84
|
+
/** Op resource — generates the Init/Plan/[Gate]/Apply workflow. */
|
|
85
|
+
op: InstanceType<typeof OpResource>;
|
|
86
|
+
}
|
|
87
|
+
export declare function TerraformApplyOp(config: TerraformApplyOpConfig): TerraformApplyOpResources;
|
|
88
|
+
//# sourceMappingURL=terraform-apply-op.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"terraform-apply-op.d.ts","sourceRoot":"","sources":["../../src/composites/terraform-apply-op.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,OAAO,EAA6B,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAS5E;;;;;;;;;;;GAWG;AACH,MAAM,MAAM,iBAAiB,GAAG,YAAY,GAAG,QAAQ,GAAG,OAAO,CAAC;AAElE,MAAM,WAAW,sBAAsB;IACrC,gFAAgF;IAChF,IAAI,EAAE,MAAM,CAAC;IACb,+GAA+G;IAC/G,IAAI,EAAE,MAAM,CAAC;IACb,0GAA0G;IAC1G,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;;;;OAIG;IACH,IAAI,CAAC,EAAE,iBAAiB,CAAC;IACzB,sEAAsE;IACtE,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,qFAAqF;IACrF,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,2DAA2D;IAC3D,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,4EAA4E;IAC5E,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB;;;;;OAKG;IACH,GAAG,CAAC,EAAE,MAAM,CAAC;IACb;;;;;;;;;;;OAWG;IACH,UAAU,CAAC,EAAE,OAAO,GAAG;QAAE,OAAO,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAC5C,mDAAmD;IACnD,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,yBAAyB;IACxC,mEAAmE;IACnE,EAAE,EAAE,YAAY,CAAC,OAAO,UAAU,CAAC,CAAC;CACrC;AAED,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,sBAAsB,GAAG,yBAAyB,CAqE1F"}
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TerraformWatchOp composite (#2087): drift reporting for one root module,
|
|
3
|
+
* on a schedule.
|
|
4
|
+
*
|
|
5
|
+
* The observe position on the lifecycle dial. `TerraformApplyOp` next door
|
|
6
|
+
* changes the estate; this one never does: it inits, plans, and reports what
|
|
7
|
+
* the plan found. `terraform plan -detailed-exitcode` is the whole mechanism.
|
|
8
|
+
* Exit 0 is "the world matches the configuration", exit 2 is drift, and
|
|
9
|
+
* `terraformPlan` turns that into the boolean `changed`, which rides out of
|
|
10
|
+
* the Op as the `Drift` search attribute.
|
|
11
|
+
*
|
|
12
|
+
* Phases: Init, Plan, and (for a finding mode that opens something) Report.
|
|
13
|
+
*
|
|
14
|
+
* ## Only the human plan is ever posted
|
|
15
|
+
*
|
|
16
|
+
* `terraformPlan` returns two renders of the same plan: `json`, from
|
|
17
|
+
* `terraform show -json`, and `text`, from `terraform show -no-color`. The
|
|
18
|
+
* JSON one carries every resource attribute value the plan touches, including
|
|
19
|
+
* provider credentials that no `sensitive` marking covers, because
|
|
20
|
+
* `sensitive_values` describes the configuration's own declarations rather
|
|
21
|
+
* than everything a provider puts in a plan. So the issue and pull-request
|
|
22
|
+
* modes reference `plan.out.text` and nothing else. There is no option to
|
|
23
|
+
* post the JSON, and `terraform-watch-op.test.ts` asserts no reference to it
|
|
24
|
+
* reaches the finding step.
|
|
25
|
+
*
|
|
26
|
+
* ## Findings reuse `reconcilePr`
|
|
27
|
+
*
|
|
28
|
+
* `issue` and `pull-request` call the temporal lexicon's `reconcilePr`
|
|
29
|
+
* activity, the one place in chant that shells to `gh issue create` /
|
|
30
|
+
* `gh pr create`, rather than growing a second copy of those calls here.
|
|
31
|
+
* That activity built its own change-set summary and had no way to be handed
|
|
32
|
+
* one, so #2087 added a single field to it (`ReconcilePrArgs.body`), which is
|
|
33
|
+
* what carries the `-no-color` plan through. Note that the pull-request mode
|
|
34
|
+
* of `reconcilePr` regenerates chant TypeScript via `chant import`; a
|
|
35
|
+
* terraform-native regeneration of HCL from live state is #2089, so until
|
|
36
|
+
* then `findingMode: "issue"` is the mode with an end-to-end answer and
|
|
37
|
+
* `"pull-request"` opens a PR whose body is the plan.
|
|
38
|
+
*
|
|
39
|
+
* ## The schedule
|
|
40
|
+
*
|
|
41
|
+
* A cron makes this a `{ op, schedule }` pair, the shape
|
|
42
|
+
* `lexicons/temporal/src/composites/workflow-audit-op.ts` and
|
|
43
|
+
* `reconcile-op.ts` return. The schedule resource is `Temporal::Schedule`,
|
|
44
|
+
* built here through core's own `createResource` rather than imported from
|
|
45
|
+
* `@intentius/chant-lexicon-temporal`: no lexicon in this repo imports
|
|
46
|
+
* another lexicon's package at runtime, and a static import would mean a
|
|
47
|
+
* project that installs terraform and runs `chant run` on the local executor
|
|
48
|
+
* could not load `@intentius/chant-lexicon-terraform` at all without also
|
|
49
|
+
* installing temporal. The declarable is the same one temporal's
|
|
50
|
+
* `TemporalSchedule` produces (`createResource("Temporal::Schedule",
|
|
51
|
+
* "temporal", {})`, `lexicons/temporal/src/resources.ts`), so temporal's
|
|
52
|
+
* serializer renders it unchanged when a project has both.
|
|
53
|
+
*
|
|
54
|
+
* A project with no Temporal at all runs the same Op on a CI cron instead:
|
|
55
|
+
* `generateOpsPipeline` against the github lexicon turns the Op plus its cron
|
|
56
|
+
* into a workflow. `examples/scheduled-watch/` is that recipe.
|
|
57
|
+
*
|
|
58
|
+
* @example
|
|
59
|
+
* ```typescript
|
|
60
|
+
* import { TerraformWatchOp } from "@intentius/chant-lexicon-terraform";
|
|
61
|
+
*
|
|
62
|
+
* // one-shot, local executor: chant run app-watch
|
|
63
|
+
* export const { op } = TerraformWatchOp({ name: "app-watch", root: "app" });
|
|
64
|
+
*
|
|
65
|
+
* // nightly, opening an issue when the plan is non-empty
|
|
66
|
+
* export const { op, schedule } = TerraformWatchOp({
|
|
67
|
+
* name: "app-watch",
|
|
68
|
+
* root: "app",
|
|
69
|
+
* schedule: "0 6 * * *",
|
|
70
|
+
* findingMode: "issue",
|
|
71
|
+
* });
|
|
72
|
+
* ```
|
|
73
|
+
*/
|
|
74
|
+
import { OpResource } from "@intentius/chant/op";
|
|
75
|
+
import type { Declarable } from "@intentius/chant/declarable";
|
|
76
|
+
/**
|
|
77
|
+
* What to do with a non-empty plan. A subset of core's `OpFindingMode`
|
|
78
|
+
* (`packages/core/src/lexicon.ts`): `merge-request` is GitLab's spelling of
|
|
79
|
+
* `pull-request` and is produced by the CI generator, not chosen here.
|
|
80
|
+
*/
|
|
81
|
+
export type TerraformFindingMode = "report" | "issue" | "pull-request";
|
|
82
|
+
export interface TerraformWatchOpConfig {
|
|
83
|
+
/** Op name (kebab-case). Also the default task queue and schedule id base. */
|
|
84
|
+
name: string;
|
|
85
|
+
/** Key into the project's `terraform.roots`. The root carries dir, workspace, var files and backend config. */
|
|
86
|
+
root: string;
|
|
87
|
+
/**
|
|
88
|
+
* Cron expression. When set, a `Temporal::Schedule` is returned alongside
|
|
89
|
+
* the Op; omit for one-shot `chant run` on the local executor, or for a CI
|
|
90
|
+
* cron built by `generateOpsPipeline`.
|
|
91
|
+
*/
|
|
92
|
+
schedule?: string;
|
|
93
|
+
/**
|
|
94
|
+
* What to do when the plan proposes changes. Default: `"report"`, which
|
|
95
|
+
* opens nothing. The `Drift` search attribute and the run's own log are
|
|
96
|
+
* the report.
|
|
97
|
+
*/
|
|
98
|
+
findingMode?: TerraformFindingMode;
|
|
99
|
+
/** Plan file the Plan step writes, relative to the root dir. Default: `chant.tfplan`. */
|
|
100
|
+
planFile?: string;
|
|
101
|
+
/** `-upgrade` on the Init step: re-resolve provider and module versions. */
|
|
102
|
+
upgrade?: boolean;
|
|
103
|
+
/**
|
|
104
|
+
* Directory each step starts the `chant.config.*` search from, which is
|
|
105
|
+
* what `terraform.roots` and the root's relative `dir` resolve against.
|
|
106
|
+
* Default: the running process's cwd, which is the project root under
|
|
107
|
+
* `chant run`. Same field, same meaning, as `TerraformApplyOpConfig.cwd`.
|
|
108
|
+
*/
|
|
109
|
+
cwd?: string;
|
|
110
|
+
/** Issue / PR title. Default: `Terraform drift in root "<root>"`. */
|
|
111
|
+
title?: string;
|
|
112
|
+
/** Branch the pull-request mode opens from. Default: `reconcilePr`'s own. */
|
|
113
|
+
branch?: string;
|
|
114
|
+
/** Override the task queue. Defaults to `name`. */
|
|
115
|
+
taskQueue?: string;
|
|
116
|
+
}
|
|
117
|
+
export interface TerraformWatchOpResources {
|
|
118
|
+
/** Op resource. Generates the Init/Plan/[Report] workflow. */
|
|
119
|
+
op: InstanceType<typeof OpResource>;
|
|
120
|
+
/** `Temporal::Schedule`, present only when `schedule` was given. */
|
|
121
|
+
schedule?: Declarable;
|
|
122
|
+
}
|
|
123
|
+
export declare function TerraformWatchOp(config: TerraformWatchOpConfig): TerraformWatchOpResources;
|
|
124
|
+
//# sourceMappingURL=terraform-watch-op.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"terraform-watch-op.d.ts","sourceRoot":"","sources":["../../src/composites/terraform-watch-op.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwEG;AAEH,OAAO,EAAa,UAAU,EAAqB,MAAM,qBAAqB,CAAC;AAE/E,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,6BAA6B,CAAC;AAI9D;;;;GAIG;AACH,MAAM,MAAM,oBAAoB,GAAG,QAAQ,GAAG,OAAO,GAAG,cAAc,CAAC;AAcvE,MAAM,WAAW,sBAAsB;IACrC,8EAA8E;IAC9E,IAAI,EAAE,MAAM,CAAC;IACb,+GAA+G;IAC/G,IAAI,EAAE,MAAM,CAAC;IACb;;;;OAIG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;;;;OAIG;IACH,WAAW,CAAC,EAAE,oBAAoB,CAAC;IACnC,yFAAyF;IACzF,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,4EAA4E;IAC5E,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB;;;;;OAKG;IACH,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,qEAAqE;IACrE,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,6EAA6E;IAC7E,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,mDAAmD;IACnD,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,yBAAyB;IACxC,8DAA8D;IAC9D,EAAE,EAAE,YAAY,CAAC,OAAO,UAAU,CAAC,CAAC;IACpC,oEAAoE;IACpE,QAAQ,CAAC,EAAE,UAAU,CAAC;CACvB;AAED,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,sBAAsB,GAAG,yBAAyB,CA6D1F"}
|
package/dist/config.d.ts
ADDED
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The `terraform` namespace in `chant.config.ts` (#1344).
|
|
3
|
+
*
|
|
4
|
+
* ```ts
|
|
5
|
+
* import type { ChantConfig } from "@intentius/chant/config";
|
|
6
|
+
* import "@intentius/chant-lexicon-terraform"; // brings the `terraform` key into ChantConfig
|
|
7
|
+
*
|
|
8
|
+
* export default {
|
|
9
|
+
* lexicons: ["terraform"],
|
|
10
|
+
* terraform: {
|
|
11
|
+
* binary: "tofu",
|
|
12
|
+
* roots: {
|
|
13
|
+
* app: { dir: "./terraform/app", workspace: "prod", varFiles: ["prod.tfvars"] },
|
|
14
|
+
* },
|
|
15
|
+
* },
|
|
16
|
+
* } satisfies ChantConfig;
|
|
17
|
+
* ```
|
|
18
|
+
*
|
|
19
|
+
* One schema, three consumers: core validates the namespace against it at load,
|
|
20
|
+
* the type below is derived from it, and that derived type is what augments
|
|
21
|
+
* `ChantConfig`, so an unknown key fails at build time and at compile time for
|
|
22
|
+
* the same reason, rather than being silently ignored at both.
|
|
23
|
+
*/
|
|
24
|
+
import { z } from "zod";
|
|
25
|
+
import type { ChantConfig } from "@intentius/chant/config";
|
|
26
|
+
/**
|
|
27
|
+
* One Terraform root module chant reads. `dir` is the only required field:
|
|
28
|
+
* everything else names how the root is invoked rather than what it declares.
|
|
29
|
+
*
|
|
30
|
+
* `strictObject`, not `object`. Core applies `.strict()` to the top level of a
|
|
31
|
+
* declared namespace itself, but nested objects are the lexicon's own to make
|
|
32
|
+
* strict, and a root entry is exactly where a typo (`varfiles`) would
|
|
33
|
+
* otherwise land silently.
|
|
34
|
+
*/
|
|
35
|
+
export declare const terraformRootSchema: z.ZodObject<{
|
|
36
|
+
/** Root module directory, relative to the project root (where `chant.config.*` lives). */
|
|
37
|
+
dir: z.ZodString;
|
|
38
|
+
/** Terraform workspace to select for this root. Omitted means `default`. */
|
|
39
|
+
workspace: z.ZodOptional<z.ZodString>;
|
|
40
|
+
/** `-var-file` arguments, in order, relative to `dir`. */
|
|
41
|
+
varFiles: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
42
|
+
/** `-backend-config` key/value pairs handed to `init`. */
|
|
43
|
+
backendConfig: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
44
|
+
}, z.core.$strict>;
|
|
45
|
+
export declare const terraformConfigSchema: z.ZodObject<{
|
|
46
|
+
/**
|
|
47
|
+
* Which CLI drives the roots. The two are wire-compatible for everything
|
|
48
|
+
* this lexicon does, so the choice is recorded rather than inferred.
|
|
49
|
+
*/
|
|
50
|
+
binary: z.ZodOptional<z.ZodEnum<{
|
|
51
|
+
terraform: "terraform";
|
|
52
|
+
tofu: "tofu";
|
|
53
|
+
}>>;
|
|
54
|
+
/** Named root modules. The name is the entity-key prefix, so keep it stable. */
|
|
55
|
+
roots: z.ZodRecord<z.ZodString, z.ZodObject<{
|
|
56
|
+
/** Root module directory, relative to the project root (where `chant.config.*` lives). */
|
|
57
|
+
dir: z.ZodString;
|
|
58
|
+
/** Terraform workspace to select for this root. Omitted means `default`. */
|
|
59
|
+
workspace: z.ZodOptional<z.ZodString>;
|
|
60
|
+
/** `-var-file` arguments, in order, relative to `dir`. */
|
|
61
|
+
varFiles: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
62
|
+
/** `-backend-config` key/value pairs handed to `init`. */
|
|
63
|
+
backendConfig: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
64
|
+
}, z.core.$strict>>;
|
|
65
|
+
}, z.core.$strict>;
|
|
66
|
+
export type TerraformRootConfig = z.infer<typeof terraformRootSchema>;
|
|
67
|
+
export type TerraformConfig = z.infer<typeof terraformConfigSchema>;
|
|
68
|
+
declare module "@intentius/chant/config" {
|
|
69
|
+
interface ChantConfig {
|
|
70
|
+
terraform?: TerraformConfig;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Compile-time proof that the augmentation above reaches `ChantConfig` (#1344).
|
|
75
|
+
*
|
|
76
|
+
* Without it this line is `Property 'terraform' does not exist on type
|
|
77
|
+
* 'ChantConfig'`, which is exactly the error a user's `chant.config.ts` gets.
|
|
78
|
+
* It lives here rather than in a test because the root tsconfig excludes test
|
|
79
|
+
* files from typechecking, so a compile-time claim asserted in one is checked
|
|
80
|
+
* by nothing.
|
|
81
|
+
*/
|
|
82
|
+
export type TerraformConfigNamespace = NonNullable<ChantConfig["terraform"]>;
|
|
83
|
+
//# sourceMappingURL=config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAE3D;;;;;;;;GAQG;AACH,eAAO,MAAM,mBAAmB;IAC9B,0FAA0F;;IAE1F,4EAA4E;;IAE5E,0DAA0D;;IAE1D,0DAA0D;;kBAE1D,CAAC;AAEH,eAAO,MAAM,qBAAqB;IAChC;;;OAGG;;;;;IAEH,gFAAgF;;QAhBhF,0FAA0F;;QAE1F,4EAA4E;;QAE5E,0DAA0D;;QAE1D,0DAA0D;;;kBAY1D,CAAC;AAEH,MAAM,MAAM,mBAAmB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,mBAAmB,CAAC,CAAC;AACtE,MAAM,MAAM,eAAe,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,qBAAqB,CAAC,CAAC;AAEpE,OAAO,QAAQ,yBAAyB,CAAC;IACvC,UAAU,WAAW;QACnB,SAAS,CAAC,EAAE,eAAe,CAAC;KAC7B;CACF;AAED;;;;;;;;GAQG;AACH,MAAM,MAAM,wBAAwB,GAAG,WAAW,CAAC,WAAW,CAAC,WAAW,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Live observation for declared terraform entities (#2087).
|
|
3
|
+
*
|
|
4
|
+
* `buildRoots()` turns each configured root module into one entity per HCL
|
|
5
|
+
* block, keyed `<root>/<address>` (`./hcl/parse.ts`). This reader answers the
|
|
6
|
+
* lifecycle question for those entities by running `terraform show -json` over
|
|
7
|
+
* the root's current state and matching addresses.
|
|
8
|
+
*
|
|
9
|
+
* ## The state file is the ownership answer
|
|
10
|
+
*
|
|
11
|
+
* Every other lexicon in chant stamps a tag or a label at synthesis and reads
|
|
12
|
+
* it back off the live resource. Terraform stamps nothing, and there is
|
|
13
|
+
* nowhere to stamp: a resource's provider-side tags are the practitioner's
|
|
14
|
+
* own, and writing chant's marker into them would edit an estate this lexicon
|
|
15
|
+
* promises never to write. What terraform has instead is the thing chant
|
|
16
|
+
* elsewhere refuses to host, a trusted state file that already records
|
|
17
|
+
* exactly which addresses this configuration manages.
|
|
18
|
+
*
|
|
19
|
+
* So the answer here is state membership. An address `terraform show -json`
|
|
20
|
+
* returns is `owned`; anything else is `unknown`. Concretely that makes a
|
|
21
|
+
* declared `module` block `unknown`: the state carries the module's
|
|
22
|
+
* resources, never a row for the block itself, so chant can see the block is
|
|
23
|
+
* live without the state ever saying that block is managed. `unknown` never
|
|
24
|
+
* escalates to a delete, which is the correct posture for a thing chant did
|
|
25
|
+
* not read a verdict for.
|
|
26
|
+
*
|
|
27
|
+
* That places terraform on the trusted-state-file row of the third axis in
|
|
28
|
+
* docs/src/content/docs/concepts/lifecycle-models.mdx, where chant elsewhere
|
|
29
|
+
* sits on the live-marker row. `docs/pages/observation.mdx` is the reader's
|
|
30
|
+
* version of this paragraph.
|
|
31
|
+
*
|
|
32
|
+
* ## What is readable at all
|
|
33
|
+
*
|
|
34
|
+
* `values.root_module.resources[]` (and, recursively, `child_modules[]`)
|
|
35
|
+
* carries `resource` and `data` blocks. A `terraform`, `provider`, `variable`,
|
|
36
|
+
* `output` or `locals` block has no row there and reads `unsupported-kind`.
|
|
37
|
+
* That is honest, not a gap to close by inventing an address for something
|
|
38
|
+
* that has none.
|
|
39
|
+
*
|
|
40
|
+
* ## Tri-state (#1089)
|
|
41
|
+
*
|
|
42
|
+
* A root whose `init` or `show` fails reports EVERY entity declared in that
|
|
43
|
+
* root as not-observed with reason `read-failed` and the root named, never
|
|
44
|
+
* absent. A failed read must never render as a list of creates. Roots are
|
|
45
|
+
* read independently and merged (`mergeObservations`), so one broken backend
|
|
46
|
+
* does not un-observe a root that answered.
|
|
47
|
+
*
|
|
48
|
+
* ## Nothing from `values` is surfaced
|
|
49
|
+
*
|
|
50
|
+
* A state row's `values` are the resource's full attribute set, secrets
|
|
51
|
+
* included, and `sensitive_values` describes only what the configuration
|
|
52
|
+
* declared sensitive. So the attributes reported here are the row's identity
|
|
53
|
+
* (address, type, mode, provider, root) and nothing from `values` except the
|
|
54
|
+
* `id`, which is the physical id every observation carries.
|
|
55
|
+
*/
|
|
56
|
+
import type { DescribeResourcesResult } from "@intentius/chant/lexicon";
|
|
57
|
+
import { terraformInit, terraformShow } from "./op/activities/terraform.js";
|
|
58
|
+
export { TERRAFORM_STATE_OWNERSHIP_KEYS } from "./state-ownership.js";
|
|
59
|
+
/** One row out of `values.root_module.resources[]`, at any module depth. */
|
|
60
|
+
export interface StateResourceRow {
|
|
61
|
+
/** Fully qualified terraform address, `module.<name>.` prefixes included. */
|
|
62
|
+
address: string;
|
|
63
|
+
/** `managed` for a `resource` block, `data` for a `data` block. */
|
|
64
|
+
mode?: string;
|
|
65
|
+
/** Resource type, e.g. `null_resource`. */
|
|
66
|
+
type?: string;
|
|
67
|
+
/** Provider that owns the row, e.g. `registry.terraform.io/hashicorp/null`. */
|
|
68
|
+
providerName?: string;
|
|
69
|
+
/** `values.id`, when the row carries a string id. Nothing else from `values` is read. */
|
|
70
|
+
id?: string;
|
|
71
|
+
}
|
|
72
|
+
/** What one root's state read produced. */
|
|
73
|
+
export interface StateIndex {
|
|
74
|
+
/** Every resource/data row, keyed by fully qualified address. */
|
|
75
|
+
rows: Map<string, StateResourceRow>;
|
|
76
|
+
/** Every `module.<name>` address the state carries a child module for, at any depth. */
|
|
77
|
+
modules: Set<string>;
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Index a `terraform show -json` document by address.
|
|
81
|
+
*
|
|
82
|
+
* Terraform already writes fully qualified addresses inside `child_modules`
|
|
83
|
+
* (`module.cdn.null_resource.edge`, as `src/__fixtures__/show-state.json`
|
|
84
|
+
* records), so the module prefix is applied only when a row's own address is
|
|
85
|
+
* missing it. Belt and braces for an older `format_version`, never a second
|
|
86
|
+
* `module.cdn.` on top of the first.
|
|
87
|
+
*/
|
|
88
|
+
export declare function indexStateResources(showJson: unknown): StateIndex;
|
|
89
|
+
/**
|
|
90
|
+
* The ownership verdict for one declared address: `owned` when the state
|
|
91
|
+
* carries a row for it, `unknown` otherwise. Exported because it is the whole
|
|
92
|
+
* of terraform's ownership channel, and a channel with one rule deserves one
|
|
93
|
+
* function to point at.
|
|
94
|
+
*/
|
|
95
|
+
export declare function classifyStateOwnership(address: string, index: StateIndex): "owned" | "unknown";
|
|
96
|
+
/** The activity pair this reader drives. Injectable so tests never run terraform. */
|
|
97
|
+
export interface TerraformReadDeps {
|
|
98
|
+
init: typeof terraformInit;
|
|
99
|
+
show: typeof terraformShow;
|
|
100
|
+
}
|
|
101
|
+
export interface DescribeResourcesOptions {
|
|
102
|
+
environment: string;
|
|
103
|
+
buildOutput: string;
|
|
104
|
+
entityNames: string[];
|
|
105
|
+
entities: Map<string, {
|
|
106
|
+
entityType: string;
|
|
107
|
+
props: Record<string, unknown>;
|
|
108
|
+
}>;
|
|
109
|
+
/**
|
|
110
|
+
* Restrict to state-backed entities (#1348). A withheld entity is
|
|
111
|
+
* `filtered`, never a silent drop into `absent`: a live module block still
|
|
112
|
+
* exists, chant just has no state row saying it is managed.
|
|
113
|
+
*/
|
|
114
|
+
owned?: boolean;
|
|
115
|
+
/**
|
|
116
|
+
* Directory the activities start the `chant.config.*` search from. Default:
|
|
117
|
+
* the running process's cwd. Same meaning as `TerraformWatchOpConfig.cwd`.
|
|
118
|
+
*/
|
|
119
|
+
cwd?: string;
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Observe every declared terraform entity, one `init` + `show` per configured
|
|
123
|
+
* root. Roots are read independently, so a broken backend on one never
|
|
124
|
+
* un-observes another (`mergeObservations`).
|
|
125
|
+
*/
|
|
126
|
+
export declare function describeResources(options: DescribeResourcesOptions, deps?: TerraformReadDeps): Promise<DescribeResourcesResult>;
|
|
127
|
+
//# sourceMappingURL=describe-resources.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"describe-resources.d.ts","sourceRoot":"","sources":["../src/describe-resources.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsDG;AAEH,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,0BAA0B,CAAC;AAUxE,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAMzE,OAAO,EAAE,8BAA8B,EAAE,MAAM,mBAAmB,CAAC;AAEnE,4EAA4E;AAC5E,MAAM,WAAW,gBAAgB;IAC/B,6EAA6E;IAC7E,OAAO,EAAE,MAAM,CAAC;IAChB,mEAAmE;IACnE,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,2CAA2C;IAC3C,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,+EAA+E;IAC/E,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,yFAAyF;IACzF,EAAE,CAAC,EAAE,MAAM,CAAC;CACb;AAED,2CAA2C;AAC3C,MAAM,WAAW,UAAU;IACzB,iEAAiE;IACjE,IAAI,EAAE,GAAG,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAC;IACpC,wFAAwF;IACxF,OAAO,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;CACtB;AAgBD;;;;;;;;GAQG;AACH,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,OAAO,GAAG,UAAU,CA6BjE;AAED;;;;;GAKG;AACH,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,UAAU,GAAG,OAAO,GAAG,SAAS,CAE9F;AASD,qFAAqF;AACrF,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,OAAO,aAAa,CAAC;IAC3B,IAAI,EAAE,OAAO,aAAa,CAAC;CAC5B;AA+GD,MAAM,WAAW,wBAAwB;IACvC,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,QAAQ,EAAE,GAAG,CAAC,MAAM,EAAE;QAAE,UAAU,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;KAAE,CAAC,CAAC;IAC9E;;;;OAIG;IACH,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB;;;OAGG;IACH,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED;;;;GAIG;AACH,wBAAsB,iBAAiB,CACrC,OAAO,EAAE,wBAAwB,EACjC,IAAI,GAAE,iBAA6B,GAClC,OAAO,CAAC,uBAAuB,CAAC,CAgDlC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/generated/index.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,CAAC"}
|