@intentius/chant-lexicon-terraform 0.57.0 → 0.59.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 +9 -0
- package/dist/composites/terraform-adopt-op.d.ts +131 -0
- package/dist/composites/terraform-adopt-op.d.ts.map +1 -0
- package/dist/composites/terraform-apply-op.d.ts +70 -17
- package/dist/composites/terraform-apply-op.d.ts.map +1 -1
- package/dist/composites/terraform-watch-op.d.ts +104 -37
- package/dist/composites/terraform-watch-op.d.ts.map +1 -1
- package/dist/config.d.ts +49 -2
- package/dist/config.d.ts.map +1 -1
- package/dist/describe-resources.d.ts +256 -16
- package/dist/describe-resources.d.ts.map +1 -1
- package/dist/hcl/descend.d.ts +98 -0
- package/dist/hcl/descend.d.ts.map +1 -0
- package/dist/hcl/marker.d.ts +130 -0
- package/dist/hcl/marker.d.ts.map +1 -0
- package/dist/hcl/parse.d.ts +156 -9
- package/dist/hcl/parse.d.ts.map +1 -1
- package/dist/hcl/references.d.ts +76 -0
- package/dist/hcl/references.d.ts.map +1 -0
- package/dist/hcl/roots.d.ts +22 -3
- package/dist/hcl/roots.d.ts.map +1 -1
- package/dist/hcl/suppressions.d.ts +54 -0
- package/dist/hcl/suppressions.d.ts.map +1 -0
- package/dist/hcl/value.d.ts +77 -0
- package/dist/hcl/value.d.ts.map +1 -0
- package/dist/index.d.ts +5 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/integrity.json +34 -5
- package/dist/lint/audit-catalog.d.ts +3 -2
- package/dist/lint/audit-catalog.d.ts.map +1 -1
- package/dist/lint/audit-lineage.d.ts +95 -0
- package/dist/lint/audit-lineage.d.ts.map +1 -1
- package/dist/lint/post-synth/blocks.d.ts +53 -0
- package/dist/lint/post-synth/blocks.d.ts.map +1 -0
- package/dist/lint/post-synth/fixtures/load.d.ts +37 -0
- package/dist/lint/post-synth/fixtures/load.d.ts.map +1 -0
- package/dist/lint/post-synth/index.d.ts.map +1 -1
- package/dist/lint/post-synth/module-source.d.ts +38 -0
- package/dist/lint/post-synth/module-source.d.ts.map +1 -0
- package/dist/lint/post-synth/scope.d.ts +65 -0
- package/dist/lint/post-synth/scope.d.ts.map +1 -0
- package/dist/lint/post-synth/tf001.d.ts +58 -6
- package/dist/lint/post-synth/tf001.d.ts.map +1 -1
- package/dist/lint/post-synth/tf002.d.ts +32 -0
- package/dist/lint/post-synth/tf002.d.ts.map +1 -0
- package/dist/lint/post-synth/tf003.d.ts +22 -0
- package/dist/lint/post-synth/tf003.d.ts.map +1 -0
- package/dist/lint/post-synth/tf004.d.ts +22 -0
- package/dist/lint/post-synth/tf004.d.ts.map +1 -0
- package/dist/lint/post-synth/tf005.d.ts +28 -0
- package/dist/lint/post-synth/tf005.d.ts.map +1 -0
- package/dist/lint/post-synth/tf006.d.ts +21 -0
- package/dist/lint/post-synth/tf006.d.ts.map +1 -0
- package/dist/lint/post-synth/tf007.d.ts +21 -0
- package/dist/lint/post-synth/tf007.d.ts.map +1 -0
- package/dist/lint/post-synth/tf008.d.ts +22 -0
- package/dist/lint/post-synth/tf008.d.ts.map +1 -0
- package/dist/lint/post-synth/tf009.d.ts +24 -0
- package/dist/lint/post-synth/tf009.d.ts.map +1 -0
- package/dist/lint/post-synth/tf010.d.ts +19 -0
- package/dist/lint/post-synth/tf010.d.ts.map +1 -0
- package/dist/lint/post-synth/tf011.d.ts +18 -0
- package/dist/lint/post-synth/tf011.d.ts.map +1 -0
- package/dist/lint/post-synth/tf012.d.ts +17 -0
- package/dist/lint/post-synth/tf012.d.ts.map +1 -0
- package/dist/lint/post-synth/tf013.d.ts +21 -0
- package/dist/lint/post-synth/tf013.d.ts.map +1 -0
- package/dist/lint/post-synth/tf014.d.ts +25 -0
- package/dist/lint/post-synth/tf014.d.ts.map +1 -0
- package/dist/lint/post-synth/tf015.d.ts +30 -0
- package/dist/lint/post-synth/tf015.d.ts.map +1 -0
- package/dist/lint/post-synth/tf016.d.ts +30 -0
- package/dist/lint/post-synth/tf016.d.ts.map +1 -0
- package/dist/lint/post-synth/tf017.d.ts +19 -0
- package/dist/lint/post-synth/tf017.d.ts.map +1 -0
- package/dist/lint/post-synth/tf018.d.ts +20 -0
- package/dist/lint/post-synth/tf018.d.ts.map +1 -0
- package/dist/lint/post-synth/tf019.d.ts +25 -0
- package/dist/lint/post-synth/tf019.d.ts.map +1 -0
- package/dist/lint/post-synth/tf020.d.ts +38 -0
- package/dist/lint/post-synth/tf020.d.ts.map +1 -0
- package/dist/lint/post-synth/tf021.d.ts +41 -0
- package/dist/lint/post-synth/tf021.d.ts.map +1 -0
- package/dist/lint/post-synth/tf022.d.ts +24 -0
- package/dist/lint/post-synth/tf022.d.ts.map +1 -0
- package/dist/lint/post-synth/tf024.d.ts +24 -0
- package/dist/lint/post-synth/tf024.d.ts.map +1 -0
- package/dist/lint/post-synth/tf025.d.ts +29 -0
- package/dist/lint/post-synth/tf025.d.ts.map +1 -0
- package/dist/lint/post-synth/tf026.d.ts +28 -0
- package/dist/lint/post-synth/tf026.d.ts.map +1 -0
- package/dist/lint/post-synth/tf027.d.ts +30 -0
- package/dist/lint/post-synth/tf027.d.ts.map +1 -0
- package/dist/lint/post-synth/tf028.d.ts +33 -0
- package/dist/lint/post-synth/tf028.d.ts.map +1 -0
- package/dist/lint/rules/fixtures/load.d.ts +13 -0
- package/dist/lint/rules/fixtures/load.d.ts.map +1 -0
- package/dist/lint/rules/plan-before-apply.d.ts +11 -0
- package/dist/lint/rules/plan-before-apply.d.ts.map +1 -1
- package/dist/lint/secret-shape.d.ts +68 -0
- package/dist/lint/secret-shape.d.ts.map +1 -0
- package/dist/live-ownership.d.ts +55 -0
- package/dist/live-ownership.d.ts.map +1 -0
- package/dist/lsp/option-keys.d.ts.map +1 -1
- package/dist/manifest.json +1 -1
- package/dist/okf/index.md +26 -0
- package/dist/okf/rules/TF002.md +11 -0
- package/dist/okf/rules/TF003.md +11 -0
- package/dist/okf/rules/TF004.md +11 -0
- package/dist/okf/rules/TF005.md +11 -0
- package/dist/okf/rules/TF006.md +11 -0
- package/dist/okf/rules/TF007.md +11 -0
- package/dist/okf/rules/TF008.md +11 -0
- package/dist/okf/rules/TF009.md +11 -0
- package/dist/okf/rules/TF010.md +11 -0
- package/dist/okf/rules/TF011.md +11 -0
- package/dist/okf/rules/TF012.md +11 -0
- package/dist/okf/rules/TF013.md +11 -0
- package/dist/okf/rules/TF014.md +11 -0
- package/dist/okf/rules/TF015.md +11 -0
- package/dist/okf/rules/TF016.md +11 -0
- package/dist/okf/rules/TF017.md +11 -0
- package/dist/okf/rules/TF018.md +11 -0
- package/dist/okf/rules/TF019.md +11 -0
- package/dist/okf/rules/TF020.md +11 -0
- package/dist/okf/rules/TF021.md +11 -0
- package/dist/okf/rules/TF022.md +11 -0
- package/dist/okf/rules/TF024.md +11 -0
- package/dist/okf/rules/TF025.md +11 -0
- package/dist/okf/rules/TF026.md +11 -0
- package/dist/okf/rules/TF027.md +11 -0
- package/dist/okf/rules/TF028.md +11 -0
- package/dist/op/activities/index.d.ts +13 -6
- package/dist/op/activities/index.d.ts.map +1 -1
- package/dist/op/activities/live-detect.d.ts +51 -0
- package/dist/op/activities/live-detect.d.ts.map +1 -0
- package/dist/op/activities/terraform.d.ts +466 -17
- package/dist/op/activities/terraform.d.ts.map +1 -1
- package/dist/op/activity-contracts.d.ts +148 -0
- package/dist/op/activity-contracts.d.ts.map +1 -0
- package/dist/op/adoption.d.ts +118 -0
- package/dist/op/adoption.d.ts.map +1 -0
- package/dist/op/builders.d.ts +48 -6
- package/dist/op/builders.d.ts.map +1 -1
- package/dist/op/resolve-root-mode.d.ts +59 -0
- package/dist/op/resolve-root-mode.d.ts.map +1 -0
- package/dist/plugin.d.ts.map +1 -1
- package/dist/rules/blocks.ts +109 -0
- package/dist/rules/module-source.ts +121 -0
- package/dist/rules/plan-before-apply.ts +11 -0
- package/dist/rules/scope.ts +107 -0
- package/dist/rules/tf001.ts +98 -18
- package/dist/rules/tf002.ts +151 -0
- package/dist/rules/tf003.ts +71 -0
- package/dist/rules/tf004.ts +63 -0
- package/dist/rules/tf005.ts +76 -0
- package/dist/rules/tf006.ts +53 -0
- package/dist/rules/tf007.ts +78 -0
- package/dist/rules/tf008.ts +75 -0
- package/dist/rules/tf009.ts +59 -0
- package/dist/rules/tf010.ts +51 -0
- package/dist/rules/tf011.ts +49 -0
- package/dist/rules/tf012.ts +47 -0
- package/dist/rules/tf013.ts +63 -0
- package/dist/rules/tf014.ts +72 -0
- package/dist/rules/tf015.ts +72 -0
- package/dist/rules/tf016.ts +75 -0
- package/dist/rules/tf017.ts +50 -0
- package/dist/rules/tf018.ts +72 -0
- package/dist/rules/tf019.ts +72 -0
- package/dist/rules/tf020.ts +123 -0
- package/dist/rules/tf021.ts +126 -0
- package/dist/rules/tf022.ts +61 -0
- package/dist/rules/tf024.ts +70 -0
- package/dist/rules/tf025.ts +101 -0
- package/dist/rules/tf026.ts +84 -0
- package/dist/rules/tf027.ts +74 -0
- package/dist/rules/tf028.ts +96 -0
- package/dist/skills/chant-terraform.md +1 -1
- package/dist/validate.d.ts.map +1 -1
- package/package.json +7 -2
- package/src/__fixtures__/ACCEPTANCE.md +181 -0
- package/src/__fixtures__/live/main.tf +28 -0
- package/src/__fixtures__/live-adopt/estate.chdf.hcl +6 -0
- package/src/__fixtures__/live-adopt/main.tf +21 -0
- package/src/__fixtures__/live-estate/README.md +58 -0
- package/src/__fixtures__/live-estate/compute.tf +10 -0
- package/src/__fixtures__/live-estate/estate.chdf.hcl +1 -0
- package/src/__fixtures__/live-estate/logs.tf +8 -0
- package/src/__fixtures__/live-estate/network.tf +24 -0
- package/src/__fixtures__/live-estate/rule.tf +11 -0
- package/src/__fixtures__/live-estate/unowned.tf +21 -0
- package/src/__fixtures__/live-estate/versions.tf +31 -0
- package/src/__fixtures__/live-ls.json +98 -0
- package/src/__fixtures__/live-plan.json +285 -0
- package/src/__fixtures__/live-sidecar/estate.chdf.hcl +3 -0
- package/src/__fixtures__/live-sidecar/main.tf +24 -0
- package/src/__fixtures__/module-tree/README.md +16 -0
- package/src/__fixtures__/module-tree/cycle/main.tf +3 -0
- package/src/__fixtures__/module-tree/cycle/modules/a/main.tf +9 -0
- package/src/__fixtures__/module-tree/cycle/modules/b/main.tf +9 -0
- package/src/__fixtures__/module-tree/missing/main.tf +9 -0
- package/src/__fixtures__/module-tree/outside/root/main.tf +9 -0
- package/src/__fixtures__/module-tree/root/main.tf +28 -0
- package/src/__fixtures__/module-tree/root/modules/cdn/main.tf +15 -0
- package/src/__fixtures__/module-tree/root/modules/cdn/modules/bucket/main.tf +11 -0
- package/src/__fixtures__/module-tree/shared/main.tf +5 -0
- package/src/__fixtures__/references/main.tf +56 -0
- package/src/__fixtures__/remote-backend/main.tf +34 -0
- package/src/__fixtures__/with-backend/main.tf +7 -0
- package/src/codegen/lint-rules-page.test.ts +45 -0
- package/src/composites/terraform-adopt-op.acceptance.test.ts +193 -0
- package/src/composites/terraform-adopt-op.test.ts +175 -0
- package/src/composites/terraform-adopt-op.ts +202 -0
- package/src/composites/terraform-apply-op.acceptance.test.ts +188 -5
- package/src/composites/terraform-apply-op.test.ts +179 -19
- package/src/composites/terraform-apply-op.ts +123 -30
- package/src/composites/terraform-watch-op.test.ts +169 -29
- package/src/composites/terraform-watch-op.ts +183 -75
- package/src/config.ts +32 -3
- package/src/describe-resources.live.test.ts +598 -0
- package/src/describe-resources.test.ts +53 -0
- package/src/describe-resources.ts +811 -28
- package/src/hcl/descend.test.ts +162 -0
- package/src/hcl/descend.ts +273 -0
- package/src/hcl/marker.test.ts +147 -0
- package/src/hcl/marker.ts +235 -0
- package/src/hcl/parse.test.ts +69 -0
- package/src/hcl/parse.ts +269 -27
- package/src/hcl/references.test.ts +116 -0
- package/src/hcl/references.ts +172 -0
- package/src/hcl/roots.ts +59 -5
- package/src/hcl/suppressions.test.ts +147 -0
- package/src/hcl/suppressions.ts +204 -0
- package/src/hcl/value.test.ts +73 -0
- package/src/hcl/value.ts +106 -0
- package/src/index.ts +31 -1
- package/src/lint/audit-catalog.ts +288 -3
- package/src/lint/audit-lineage.ts +384 -1
- package/src/lint/audit.test.ts +210 -3
- package/src/lint/post-synth/blocks.ts +109 -0
- package/src/lint/post-synth/fixtures/TF001/negative-cloud.tf +28 -0
- package/src/lint/post-synth/fixtures/TF001/negative.tf +30 -0
- package/src/lint/post-synth/fixtures/TF001/positive-local.tf +31 -0
- package/src/lint/post-synth/fixtures/TF001/positive.tf +24 -0
- package/src/lint/post-synth/fixtures/TF002/negative.tf +17 -0
- package/src/lint/post-synth/fixtures/TF002/positive-legacy.tf +10 -0
- package/src/lint/post-synth/fixtures/TF002/positive-no-version.tf +12 -0
- package/src/lint/post-synth/fixtures/TF002/positive.tf +7 -0
- package/src/lint/post-synth/fixtures/TF003/negative.tf +10 -0
- package/src/lint/post-synth/fixtures/TF003/positive.tf +8 -0
- package/src/lint/post-synth/fixtures/TF004/negative-git.tf +3 -0
- package/src/lint/post-synth/fixtures/TF004/negative-local.tf +3 -0
- package/src/lint/post-synth/fixtures/TF004/negative.tf +4 -0
- package/src/lint/post-synth/fixtures/TF004/positive.tf +3 -0
- package/src/lint/post-synth/fixtures/TF005/negative-local.tf +3 -0
- package/src/lint/post-synth/fixtures/TF005/negative-registry.tf +3 -0
- package/src/lint/post-synth/fixtures/TF005/negative-sha.tf +3 -0
- package/src/lint/post-synth/fixtures/TF005/negative.tf +3 -0
- package/src/lint/post-synth/fixtures/TF005/positive-branch.tf +3 -0
- package/src/lint/post-synth/fixtures/TF005/positive-non-semver.tf +3 -0
- package/src/lint/post-synth/fixtures/TF005/positive.tf +3 -0
- package/src/lint/post-synth/fixtures/TF006/negative.tf +5 -0
- package/src/lint/post-synth/fixtures/TF006/positive-empty-default.tf +11 -0
- package/src/lint/post-synth/fixtures/TF006/positive.tf +6 -0
- package/src/lint/post-synth/fixtures/TF007/negative.tf +10 -0
- package/src/lint/post-synth/fixtures/TF007/positive.tf +9 -0
- package/src/lint/post-synth/fixtures/TF008/negative-variable.tf +10 -0
- package/src/lint/post-synth/fixtures/TF008/negative.tf +8 -0
- package/src/lint/post-synth/fixtures/TF008/positive-other-provider.tf +10 -0
- package/src/lint/post-synth/fixtures/TF008/positive.tf +5 -0
- package/src/lint/post-synth/fixtures/TF009/negative.tf +10 -0
- package/src/lint/post-synth/fixtures/TF009/positive.tf +4 -0
- package/src/lint/post-synth/fixtures/TF010/negative.tf +5 -0
- package/src/lint/post-synth/fixtures/TF010/positive.tf +4 -0
- package/src/lint/post-synth/fixtures/TF011/negative.tf +5 -0
- package/src/lint/post-synth/fixtures/TF011/positive-blank.tf +5 -0
- package/src/lint/post-synth/fixtures/TF011/positive.tf +4 -0
- package/src/lint/post-synth/fixtures/TF012/negative.tf +4 -0
- package/src/lint/post-synth/fixtures/TF012/positive.tf +3 -0
- package/src/lint/post-synth/fixtures/TF013/negative.tf +8 -0
- package/src/lint/post-synth/fixtures/TF013/positive-data.tf +8 -0
- package/src/lint/post-synth/fixtures/TF013/positive.tf +8 -0
- package/src/lint/post-synth/fixtures/TF014/negative/main.tf +26 -0
- package/src/lint/post-synth/fixtures/TF014/negative/modules/cdn/main.tf +19 -0
- package/src/lint/post-synth/fixtures/TF014/positive/main.tf +16 -0
- package/src/lint/post-synth/fixtures/TF014/positive/modules/cdn/main.tf +15 -0
- package/src/lint/post-synth/fixtures/TF015/negative/main.tf +13 -0
- package/src/lint/post-synth/fixtures/TF015/negative/modules/cdn/main.tf +16 -0
- package/src/lint/post-synth/fixtures/TF015/positive/main.tf +13 -0
- package/src/lint/post-synth/fixtures/TF015/positive/modules/cdn/main.tf +14 -0
- package/src/lint/post-synth/fixtures/TF016/negative-template.tf +7 -0
- package/src/lint/post-synth/fixtures/TF016/negative.tf +16 -0
- package/src/lint/post-synth/fixtures/TF016/positive-shared-file.tf +12 -0
- package/src/lint/post-synth/fixtures/TF016/positive.tf +13 -0
- package/src/lint/post-synth/fixtures/TF017/negative.tf +4 -0
- package/src/lint/post-synth/fixtures/TF017/positive.tf +5 -0
- package/src/lint/post-synth/fixtures/TF018/negative.tf +9 -0
- package/src/lint/post-synth/fixtures/TF018/positive-data.tf +9 -0
- package/src/lint/post-synth/fixtures/TF018/positive.tf +4 -0
- package/src/lint/post-synth/fixtures/TF019/negative.tf +14 -0
- package/src/lint/post-synth/fixtures/TF019/positive-output.tf +5 -0
- package/src/lint/post-synth/fixtures/TF019/positive.tf +16 -0
- package/src/lint/post-synth/fixtures/TF020/negative.tf +43 -0
- package/src/lint/post-synth/fixtures/TF020/positive.tf +32 -0
- package/src/lint/post-synth/fixtures/TF020/scoped/main.tf +21 -0
- package/src/lint/post-synth/fixtures/TF020/scoped/modules/cdn/main.tf +13 -0
- package/src/lint/post-synth/fixtures/TF021/negative.tf +31 -0
- package/src/lint/post-synth/fixtures/TF021/positive-length.tf +8 -0
- package/src/lint/post-synth/fixtures/TF021/positive.tf +8 -0
- package/src/lint/post-synth/fixtures/TF022/negative-locator.tf +7 -0
- package/src/lint/post-synth/fixtures/TF022/negative.tf +10 -0
- package/src/lint/post-synth/fixtures/TF022/positive-nested.tf +10 -0
- package/src/lint/post-synth/fixtures/TF022/positive.tf +6 -0
- package/src/lint/post-synth/fixtures/TF023/negative/main.tf +15 -0
- package/src/lint/post-synth/fixtures/TF023/positive/main.tf +9 -0
- package/src/lint/post-synth/fixtures/TF023/positive/state.json +24 -0
- package/src/lint/post-synth/fixtures/TF024/live-clean/main.tf +9 -0
- package/src/lint/post-synth/fixtures/TF024/live-with-backend/main.tf +14 -0
- package/src/lint/post-synth/fixtures/TF024/live-with-cloud/main.tf +16 -0
- package/src/lint/post-synth/fixtures/TF025/live-clean/main.tf +13 -0
- package/src/lint/post-synth/fixtures/TF025/live-with-workspace-ref/main.tf +13 -0
- package/src/lint/post-synth/fixtures/TF026/live-default/main.tf +9 -0
- package/src/lint/post-synth/fixtures/TF026/live-explicit-delete/main.tf +13 -0
- package/src/lint/post-synth/fixtures/TF026/live-keep/main.tf +13 -0
- package/src/lint/post-synth/fixtures/TF027/live-default/main.tf +9 -0
- package/src/lint/post-synth/fixtures/TF027/live-untagged-delete/main.tf +13 -0
- package/src/lint/post-synth/fixtures/TF027/live-untagged-delete-scoped/main.tf +17 -0
- package/src/lint/post-synth/fixtures/TF027/live-untagged-report/main.tf +13 -0
- package/src/lint/post-synth/fixtures/TF028/live/main.tf +9 -0
- package/src/lint/post-synth/fixtures/TF028/stock/main.tf +10 -0
- package/src/lint/post-synth/fixtures/load.ts +108 -0
- package/src/lint/post-synth/index.ts +52 -0
- package/src/lint/post-synth/live-refusals-config-format.test.ts +143 -0
- package/src/lint/post-synth/module-rules.test.ts +153 -0
- package/src/lint/post-synth/module-source.test.ts +75 -0
- package/src/lint/post-synth/module-source.ts +121 -0
- package/src/lint/post-synth/post-synth.test.ts +73 -16
- package/src/lint/post-synth/scope.ts +107 -0
- package/src/lint/post-synth/single-block.test.ts +263 -0
- package/src/lint/post-synth/suppression.test.ts +110 -0
- package/src/lint/post-synth/tf001.ts +98 -18
- package/src/lint/post-synth/tf002.test.ts +93 -0
- package/src/lint/post-synth/tf002.ts +151 -0
- package/src/lint/post-synth/tf003.test.ts +75 -0
- package/src/lint/post-synth/tf003.ts +71 -0
- package/src/lint/post-synth/tf004.test.ts +47 -0
- package/src/lint/post-synth/tf004.ts +63 -0
- package/src/lint/post-synth/tf005.test.ts +57 -0
- package/src/lint/post-synth/tf005.ts +76 -0
- package/src/lint/post-synth/tf006.ts +53 -0
- package/src/lint/post-synth/tf007.ts +78 -0
- package/src/lint/post-synth/tf008.ts +75 -0
- package/src/lint/post-synth/tf009.ts +59 -0
- package/src/lint/post-synth/tf010.ts +51 -0
- package/src/lint/post-synth/tf011.ts +49 -0
- package/src/lint/post-synth/tf012.ts +47 -0
- package/src/lint/post-synth/tf013.ts +63 -0
- package/src/lint/post-synth/tf014.ts +72 -0
- package/src/lint/post-synth/tf015.ts +72 -0
- package/src/lint/post-synth/tf016.ts +75 -0
- package/src/lint/post-synth/tf017.ts +50 -0
- package/src/lint/post-synth/tf018.ts +72 -0
- package/src/lint/post-synth/tf019.ts +72 -0
- package/src/lint/post-synth/tf020.ts +123 -0
- package/src/lint/post-synth/tf021.ts +126 -0
- package/src/lint/post-synth/tf022.ts +61 -0
- package/src/lint/post-synth/tf024.test.ts +42 -0
- package/src/lint/post-synth/tf024.ts +70 -0
- package/src/lint/post-synth/tf025.test.ts +46 -0
- package/src/lint/post-synth/tf025.ts +101 -0
- package/src/lint/post-synth/tf026.test.ts +56 -0
- package/src/lint/post-synth/tf026.ts +84 -0
- package/src/lint/post-synth/tf027.test.ts +62 -0
- package/src/lint/post-synth/tf027.ts +74 -0
- package/src/lint/post-synth/tf028.test.ts +92 -0
- package/src/lint/post-synth/tf028.ts +96 -0
- package/src/lint/presets.test.ts +72 -0
- package/src/lint/rules/fixtures/TF101/negative-op.ts +2 -0
- package/src/lint/rules/fixtures/TF101/positive-op.ts +2 -0
- package/src/lint/rules/fixtures/load.ts +53 -0
- package/src/lint/rules/plan-before-apply.test.ts +112 -7
- package/src/lint/rules/plan-before-apply.ts +11 -0
- package/src/lint/secret-shape.test.ts +150 -0
- package/src/lint/secret-shape.ts +159 -0
- package/src/live-ownership.ts +60 -0
- package/src/lsp/completions.test.ts +3 -2
- package/src/lsp/option-keys.ts +12 -6
- package/src/op/activities/choudoufu.acceptance.test.ts +127 -0
- package/src/op/activities/choudoufu.test.ts +725 -0
- package/src/op/activities/index.ts +40 -4
- package/src/op/activities/live-detect.test.ts +143 -0
- package/src/op/activities/live-detect.ts +162 -0
- package/src/op/activities/registry.test.ts +11 -3
- package/src/op/activities/terraform.test.ts +7 -3
- package/src/op/activities/terraform.ts +861 -69
- package/src/op/activity-contracts.test.ts +147 -0
- package/src/op/activity-contracts.ts +178 -0
- package/src/op/adoption.test.ts +170 -0
- package/src/op/adoption.ts +241 -0
- package/src/op/builders.test.ts +60 -5
- package/src/op/builders.ts +95 -5
- package/src/op/resolve-root-mode.test.ts +85 -0
- package/src/op/resolve-root-mode.ts +86 -0
- package/src/plugin.test.ts +106 -0
- package/src/plugin.ts +186 -29
- package/src/skills/chant-terraform.md +1 -1
- package/src/validate.ts +10 -1
|
@@ -15,6 +15,101 @@
|
|
|
15
15
|
* `terraform_workspace_remote` (a `terraform.workspace` compatibility check
|
|
16
16
|
* against remote execution, a different condition than "no backend is
|
|
17
17
|
* configured at all"). Ship with no lineage rather than invent a credit.
|
|
18
|
+
*
|
|
19
|
+
* TF101 (plan-before-apply, `lint/rules/plan-before-apply.ts`) is a source-level
|
|
20
|
+
* lint rule over chant's own Op builders, not a post-synth check, so it carries
|
|
21
|
+
* no `RuleMeta`/`Lineage` entry here at all: this file's `Record` only ever
|
|
22
|
+
* keys post-synth check ids. Its own page section (docs/pages/lint-rules.mdx)
|
|
23
|
+
* says the same thing directly: no tool anywhere models "this plan file traces
|
|
24
|
+
* back to a specific preceding plan step", because that is a question about
|
|
25
|
+
* chant's own DSL, not about a Terraform root.
|
|
26
|
+
*
|
|
27
|
+
* ## The survey registry
|
|
28
|
+
*
|
|
29
|
+
* #2107 ran three research passes over every serious Terraform lint, scan and
|
|
30
|
+
* policy tool (1,888 lines, 222 cited URLs, attached to that issue as
|
|
31
|
+
* comments). The tools and documents below are what the survey found worth
|
|
32
|
+
* crediting from across that research. #2108 added none of them to
|
|
33
|
+
* `PRIOR_ART`: `packages/core/src/audit/catalog.test.ts`'s "every registered
|
|
34
|
+
* tool is credited" test fails on an entry no shipped rule cites yet, and
|
|
35
|
+
* neither TF001 nor TF101 cites anything. #2109 (TF002-TF005) is the first to
|
|
36
|
+
* draw from this list: `tflint-ruleset-terraform`, `terraform-sentinel-policies`,
|
|
37
|
+
* `hashicorp-style-guide` and `aws-terraform-prescriptive-guidance` are now in
|
|
38
|
+
* `PRIOR_ART`, spelled exactly as below. `checkov` and `kics` were already
|
|
39
|
+
* registered (other lexicons cite them); TF004 and TF005 are the first
|
|
40
|
+
* Terraform rules to. Each later rule issue adds the remaining entries it
|
|
41
|
+
* needs the first time a shipped rule cites them: #2112 (TF014, TF015, TF020,
|
|
42
|
+
* TF021) added `gcp-terraform-best-practices`, the last row of the table below
|
|
43
|
+
* that no shipped rule had cited yet.
|
|
44
|
+
*
|
|
45
|
+
* Each row's Sweep note says whether `scripts/prior-art-sweep.ts` can index the
|
|
46
|
+
* source and, when it cannot, why (#2219). Five of these are indexed as of
|
|
47
|
+
* 2026-09-07: the three tflint rulesets, tfsec and the Sentinel policy set,
|
|
48
|
+
* 311 upstream rule ids in `scripts/prior-art/snapshot.json`. The rest are
|
|
49
|
+
* prose or code, so the tools they credit are re-read by hand when their
|
|
50
|
+
* documents change.
|
|
51
|
+
*
|
|
52
|
+
* | Key | Name | URL | Licence | Kind | Note |
|
|
53
|
+
* |---|---|---|---|---|---|
|
|
54
|
+
* | `tflint` | tflint | https://github.com/terraform-linters/tflint | MPL-2.0 (its `terraform` package is BUSL-1.1; binaries are bound by both) | scanner | The plugin host; ships no language rules of its own. Sweep: not registered in `PRIOR_ART` (no rule cites it), so it is not swept. |
|
|
55
|
+
* | `tflint-ruleset-terraform` | tflint-ruleset-terraform | https://github.com/terraform-linters/tflint-ruleset-terraform | MPL-2.0 | scanner | The official language-level ruleset, bundled into tflint. Sweep: indexed from `docs/rules/README.md`, whose table links each rule's page (20 rules). |
|
|
56
|
+
* | `tflint-ruleset-redeploy` | tflint-ruleset-redeploy | https://github.com/RedeployAB/tflint-ruleset-redeploy | 0BSD | scanner | Community ruleset; richest source of language-level rules outside the official set. Sweep: indexed from `docs/rules/README.md`, same table shape (33 rules). |
|
|
57
|
+
* | `tflint-ruleset-avm` | tflint-ruleset-avm | https://github.com/Azure/tflint-ruleset-avm | MIT | scanner | Azure Verified Modules conformance; two of its 33 rules are provider-agnostic. Sweep: indexed from the repository-root `RULES.md`, since `docs/` holds pages for only two rules (33 rules). |
|
|
58
|
+
* | `tfsec` | tfsec | https://github.com/aquasecurity/tfsec | MIT | scanner | Historical: not archived but effectively frozen (no release since 2025-05); its docs site 404s above v0.61.x, so cite pinned repository paths (`github.com/aquasecurity/tfsec/blob/master/docs/checks/...`), not the docs site. Sweep: indexed from the root `rules.md` on `master`, a flat table of all 152 check ids, because `docs/checks` nests a directory per provider, service and check. |
|
|
59
|
+
* | `trivy-checks` | trivy-checks | https://github.com/aquasecurity/trivy-checks | MIT (not the trivy scanner's own Apache-2.0; cite the checks repo's licence, not the engine's) | scanner | Where tfsec's rules live today (tfsec -> defsec -> trivy + trivy-checks). Cite rules by `long_id` (stable, human-readable); `AVD-*` ids are aliases now. Sweep: not registered in `PRIOR_ART` (no rule cites it yet) and its `long_id`s live in Rego metadata under `checks/<kind>/<provider>/<service>/`, with no flat index. |
|
|
60
|
+
* | `terraform-sentinel-policies` | HashiCorp reference Sentinel policies | https://github.com/hashicorp/terraform-sentinel-policies | MPL-2.0 | specification | HashiCorp's own example policy set; ships zero rules baked into HCP Terraform itself, so treat a cited policy as a documented pattern (`specification`) unless a future entry runs it as a real check (`scanner`); the `kind` union allows either. Sweep: indexed by listing the five per-cloud directories, whose `.sentinel` filenames are the policy ids credits cite (73 policies); the repository publishes no index page. |
|
|
61
|
+
* | `choudoufu` | choudoufu | https://github.com/INTENTIUS/choudoufu | MPL-2.0 | scanner | Its `internal/live/lint` package; experimental, AWS-only. Sweep: unsweepable, its rule ids are Go constants in `internal/live/lint/issue.go` and it publishes no rule index. |
|
|
62
|
+
* | `hashicorp-style-guide` | HashiCorp Terraform style guide | https://developer.hashicorp.com/terraform/language/style | n/a | specification | Sweep: unsweepable, one prose page of recommendations with no rule ids; a credit quotes the sentence and links its fragment. |
|
|
63
|
+
* | `gcp-terraform-best-practices` | Google Cloud Terraform best-practices series | https://docs.cloud.google.com/docs/terraform/best-practices/general-style-structure | n/a | specification | A multi-page series; cite the specific page's fragment. Sweep: unsweepable, prose across several pages with no rule ids. |
|
|
64
|
+
* | `aws-terraform-prescriptive-guidance` | AWS prescriptive guidance for Terraform | https://docs.aws.amazon.com/prescriptive-guidance/latest/terraform-aws-provider-best-practices/ | n/a | specification | Sweep: unsweepable, a prose guide whose sections carry headings rather than rule ids. |
|
|
65
|
+
*
|
|
66
|
+
* Deliberately excluded, per the survey: Terrascan and regula (both archived,
|
|
67
|
+
* do not build on dead projects); Snyk IaC (a product, not a rule source);
|
|
68
|
+
* semgrep (no SPDX id: its engine is LGPL-2.1 but its rules ship under the
|
|
69
|
+
* proprietary Semgrep Rules License v1.0, which forbids redistribution; cite
|
|
70
|
+
* it by name in prose if a rule's idea comes from it, never register it in
|
|
71
|
+
* `PRIOR_ART` with an SPDX licence). TF008 credits semgrep by name under that
|
|
72
|
+
* rule, so `PRIOR_ART` does carry the entry, with the licence spelled out
|
|
73
|
+
* rather than as an SPDX id. Sweep: unsweepable, the registry publishes no
|
|
74
|
+
* index and a rule id is the path of its YAML file under
|
|
75
|
+
* `terraform/<provider>/<category>/`, which no single directory listing covers.
|
|
76
|
+
*
|
|
77
|
+
* TF024 (#2103, live root declares a backend/cloud block) credits choudoufu's
|
|
78
|
+
* own `RuleStateBackend`, `internal/live/lint/issue.go` of
|
|
79
|
+
* github.com/INTENTIUS/choudoufu: the identical condition, checked the same
|
|
80
|
+
* way this fork checks it at `init` before any command runs. TF025 (a live
|
|
81
|
+
* root's non-default `terraform.workspace`) has no entry: its workspace half
|
|
82
|
+
* is refused at the CLI argument-parsing layer there
|
|
83
|
+
* (`internal/command/live_mode.go`), not by a dedicated lint rule under
|
|
84
|
+
* `internal/live/lint`, so there is no `Rule*` constant to point at.
|
|
85
|
+
*
|
|
86
|
+
* TF026 (#2106, a live root's `delete: "never"` against its `policy` block's
|
|
87
|
+
* `undeclared_tagged` verb) has no entry either, the same reason TF001 has
|
|
88
|
+
* none: choudoufu's own `internal/live/lint` package checks a policy block
|
|
89
|
+
* for internal validity (`RulePolicyVerb`: an unrecognized or wrong-quadrant
|
|
90
|
+
* verb; `RulePolicyScope`: `undeclared_untagged = "delete"` with no `scope`
|
|
91
|
+
* block), never against a `delete: "never" | "owned-only" | "gated"`
|
|
92
|
+
* classification, because choudoufu has no such classification — that
|
|
93
|
+
* vocabulary is chant's own, shared across lexicons (`lexicons/k8s/src/op/
|
|
94
|
+
* activities/kubectl.ts`'s `ApplyDeleteMode`, `packages/core/src/op/
|
|
95
|
+
* activities/apply.ts`'s `DeleteMode`), applied here to a tool that does not
|
|
96
|
+
* itself carry the concept. Ship with no lineage rather than invent a credit.
|
|
97
|
+
*
|
|
98
|
+
* TF027 (#2216, a live root's `policy` block setting `undeclared_untagged =
|
|
99
|
+
* "delete"`) does have one: choudoufu's `RulePolicyScope`
|
|
100
|
+
* (`internal/live/lint/policy.go`) refuses the same assignment, and issue #67
|
|
101
|
+
* there makes it a lint refusal rather than a default. The relation is
|
|
102
|
+
* `extends`, because choudoufu refuses it only when no `scope` block narrows
|
|
103
|
+
* the purge, while chant refuses it either way: a `scope` block bounds an
|
|
104
|
+
* account-wide sweep to a service, type or region, and every resource inside
|
|
105
|
+
* that boundary is still one this estate never marked. "Bounded" is not
|
|
106
|
+
* "owned", and owning it is the condition chant applies.
|
|
107
|
+
*
|
|
108
|
+
* TF028 (#2216, a live root watched by a `TerraformWatchOp` built without
|
|
109
|
+
* `live: true`) has no entry. It reads a chant Op's own configuration against
|
|
110
|
+
* a root's mode, and no surveyed tool has an Op model to read: choudoufu lints
|
|
111
|
+
* HCL, and every tflint ruleset, tfsec/trivy-checks and the Sentinel policies
|
|
112
|
+
* do the same. There is nothing upstream to credit.
|
|
18
113
|
*/
|
|
19
114
|
import type { Lineage } from "@intentius/chant/audit/catalog";
|
|
20
115
|
export declare const terraformAuditLineage: Record<string, Lineage[]>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"audit-lineage.d.ts","sourceRoot":"","sources":["../../src/lint/audit-lineage.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"audit-lineage.d.ts","sourceRoot":"","sources":["../../src/lint/audit-lineage.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgHG;AACH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,gCAAgC,CAAC;AAQ9D,eAAO,MAAM,qBAAqB,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,EAAE,CA0R3D,CAAC"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared reading helpers for the single-block post-synth checks (#2110).
|
|
3
|
+
*
|
|
4
|
+
* Thirteen of the fourteen rules in that issue do the same three things: pick
|
|
5
|
+
* the entities of one block type out of `ctx.entities`, read one attribute of
|
|
6
|
+
* each body, and report. This module is those three things, so a rule file is
|
|
7
|
+
* its condition and its message and nothing else. It exports no
|
|
8
|
+
* `PostSynthCheck`, so the generated barrel skips it (see
|
|
9
|
+
* `packages/core/src/codegen/generate-post-synth-barrel.ts`).
|
|
10
|
+
*/
|
|
11
|
+
import type { PostSynthContext } from "@intentius/chant/lint/post-synth";
|
|
12
|
+
import type { BlockBody } from "../../hcl/parse.js";
|
|
13
|
+
/** One parsed block, with the entity key the diagnostic reports against. */
|
|
14
|
+
export interface TerraformBlock {
|
|
15
|
+
/** `ctx.entities` key: `<root>/<address>`. */
|
|
16
|
+
key: string;
|
|
17
|
+
address: string;
|
|
18
|
+
body: BlockBody;
|
|
19
|
+
file: string;
|
|
20
|
+
root: string;
|
|
21
|
+
/** The raw text of the file this block came from (see `TerraformEntity.props`). */
|
|
22
|
+
source: string;
|
|
23
|
+
}
|
|
24
|
+
/** Every block of one entity type, in `ctx.entities` order. */
|
|
25
|
+
export declare function blocksOfType(ctx: PostSynthContext, entityType: string): TerraformBlock[];
|
|
26
|
+
/** Blocks of several types at once, in the order the types are given. */
|
|
27
|
+
export declare function blocksOfTypes(ctx: PostSynthContext, entityTypes: string[]): TerraformBlock[];
|
|
28
|
+
/** The name half of a `var.<name>` / `output.<name>` address. */
|
|
29
|
+
export declare function blockName(address: string): string;
|
|
30
|
+
/**
|
|
31
|
+
* The bodies of a nested block (`lifecycle`, `validation`, a provider's
|
|
32
|
+
* `assume_role`). hcl2json encodes a repeatable block as an array of bodies
|
|
33
|
+
* and a singleton as a bare object, so both are normalized to an array here.
|
|
34
|
+
*/
|
|
35
|
+
export declare function nestedBodies(body: BlockBody, key: string): BlockBody[];
|
|
36
|
+
/** Is this attribute value a string that says nothing? */
|
|
37
|
+
export declare function isBlank(value: unknown): boolean;
|
|
38
|
+
/** One scalar attribute found by {@link walkAttributes}. */
|
|
39
|
+
export interface Attribute {
|
|
40
|
+
/** The attribute's own name (the last path segment). */
|
|
41
|
+
name: string;
|
|
42
|
+
/** Dotted path from the block body, e.g. `connection.password`. */
|
|
43
|
+
path: string;
|
|
44
|
+
value: unknown;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Every scalar attribute in a block body, descending through nested blocks so
|
|
48
|
+
* a credential inside `connection {}` or `assume_role {}` is not invisible.
|
|
49
|
+
* Depth-limited: a Terraform block nests a handful of levels at most, and an
|
|
50
|
+
* unbounded walk over a large body buys nothing.
|
|
51
|
+
*/
|
|
52
|
+
export declare function walkAttributes(body: BlockBody, maxDepth?: number): Attribute[];
|
|
53
|
+
//# sourceMappingURL=blocks.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"blocks.d.ts","sourceRoot":"","sources":["../../../src/lint/post-synth/blocks.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,kCAAkC,CAAC;AAEzE,OAAO,KAAK,EAAE,SAAS,EAAmB,MAAM,iBAAiB,CAAC;AAElE,4EAA4E;AAC5E,MAAM,WAAW,cAAc;IAC7B,8CAA8C;IAC9C,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,SAAS,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,mFAAmF;IACnF,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,+DAA+D;AAC/D,wBAAgB,YAAY,CAAC,GAAG,EAAE,gBAAgB,EAAE,UAAU,EAAE,MAAM,GAAG,cAAc,EAAE,CAgBxF;AAED,yEAAyE;AACzE,wBAAgB,aAAa,CAAC,GAAG,EAAE,gBAAgB,EAAE,WAAW,EAAE,MAAM,EAAE,GAAG,cAAc,EAAE,CAE5F;AAED,iEAAiE;AACjE,wBAAgB,SAAS,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAGjD;AAED;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,SAAS,EAAE,GAAG,EAAE,MAAM,GAAG,SAAS,EAAE,CAKtE;AAED,0DAA0D;AAC1D,wBAAgB,OAAO,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAE/C;AAED,4DAA4D;AAC5D,MAAM,WAAW,SAAS;IACxB,wDAAwD;IACxD,IAAI,EAAE,MAAM,CAAC;IACb,mEAAmE;IACnE,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,OAAO,CAAC;CAChB;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,SAAS,EAAE,QAAQ,SAAI,GAAG,SAAS,EAAE,CAmBzE"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import type { PostSynthContext } from "@intentius/chant/lint/post-synth";
|
|
2
|
+
import type { CallModuleType } from "../../../hcl/descend.js";
|
|
3
|
+
/**
|
|
4
|
+
* Parse `fixtures/<checkId>/<name>.tf` into a {@link PostSynthContext} whose
|
|
5
|
+
* `entities` are exactly what a real root module of that one file would
|
|
6
|
+
* produce. `root` (the entity key prefix and the `TerraformEntity.props.root`
|
|
7
|
+
* value) defaults to `checkId`; pass a distinct value to load two fixtures
|
|
8
|
+
* into one context under different root names.
|
|
9
|
+
*
|
|
10
|
+
* Three lines per fixture in a test:
|
|
11
|
+
* ```ts
|
|
12
|
+
* const diags = tf001.check(await loadFixture("TF001", "positive"));
|
|
13
|
+
* expect(diags).toHaveLength(1);
|
|
14
|
+
* ```
|
|
15
|
+
*/
|
|
16
|
+
export declare function loadFixture(checkId: string, name: string, root?: string): Promise<PostSynthContext>;
|
|
17
|
+
/**
|
|
18
|
+
* Parse a whole fixture DIRECTORY, `fixtures/<checkId>/<name>/`, the way
|
|
19
|
+
* `buildRoots()` parses a configured root: its own `.tf` files, then every
|
|
20
|
+
* local `module` call followed into its directory (chant #2112). A rule about
|
|
21
|
+
* child modules (TF014, TF015) or about a whole scope's references (TF020)
|
|
22
|
+
* cannot be shown a single file and still be tested honestly, so its fixture
|
|
23
|
+
* is a tree:
|
|
24
|
+
*
|
|
25
|
+
* ```
|
|
26
|
+
* fixtures/TF014/positive/main.tf # module "cdn" { source = "./modules/cdn" }
|
|
27
|
+
* fixtures/TF014/positive/modules/cdn/main.tf # the provider block the rule reports
|
|
28
|
+
* ```
|
|
29
|
+
*
|
|
30
|
+
* The fixture directory is also the project root for the descent, so a
|
|
31
|
+
* fixture can exercise the outside-the-project refusal with a `../` source
|
|
32
|
+
* without reaching into the repository around it. `warnings` from the render
|
|
33
|
+
* lands on `buildResult.warnings`, where the descent's own refusals are
|
|
34
|
+
* readable by a test.
|
|
35
|
+
*/
|
|
36
|
+
export declare function loadTreeFixture(checkId: string, name: string, root?: string, callModuleType?: CallModuleType): Promise<PostSynthContext>;
|
|
37
|
+
//# sourceMappingURL=load.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"load.d.ts","sourceRoot":"","sources":["../../../../src/lint/post-synth/fixtures/load.ts"],"names":[],"mappings":"AAwBA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,kCAAkC,CAAC;AAEzE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAK3D;;;;;;;;;;;;GAYG;AACH,wBAAsB,WAAW,CAC/B,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,MAAM,EACZ,IAAI,GAAE,MAAgB,GACrB,OAAO,CAAC,gBAAgB,CAAC,CAe3B;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAsB,eAAe,CACnC,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,MAAM,EACZ,IAAI,GAAE,MAAgB,EACtB,cAAc,CAAC,EAAE,cAAc,GAC9B,OAAO,CAAC,gBAAgB,CAAC,CAkB3B"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/lint/post-synth/index.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,kCAAkC,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/lint/post-synth/index.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,kCAAkC,CAAC;AA6BvE,eAAO,MAAM,eAAe,EAAE,cAAc,EA4B3C,CAAC"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Classify a `module` block's `source` string, shared by TF004 (registry
|
|
3
|
+
* module without a version) and TF005 (git/hg module unpinned or pinned to
|
|
4
|
+
* a branch). Neither rule evaluates HCL: both read `source` as the literal
|
|
5
|
+
* string hcl2json hands back, so a source built from a variable or a
|
|
6
|
+
* function call is never classified (`"other"`), matching tflint's own
|
|
7
|
+
* `SourceKnown` guard on `module.Source`.
|
|
8
|
+
*
|
|
9
|
+
* `registry` mirrors `hashicorp/terraform-registry-address`'s
|
|
10
|
+
* `ParseModuleSource` (MPL-2.0,
|
|
11
|
+
* https://github.com/hashicorp/terraform-registry-address/blob/main/module.go):
|
|
12
|
+
* three slash-separated parts (`namespace/name/target-system`), or four with
|
|
13
|
+
* a leading hostname that contains a dot and is not `github.com` or
|
|
14
|
+
* `bitbucket.org` (those are reserved for direct VCS installs, never a
|
|
15
|
+
* registry). `git` covers the sources tflint's `terraform_module_pinned_source`
|
|
16
|
+
* treats as git/hg: an explicit `git::`/`hg::` force prefix, the `github.com`
|
|
17
|
+
* and `bitbucket.org` shorthands its `GitHubDetector`/`BitBucketDetector`
|
|
18
|
+
* recognize, scp-style `git@host:path` addresses, and any source ending in
|
|
19
|
+
* `.git`. `local` is `./` or `../` (checkov's `UNKNOWN` case for module
|
|
20
|
+
* pinning: a local path cannot be pinned to anything and is never flagged).
|
|
21
|
+
*/
|
|
22
|
+
export type ModuleSourceKind = "local" | "registry" | "git" | "other";
|
|
23
|
+
export interface ModuleSourceClassification {
|
|
24
|
+
kind: ModuleSourceKind;
|
|
25
|
+
/** The `?ref=`/`&ref=` value (falling back to `rev`), when `kind` is `"git"`. */
|
|
26
|
+
ref?: string;
|
|
27
|
+
}
|
|
28
|
+
export declare function classifyModuleSource(source: string): ModuleSourceClassification;
|
|
29
|
+
/**
|
|
30
|
+
* Is `ref` pinned tightly enough for TF005: a semver-shaped tag or a full
|
|
31
|
+
* 40-hex commit SHA. Stricter than checkov's `CKV_TF_1`/`CKV_TF_2`, which
|
|
32
|
+
* accept any `?ref=` containing `\d\.\d` (so `v1.2-dev` passes there); the
|
|
33
|
+
* page documents the difference.
|
|
34
|
+
*/
|
|
35
|
+
export declare function isPinnedRef(ref: string): boolean;
|
|
36
|
+
/** Is `ref` one of the well-known mutable branch names tflint's `flexible` style rejects, plus `trunk`. */
|
|
37
|
+
export declare function isDefaultBranch(ref: string): boolean;
|
|
38
|
+
//# sourceMappingURL=module-source.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"module-source.d.ts","sourceRoot":"","sources":["../../../src/lint/post-synth/module-source.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,MAAM,MAAM,gBAAgB,GAAG,OAAO,GAAG,UAAU,GAAG,KAAK,GAAG,OAAO,CAAC;AAEtE,MAAM,WAAW,0BAA0B;IACzC,IAAI,EAAE,gBAAgB,CAAC;IACvB,iFAAiF;IACjF,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAmDD,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,MAAM,GAAG,0BAA0B,CAsB/E;AAMD;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAEhD;AAED,2GAA2G;AAC3G,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAEpD"}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Root scope or child scope, and the `Callers:` chain that says which call
|
|
3
|
+
* reached a finding (chant #2112).
|
|
4
|
+
*
|
|
5
|
+
* Since the parse descends into local modules, `ctx.entities` holds two kinds
|
|
6
|
+
* of block: the root module's own, keyed `<root>/<address>`, and a child
|
|
7
|
+
* module's, keyed `<root>/module.<name>/<address>` with the call chain on
|
|
8
|
+
* `props.callers`. Every check has to say which it applies to, and the three
|
|
9
|
+
* shapes that answer live here:
|
|
10
|
+
*
|
|
11
|
+
* - {@link isRootScoped} for a check about how a ROOT is assembled (TF001's
|
|
12
|
+
* backend, TF002's `required_providers`): a child module has no backend and
|
|
13
|
+
* no provider requirements of its own to judge, and reading one as if it
|
|
14
|
+
* were the root's is how a root with a perfectly good backend gets flagged
|
|
15
|
+
* because a module beneath it has none.
|
|
16
|
+
* - {@link isChildScoped} for the mirror, the two rules that are ONLY about
|
|
17
|
+
* child modules (TF014, TF015).
|
|
18
|
+
* - {@link callersNote} for the sentence appended to a finding inside a
|
|
19
|
+
* child, naming each call site with the file and line it sits on. tflint
|
|
20
|
+
* prints the same thing as a `Callers:` block under the diagnostic
|
|
21
|
+
* (https://github.com/terraform-linters/tflint/blob/master/docs/user-guide/calling-modules.md);
|
|
22
|
+
* a `PostSynthDiagnostic` carries no ranges, so the chain goes in the
|
|
23
|
+
* message, where a reader of any output format sees it.
|
|
24
|
+
*
|
|
25
|
+
* A check with no opinion (most of them: an unset `type` on a variable is the
|
|
26
|
+
* same finding wherever the variable lives) needs nothing from this module and
|
|
27
|
+
* runs over both scopes, which is what tflint does with its own language rules
|
|
28
|
+
* under `--call-module-type=local`.
|
|
29
|
+
*/
|
|
30
|
+
import type { PostSynthCheck, PostSynthContext } from "@intentius/chant/lint/post-synth";
|
|
31
|
+
import { type Declarable } from "@intentius/chant/declarable";
|
|
32
|
+
/** The `module.<name>` chain on an entity, outermost first. Empty for a root block. */
|
|
33
|
+
export declare function callersOf(entity: Declarable): readonly string[];
|
|
34
|
+
/** Was this block declared in the root module itself? */
|
|
35
|
+
export declare function isRootScoped(entity: Declarable): boolean;
|
|
36
|
+
/** Was this block declared in a child module the root calls? */
|
|
37
|
+
export declare function isChildScoped(entity: Declarable): boolean;
|
|
38
|
+
/**
|
|
39
|
+
* The `Callers:` sentence for a finding on `key`, or `""` when the finding is
|
|
40
|
+
* in the root module.
|
|
41
|
+
*
|
|
42
|
+
* The call sites are the key's own prefixes: a finding on
|
|
43
|
+
* `app/module.cdn/module.bucket/aws_s3_bucket.assets` was reached through
|
|
44
|
+
* `app/module.cdn` and then `app/module.cdn/module.bucket`, both of them
|
|
45
|
+
* `module` block entities in `ctx.entities`, so the file and line each was
|
|
46
|
+
* parsed from are already recorded. A prefix with no entity (a hand-built
|
|
47
|
+
* context in a test) renders as the bare call name.
|
|
48
|
+
*/
|
|
49
|
+
export declare function callersNote(ctx: PostSynthContext, key: string): string;
|
|
50
|
+
/**
|
|
51
|
+
* Wrap every check so a finding inside a child module carries its
|
|
52
|
+
* {@link callersNote}, whichever rule produced it.
|
|
53
|
+
*
|
|
54
|
+
* Done once, here, rather than in each rule's message: a reader of a finding
|
|
55
|
+
* on `module.cdn`'s bucket needs to know which call reached that code no
|
|
56
|
+
* matter which of the twenty-odd checks reported it, and a rule that forgot
|
|
57
|
+
* to append the chain would be a silent gap. The wrapper is what
|
|
58
|
+
* `terraformPlugin.postSynthChecks()` returns; a rule's own `check()` is
|
|
59
|
+
* unchanged, which is what its unit tests call.
|
|
60
|
+
*
|
|
61
|
+
* A message that already names the chain is left alone, so a rule with
|
|
62
|
+
* something more specific to say about its callers can say it.
|
|
63
|
+
*/
|
|
64
|
+
export declare function withCallersChain(checks: readonly PostSynthCheck[]): PostSynthCheck[];
|
|
65
|
+
//# sourceMappingURL=scope.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scope.d.ts","sourceRoot":"","sources":["../../../src/lint/post-synth/scope.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,kCAAkC,CAAC;AACzF,OAAO,EAAwB,KAAK,UAAU,EAAE,MAAM,6BAA6B,CAAC;AAGpF,uFAAuF;AACvF,wBAAgB,SAAS,CAAC,MAAM,EAAE,UAAU,GAAG,SAAS,MAAM,EAAE,CAI/D;AAED,yDAAyD;AACzD,wBAAgB,YAAY,CAAC,MAAM,EAAE,UAAU,GAAG,OAAO,CAExD;AAED,gEAAgE;AAChE,wBAAgB,aAAa,CAAC,MAAM,EAAE,UAAU,GAAG,OAAO,CAEzD;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,WAAW,CAAC,GAAG,EAAE,gBAAgB,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAgBtE;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,SAAS,cAAc,EAAE,GAAG,cAAc,EAAE,CAYpF"}
|
|
@@ -1,17 +1,69 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* TF001: a root module keeps its state on local disk.
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
* and
|
|
4
|
+
* Two ways a root gets there, and this reports both (#2218). A `terraform`
|
|
5
|
+
* block with no `backend "<type>"` and no `cloud {}` falls back to the local
|
|
6
|
+
* backend implicitly. A `backend "local"` block asks for the same backend by
|
|
7
|
+
* name. Either way `terraform.tfstate` lands in the working directory, and
|
|
8
|
+
* that file holds every attribute of every managed resource, secrets
|
|
9
|
+
* included, and it is not shared, not locked, and not versioned. The first
|
|
10
|
+
* apply from a second machine or a CI runner starts from an empty state and
|
|
11
|
+
* proposes to create the estate again.
|
|
12
|
+
*
|
|
13
|
+
* So the rule reads the backend block's TYPE LABEL rather than its presence:
|
|
14
|
+
* the id means "no remote backend", which is what its name, its message and
|
|
15
|
+
* its page have always argued. `cloud {}` counts as remote (it is Terraform
|
|
16
|
+
* Cloud / HCP state, held off the machine and locked). Every other backend
|
|
17
|
+
* type is taken as remote without a list to maintain, since `local` is the
|
|
18
|
+
* only backend Terraform ships that writes to the working directory.
|
|
19
|
+
*
|
|
20
|
+
* A root that keeps local state on purpose says so with a
|
|
21
|
+
* `# chant-ignore-block: TF001` on the line above its `terraform` block
|
|
22
|
+
* (chant #2111), which is what the three shipped examples do.
|
|
10
23
|
*
|
|
11
24
|
* One diagnostic per root, fired from the root's `terraform` block. A root
|
|
12
25
|
* with no `terraform` block at all is not flagged: it declares no version
|
|
13
26
|
* constraints either, and the missing block is a different finding.
|
|
27
|
+
*
|
|
28
|
+
* Scope: root modules only (#2112). A child module must NOT declare a
|
|
29
|
+
* backend, which is the mirror image and TF015's finding, so a descended
|
|
30
|
+
* module's `terraform` block is skipped here rather than read as if it were
|
|
31
|
+
* the root's.
|
|
32
|
+
*
|
|
33
|
+
* Does not fire on a live root (#2103): a `backend` block is exactly what
|
|
34
|
+
* choudoufu refuses there (TF024's territory), and the fallback to local
|
|
35
|
+
* state this check warns about does not apply, since a live root keeps no
|
|
36
|
+
* state file at all, local or remote.
|
|
14
37
|
*/
|
|
15
38
|
import type { PostSynthCheck } from "@intentius/chant/lint/post-synth";
|
|
39
|
+
import { type BlockBody } from "../../hcl/parse.js";
|
|
40
|
+
/**
|
|
41
|
+
* `backend`/`cloud` are blocks, so hcl2json encodes them as a value under the
|
|
42
|
+
* key, structurally the same "literal value under this key" shape `attr()`
|
|
43
|
+
* (`../../hcl/value.ts`, chant #2113) reads for an ordinary attribute, so
|
|
44
|
+
* this reads through it rather than re-deriving presence by hand.
|
|
45
|
+
*/
|
|
46
|
+
export declare function hasBlock(body: BlockBody, key: string): boolean;
|
|
47
|
+
/** The one backend type that writes state to the working directory. */
|
|
48
|
+
export declare const LOCAL_BACKEND = "local";
|
|
49
|
+
/**
|
|
50
|
+
* The type labels of the `backend` blocks in a `terraform` block body.
|
|
51
|
+
*
|
|
52
|
+
* `backend` takes one label, so hcl2json nests it one level deeper than an
|
|
53
|
+
* unlabelled block: `backend "s3" { bucket = "b" }` is
|
|
54
|
+
* `{ backend: { s3: [{ bucket: "b" }] } }`, where `cloud { ... }` is just
|
|
55
|
+
* `{ cloud: [{ ... }] }`. The keys of that inner object are the labels, which
|
|
56
|
+
* is the only place the type survives the parse. A malformed body that puts
|
|
57
|
+
* an array or a scalar under `backend` yields no labels, and the caller then
|
|
58
|
+
* treats the root as having no remote backend, the same verdict a missing
|
|
59
|
+
* block gets.
|
|
60
|
+
*/
|
|
61
|
+
export declare function backendTypes(body: BlockBody): string[];
|
|
62
|
+
/**
|
|
63
|
+
* Whether the body configures state somewhere other than the working
|
|
64
|
+
* directory: any `backend` block whose type is not `local`, or a `cloud`
|
|
65
|
+
* block.
|
|
66
|
+
*/
|
|
67
|
+
export declare function hasRemoteBackend(body: BlockBody): boolean;
|
|
16
68
|
export declare const tf001: PostSynthCheck;
|
|
17
69
|
//# sourceMappingURL=tf001.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tf001.d.ts","sourceRoot":"","sources":["../../../src/lint/post-synth/tf001.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"tf001.d.ts","sourceRoot":"","sources":["../../../src/lint/post-synth/tf001.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;AAEH,OAAO,KAAK,EACV,cAAc,EAGf,MAAM,kCAAkC,CAAC;AAE1C,OAAO,EAAkB,KAAK,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAIjE;;;;;GAKG;AACH,wBAAgB,QAAQ,CAAC,IAAI,EAAE,SAAS,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAK9D;AAED,uEAAuE;AACvE,eAAO,MAAM,aAAa,UAAU,CAAC;AAErC;;;;;;;;;;;GAWG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,SAAS,GAAG,MAAM,EAAE,CAMtD;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,SAAS,GAAG,OAAO,CAGzD;AAED,eAAO,MAAM,KAAK,EAAE,cAmDnB,CAAC"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TF002: a provider a root implies has no `required_providers` entry, or an
|
|
3
|
+
* incomplete one.
|
|
4
|
+
*
|
|
5
|
+
* A provider is implied two ways: an explicit `provider "<name>" {}` block,
|
|
6
|
+
* or a resource/data type prefix (`aws_instance` implies `aws`, up to the
|
|
7
|
+
* first underscore, the same heuristic tflint's `terraform_required_providers`
|
|
8
|
+
* reads via `GetProviderRefs()`). The `terraform` builtin (the provider
|
|
9
|
+
* behind `terraform_remote_state`) is never implied: it has no registry
|
|
10
|
+
* entry to require. Every implied provider needs a `required_providers`
|
|
11
|
+
* entry that is an object carrying both `source` and `version`, since the old
|
|
12
|
+
* shorthand form (`aws = "~> 4.0"`, a bare string) has neither and fires the
|
|
13
|
+
* same as a missing entry.
|
|
14
|
+
*
|
|
15
|
+
* Fires once per incomplete or missing provider, not once per resource: two
|
|
16
|
+
* resources implying the same unconstrained provider produce one diagnostic.
|
|
17
|
+
* Anchored on whichever entity first implied the provider, preferring an
|
|
18
|
+
* explicit `provider` block over a resource/data type, so the diagnostic
|
|
19
|
+
* points at the most specific place a fix belongs.
|
|
20
|
+
*
|
|
21
|
+
* A root with no `terraform` block at all is out of scope, same as TF001:
|
|
22
|
+
* the missing block is that rule's finding, not this one's.
|
|
23
|
+
*
|
|
24
|
+
* Scope: root modules only (#2112). A child module's own `required_providers`
|
|
25
|
+
* are the child's business, and its resources are constrained by the root's
|
|
26
|
+
* block at plan time, so folding a descended module's blocks into this pass
|
|
27
|
+
* would both credit the root with requirements it never declared and judge it
|
|
28
|
+
* on providers it never named.
|
|
29
|
+
*/
|
|
30
|
+
import type { PostSynthCheck } from "@intentius/chant/lint/post-synth";
|
|
31
|
+
export declare const tf002: PostSynthCheck;
|
|
32
|
+
//# sourceMappingURL=tf002.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tf002.d.ts","sourceRoot":"","sources":["../../../src/lint/post-synth/tf002.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AAEH,OAAO,KAAK,EACV,cAAc,EAGf,MAAM,kCAAkC,CAAC;AAyE1C,eAAO,MAAM,KAAK,EAAE,cA2CnB,CAAC"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TF003: a root's `terraform` block has no `required_version`.
|
|
3
|
+
*
|
|
4
|
+
* Sits on the same `terraform` block TF001 already walks. Without
|
|
5
|
+
* `required_version`, a root can be applied by whatever Terraform binary
|
|
6
|
+
* happens to be on the runner's `PATH`, and a binary upgrade that changes
|
|
7
|
+
* behavior (a provider protocol bump, a changed default) surfaces as a
|
|
8
|
+
* surprise plan diff instead of a version-check failure before anything runs.
|
|
9
|
+
*
|
|
10
|
+
* One diagnostic per root, fired once even if the root spreads its
|
|
11
|
+
* `terraform` block across several files (a legacy-config split into
|
|
12
|
+
* `terraform.tf` and `versions.tf`, say). A root with no `terraform` block
|
|
13
|
+
* at all is out of scope, same as TF001 and TF002: the missing block is
|
|
14
|
+
* their finding, not this one's.
|
|
15
|
+
*
|
|
16
|
+
* Scope: root modules only (#2112). A child module may legitimately leave
|
|
17
|
+
* `required_version` to the root that calls it, so a descended module's
|
|
18
|
+
* `terraform` block is skipped here.
|
|
19
|
+
*/
|
|
20
|
+
import type { PostSynthCheck } from "@intentius/chant/lint/post-synth";
|
|
21
|
+
export declare const tf003: PostSynthCheck;
|
|
22
|
+
//# sourceMappingURL=tf003.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tf003.d.ts","sourceRoot":"","sources":["../../../src/lint/post-synth/tf003.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,KAAK,EACV,cAAc,EAGf,MAAM,kCAAkC,CAAC;AAS1C,eAAO,MAAM,KAAK,EAAE,cAqCnB,CAAC"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TF004: a registry-sourced `module` block has no `version`.
|
|
3
|
+
*
|
|
4
|
+
* "Registry-sourced" means `source` parses as a Terraform module registry
|
|
5
|
+
* address (`classifyModuleSource`, `./module-source.ts`): a bare
|
|
6
|
+
* `namespace/name/target-system`, or a hostname-prefixed
|
|
7
|
+
* `host/namespace/name/target-system`. Without `version`, `terraform init`
|
|
8
|
+
* always resolves to the newest release that satisfies no constraint at
|
|
9
|
+
* all, so an upstream module release can change what a root provisions with
|
|
10
|
+
* no local edit and no diff to review first.
|
|
11
|
+
*
|
|
12
|
+
* A local (`./`, `../`) or git/hg source is never flagged here: git/hg is
|
|
13
|
+
* TF005's territory, and a local source cannot carry a registry version at
|
|
14
|
+
* all. One diagnostic per module block.
|
|
15
|
+
*
|
|
16
|
+
* Scope: root and child modules alike (#2112). The condition is a property
|
|
17
|
+
* of the block itself, so a descended module's block is read exactly as a
|
|
18
|
+
* root's is.
|
|
19
|
+
*/
|
|
20
|
+
import type { PostSynthCheck } from "@intentius/chant/lint/post-synth";
|
|
21
|
+
export declare const tf004: PostSynthCheck;
|
|
22
|
+
//# sourceMappingURL=tf004.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tf004.d.ts","sourceRoot":"","sources":["../../../src/lint/post-synth/tf004.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,KAAK,EACV,cAAc,EAGf,MAAM,kCAAkC,CAAC;AAK1C,eAAO,MAAM,KAAK,EAAE,cAiCnB,CAAC"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TF005: a git or hg `module` source with no `?ref=`, or a `?ref=` that
|
|
3
|
+
* isn't tight enough to call pinned.
|
|
4
|
+
*
|
|
5
|
+
* "Git or hg" is `classifyModuleSource`'s `"git"` kind (`./module-source.ts`):
|
|
6
|
+
* an explicit `git::`/`hg::` prefix, the bare `github.com`/`bitbucket.org`
|
|
7
|
+
* shorthands, an scp-style `git@host:path`, or anything ending in `.git`.
|
|
8
|
+
* A ref counts as pinned only if it is a semver-shaped tag or a full 40-hex
|
|
9
|
+
* commit SHA (`isPinnedRef`), stricter than checkov's `CKV_TF_1`/`CKV_TF_2`,
|
|
10
|
+
* which accept any `?ref=` containing `\d\.\d` (so `v1.2-dev` passes there;
|
|
11
|
+
* it does not here, and the rule's page section says so). A ref matching a
|
|
12
|
+
* well-known mutable branch name (`main`, `master`, `develop`, `trunk`) gets
|
|
13
|
+
* its own, more specific message, since that's the exact case tflint's
|
|
14
|
+
* `flexible` style (the style this rule ships; see the page section for what
|
|
15
|
+
* `semver` style would add) already reports on.
|
|
16
|
+
*
|
|
17
|
+
* A local (`./`, `../`) source is never flagged: it can't be pinned to a
|
|
18
|
+
* ref at all, and checkov's own module-pinning checks return `UNKNOWN`
|
|
19
|
+
* (not a failure) for the same reason. A registry source is TF004's
|
|
20
|
+
* territory, not this rule's; the two never fire on the same module block.
|
|
21
|
+
*
|
|
22
|
+
* Scope: root and child modules alike (#2112). The condition is a property
|
|
23
|
+
* of the block itself, so a descended module's block is read exactly as a
|
|
24
|
+
* root's is.
|
|
25
|
+
*/
|
|
26
|
+
import type { PostSynthCheck } from "@intentius/chant/lint/post-synth";
|
|
27
|
+
export declare const tf005: PostSynthCheck;
|
|
28
|
+
//# sourceMappingURL=tf005.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tf005.d.ts","sourceRoot":"","sources":["../../../src/lint/post-synth/tf005.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAEH,OAAO,KAAK,EACV,cAAc,EAGf,MAAM,kCAAkC,CAAC;AAK1C,eAAO,MAAM,KAAK,EAAE,cAwCnB,CAAC"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TF006: a `sensitive = true` variable carries a `default`.
|
|
3
|
+
*
|
|
4
|
+
* Marking a variable sensitive is a statement that its value must not be seen.
|
|
5
|
+
* A default is a value committed to the repository, so the two together are a
|
|
6
|
+
* contradiction: the secret is in git, and the `sensitive` flag only hides it
|
|
7
|
+
* from plan output, where it was never the exposure. It is also the shape that
|
|
8
|
+
* survives longest, because every environment that forgets to pass the variable
|
|
9
|
+
* silently gets the committed one.
|
|
10
|
+
*
|
|
11
|
+
* Any default counts, not only a secret-shaped one. `default = ""` and
|
|
12
|
+
* `default = null` are the two that look harmless, and both make a required
|
|
13
|
+
* secret optional, which is the other half of the failure.
|
|
14
|
+
*
|
|
15
|
+
* Scope: root and child modules alike (#2112). The condition is a property
|
|
16
|
+
* of the block itself, so a descended module's block is read exactly as a
|
|
17
|
+
* root's is.
|
|
18
|
+
*/
|
|
19
|
+
import type { PostSynthCheck } from "@intentius/chant/lint/post-synth";
|
|
20
|
+
export declare const tf006: PostSynthCheck;
|
|
21
|
+
//# sourceMappingURL=tf006.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tf006.d.ts","sourceRoot":"","sources":["../../../src/lint/post-synth/tf006.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,KAAK,EACV,cAAc,EAGf,MAAM,kCAAkC,CAAC;AAI1C,eAAO,MAAM,KAAK,EAAE,cAyBnB,CAAC"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TF007: a variable default or a `locals` value holds a secret-shaped literal.
|
|
3
|
+
*
|
|
4
|
+
* This is the check tfsec shipped as `general-secrets-sensitive-in-variable`
|
|
5
|
+
* and `general-secrets-sensitive-in-local`, and that trivy dropped when it
|
|
6
|
+
* absorbed tfsec. #2107's survey found no maintained tool that has it today.
|
|
7
|
+
*
|
|
8
|
+
* A committed default or local is a credential in git history, which no later
|
|
9
|
+
* edit removes, and Terraform copies it into state and into plan output on
|
|
10
|
+
* every run. Both heuristics in `../secret-shape.ts` count: the name (a
|
|
11
|
+
* variable called `db_password`) and the value (something shaped like a live
|
|
12
|
+
* credential whatever it is called). References and interpolations are never
|
|
13
|
+
* flagged, because passing the value in is the fix.
|
|
14
|
+
*
|
|
15
|
+
* Scope: root and child modules alike (#2112). The condition is a property
|
|
16
|
+
* of the block itself, so a descended module's block is read exactly as a
|
|
17
|
+
* root's is.
|
|
18
|
+
*/
|
|
19
|
+
import type { PostSynthCheck } from "@intentius/chant/lint/post-synth";
|
|
20
|
+
export declare const tf007: PostSynthCheck;
|
|
21
|
+
//# sourceMappingURL=tf007.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tf007.d.ts","sourceRoot":"","sources":["../../../src/lint/post-synth/tf007.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,KAAK,EACV,cAAc,EAGf,MAAM,kCAAkC,CAAC;AAY1C,eAAO,MAAM,KAAK,EAAE,cA0CnB,CAAC"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TF008: a `provider` block configures a credential inline.
|
|
3
|
+
*
|
|
4
|
+
* The most corroborated rule in #2107's survey: checkov (`CKV_AWS_41` and its
|
|
5
|
+
* `credentials.py` siblings), KICS, Snyk and semgrep all ship a version of it,
|
|
6
|
+
* and it is the only Terraform-language-shaped check any of Snyk or semgrep
|
|
7
|
+
* ships at all. Every one of them is written per provider. This one is written
|
|
8
|
+
* against attribute NAMES, so it covers the providers those tools cover and
|
|
9
|
+
* the several hundred they do not.
|
|
10
|
+
*
|
|
11
|
+
* A credential in a provider block is used by every resource that provider
|
|
12
|
+
* manages, so it is the highest-value one in the root, and it is read from the
|
|
13
|
+
* repository by everyone who can clone it. Providers all accept the same
|
|
14
|
+
* credential through the environment or a shared config file instead.
|
|
15
|
+
*
|
|
16
|
+
* Scope: root and child modules alike (#2112). The condition is a property
|
|
17
|
+
* of the block itself, so a descended module's block is read exactly as a
|
|
18
|
+
* root's is.
|
|
19
|
+
*/
|
|
20
|
+
import type { PostSynthCheck } from "@intentius/chant/lint/post-synth";
|
|
21
|
+
export declare const tf008: PostSynthCheck;
|
|
22
|
+
//# sourceMappingURL=tf008.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tf008.d.ts","sourceRoot":"","sources":["../../../src/lint/post-synth/tf008.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,KAAK,EACV,cAAc,EAGf,MAAM,kCAAkC,CAAC;AAmB1C,eAAO,MAAM,KAAK,EAAE,cA+BnB,CAAC"}
|