mon-far -- French for "my lighthouse". Because someone has to shine a light on your Terraform constraints.
Catch version drift, deprecated modules, and risky constraints across all your Terraform repos.
Across your repos, this is happening right now:
# team-a/main.tf -- no pin, pulls latest on every init module "vpc" { source = "terraform-aws-modules/vpc/aws" } # team-b/main.tf -- anything goes module "vpc" { source = "terraform-aws-modules/vpc/aws" version = ">= 0.0.0" } # team-c/main.tf -- frozen, no security patches module "vpc" { source = "terraform-aws-modules/vpc/aws" version = "= 2.44.0" }
Nobody knows until something breaks. MonPhare finds these before production does.
| Issue | What's wrong | Example |
|---|---|---|
| Missing version | No constraint at all, pulls latest on every init | source = "aws-modules/vpc/aws" (no version) |
| Too broad | Accepts anything, including breaking changes | version = ">= 0.0.0" |
| Wildcard | Same as above, different syntax | version = "*" |
| No upper bound | Lets breaking majors in silently | version = ">= 3.0" |
| Exact pin | Frozen -- no patches, no security fixes | version = "= 2.44.0" |
| Pre-release | Alpha/beta refs in production | version = "~> 2.0.0-beta" |
| Cross-repo conflict | Two repos want incompatible ranges for the same module | repo-a: >= 5.0 vs repo-b: < 5.0 |
| Deprecated module | Module with known CVE or retired version still in use | terraform-aws-modules/vpc/aws at 1.0.1 |
| Deprecated provider | Provider version range flagged by your security team | hashicorp/azurerm < 3.50.0 |
| Deprecated runtime | Terraform/OpenTofu version too old | terraform < 0.13.0 |
brew tap tanguc/tap brew install monphare
Download from the Releases page:
| Platform | Architecture | Download |
|---|---|---|
| Linux | x86_64 | monphare-linux-x86_64.tar.gz |
| Linux | ARM64 | monphare-linux-aarch64.tar.gz |
| macOS | Intel | monphare-darwin-x86_64.tar.gz |
| macOS | Apple Silicon | monphare-darwin-aarch64.tar.gz |
| Windows | x86_64 | monphare-windows-x86_64.zip |
# linux/macOS
curl -LO https://github.com/tanguc/monphare/releases/latest/download/monphare-linux-x86_64.tar.gz
tar -xzf monphare-linux-x86_64.tar.gz
sudo mv monphare /usr/local/bin/docker pull ghcr.io/tanguc/monphare:latest # scan a local directory docker run --rm -v "$(pwd):/workspace" ghcr.io/tanguc/monphare scan /workspace # scan a remote repo docker run --rm ghcr.io/tanguc/monphare scan https://github.com/terraform-aws-modules/terraform-aws-vpc
Available for linux/amd64 and linux/arm64.
git clone https://github.com/tanguc/monphare cd monphare cargo install --path .
# scan a local directory monphare scan ./terraform # scan a remote repo directly (public repos work without a token) monphare scan https://github.com/terraform-aws-modules/terraform-aws-vpc
Output:
MonPhare v0.3.0 [FAILED] 3 errors, 3 warnings
Scanned: 1 files, 4 modules, 3 providers
+------+-----------------------+----------------+----------+-----------+
| Sev | Resource | Issue | Current | File |
+------+-----------------------+----------------+----------+-----------+
| ERR | module.vpc_no_version | No version | - | main.tf:0 |
| ERR | module.git_module | No version | - | main.tf:0 |
| ERR | provider.aws | No version | - | main.tf:0 |
| WARN | resource.google | No upper bound | - | main.tf:0 |
| WARN | resource.azurerm | No upper bound | - | main.tf:0 |
| WARN | provider.google | Too broad | >= 0.0.0 | main.tf:0 |
| INFO | resource.eks_exact | Exact version | - | main.tf:0 |
+------+-----------------------+----------------+----------+-----------+
Fix errors to pass.
Point it at local directories, remote URLs, or an entire org.
# local directories monphare scan ./repo1 ./repo2 ./repo3 # remote repositories (URL auto-detected, no --repo flag needed) monphare scan https://github.com/org/repo1 https://github.com/org/repo2 # mix local and remote monphare scan ./local-repo https://github.com/org/remote-repo # output as JSON or HTML monphare scan ./terraform --format json --output report.json monphare scan ./terraform --format html --output report.html # strict mode for CI -- exit code 1 on warnings monphare scan ./terraform --strict
Scan all repositories from a GitHub org, GitLab group, Azure DevOps project, or Bitbucket workspace. Works without a token for public orgs.
# public org -- no token needed monphare scan --github terraform-aws-modules # private org -- set token via env var export MONPHARE_GIT_TOKEN=ghp_xxx monphare scan --github my-private-org # other platforms monphare scan --gitlab my-group monphare scan --ado my-org/my-project monphare scan --bitbucket my-workspace
See how modules and providers relate to each other. Useful to understand blast radius before upgrading a shared module.
# DOT format (for Graphviz) monphare graph ./terraform --format dot --output deps.dot # Mermaid diagram (renders in GitHub, GitLab, Notion, etc.) monphare graph ./terraform --format mermaid # JSON for programmatic use monphare graph ./terraform --format json # filter to modules only or providers only monphare graph ./terraform --modules-only monphare graph ./terraform --providers-only
Creates a monphare.yaml in the current directory with documented defaults.
monphare init
Validates a config file before you wire it into CI.
monphare validate monphare.yaml
MonPhare uses a monphare.yaml file. Run monphare init to generate one with all available options.
scan: exclude_patterns: - "**/test/**" - "**/examples/**" - "**/.terraform/**" continue_on_error: true analysis: check_exact_versions: true check_prerelease: true check_upper_bound: true policies: require_version_constraint: true require_upper_bound: false # flag modules/providers with known issues deprecations: modules: "terraform-aws-modules/vpc/aws": - version: "1.0.1" reason: "Critical security vulnerability in VPC module versions before 3.0" severity: error replacement: "terraform-aws-modules/vpc/aws >= 5.0.0" providers: "hashicorp/azurerm": versions: - version: "> 0.0.1, < 3.50.0" reason: "Multiple CVEs in versions before 3.50.0" severity: error replacement: ">= 3.50.0" cache: enabled: true ttl_hours: 24
Configuration priority (highest to lowest):
- CLI arguments
- Environment variables (
MONPHARE_GIT_TOKEN,MONPHARE_CONFIG) monphare.yaml- Defaults
Use --strict to fail the pipeline when warnings are found.
# GitHub Actions example - name: Analyze Terraform constraints run: monphare scan ./terraform --strict --format json --output report.json
| Code | Meaning |
|---|---|
| 0 | No issues (or warnings without --strict) |
| 1 | Warnings found (with --strict), or runtime error |
| 2 | Constraint errors found |
| Code | Severity | Description |
|---|---|---|
missing-version |
error | Module or provider has no version constraint |
wildcard-constraint |
warning | Constraint uses * wildcard |
broad-constraint |
warning | Constraint is too permissive (e.g. >= 0.0.0) |
no-upper-bound |
warning | No upper bound allows breaking changes in |
exact-version |
info | Exact pin prevents patch and security updates |
prerelease-version |
info | Pre-release version referenced |
Contributions welcome. Fork, branch, PR.
cargo test --all-features
cargo clippy --all-features -- -D warnings
cargo fmt --all -- --checkMIT -- see LICENSE.