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 monphareDownload 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-vpcAvailable 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-vpcOutput:
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 --strictScan 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-workspaceSee 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-onlyCreates a monphare.yaml in the current directory with documented defaults.
monphare initValidates a config file before you wire it into CI.
monphare validate monphare.yamlMonPhare 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: 24Configuration 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.