sarj-iac-lint
Custom Terraform / IaC lint rules — stdlib only, line/block based, pre-commit-friendly. Mined from recurring infra review comments across the org.
uv tool install sarj-iac-lint
Rules
| Code | Rule | What it flags |
|---|---|---|
| SARJ201 | require-deletion-protection |
A stateful resource (Cloud SQL, GKE, BigQuery, Spanner, AlloyDB, Bigtable, RDS, DynamoDB, ElastiCache, DocumentDB, Neptune, Azure databases, Cosmos DB, ...) without deletion_protection = true. |
| SARJ202 | no-comment-cruft |
Commented-out Terraform/HCL and section-banner / divider comments. |
| SARJ203 | require-prevent-destroy-on-irreplaceable |
A bucket, Secret Manager secret, or artifact registry — which expose no deletion_protection argument at all — without lifecycle { prevent_destroy = true }. |
.tf, .hcl, and .tfvars files are scanned by all rules; .yaml/.yml
(Helm/k8s/Compose) are scanned by no-comment-cruft for banners only.
Pre-commit
- repo: https://github.com/sarj-ai/standards
rev: iac-v0.2.0
hooks:
- id: sarj-require-deletion-protection
- id: sarj-no-comment-cruft-iac
- id: sarj-require-prevent-destroy-on-irreplaceable
CLI
sarj-iac-lint check --rule require-deletion-protection iac/
sarj-iac-lint list-rules
Diagnostic format is path:line:col: CODE message — Ruff-compatible.
--exit-zero reports without failing (warn mode).
Adoption
All three rules have ~zero false positives — run them as hard (blocking) hooks.
require-deletion-protection treats variable/expression-gated protection
(deletion_protection = var.enabled) and lifecycle { prevent_destroy = true }
as protected — only a literal = false or a total absence is flagged. Protection
must sit on the resource itself: a flag nested in settings { ... } is the
API-side switch and does not stop terraform destroy.
require-prevent-destroy-on-irreplaceable covers the stores SARJ201 cannot,
because they have no protection argument to check. It exempts anything declared
disposable via force_destroy, and any secret whose value a *_secret_version
resource in the same file reconstructs.
Suppression
Inline # sarj-noqa: SARJ201 — <reason> on the offending line (the resource
line for SARJ201 and SARJ203).
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distributions
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file sarj_iac_lint-0.5.3-py3-none-any.whl.
File metadata
- Download URL: sarj_iac_lint-0.5.3-py3-none-any.whl
- Upload date:
- Size: 15.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
258fa6a63e006fcc3fc9a099bf654a765acbcad4e8e589bc5dc8cf91e1d5c0b8
|
|
| MD5 |
1cb4cdcbd7ab10d1ada7fefa5086db5a
|
|
| BLAKE2b-256 |
253cf88272ca3b0b5fd60a3da25da66fcf6b1fe52f6436daee31aa32286f1291
|
Provenance
The following attestation bundles were made for sarj_iac_lint-0.5.3-py3-none-any.whl:
Publisher:
release.yml on sarj-ai/standards
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
sarj_iac_lint-0.5.3-py3-none-any.whl -
Subject digest:
258fa6a63e006fcc3fc9a099bf654a765acbcad4e8e589bc5dc8cf91e1d5c0b8 - Sigstore transparency entry: 2349209879
- Sigstore integration time:
-
Permalink:
sarj-ai/standards@a1fdfa4d11ca7591c68be6c005d8800bf7040312 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/sarj-ai
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@a1fdfa4d11ca7591c68be6c005d8800bf7040312 -
Trigger Event:
push
-
Statement type: