Cartographer is a lightweight CLI tool written in Go that analyzes and visualizes relationships between Kubernetes resources. It ingests Kubernetes manifests—from YAML files, Helm charts, or a live cluster—and produces dependency graphs in multiple formats (DOT, Mermaid, JSON, PNG, SVG) to help you understand and document your application's architecture.
-
Kubernetes Manifest Ingestion
- Parse multi-document YAML files and convert them into structured Kubernetes objects for analysis.
- Support for ephemeral containers, environment variable references, volume references (Secrets, ConfigMaps, PVCs), and more.
-
Helm Chart Support
- Render and analyze Kubernetes manifests from Helm charts via the Helm SDK.
- Specify the chart path similarly to Helm CLI usage (e.g.,
--chart,--release,--values,--version).
-
Live Cluster Mode
- Connect to a running Kubernetes cluster via kubeconfig and analyze deployed resources directly from the API server.
--clusterflag with optional-A/--all-namespacesfor cross-namespace analysis.- Cluster settings (
kubeconfig,context) configurable via.cartographer.yaml.
-
Dependency Analysis with Labeled Edges
- Detect references such as:
- Owner References (e.g., Deployment owned by a HelmRelease).
- Pod Spec References (Secrets, ConfigMaps, PVCs, ServiceAccounts, imagePullSecrets).
- Label Selectors (Service → Pod, NetworkPolicy → Pod, PodDisruptionBudget → Pod), including full
matchExpressionssupport (In, NotIn, Exists, DoesNotExist). - Ingress routes (Ingress → Service → TLS Secret).
- HPA scale targets (HPA → Deployment).
- Each edge is annotated with a reason (e.g.,
ownerRef,secretRef,selector) to clarify how resources are connected.
- Detect references such as:
-
Multiple Output Formats
- DOT, Mermaid, JSON, PNG, and SVG output formats.
- Mermaid renders natively in GitHub READMEs, Notion, and Confluence.
- PNG and SVG render directly via built-in GraphViz integration.
- JSON output for integration with other tools and CI pipelines.
- Edges are automatically labeled with the reference reason, making the graph easy to interpret.
-
Color-Coded Resource Categories
- Nodes are color-coded by semantic category: Workloads, Networking, Config & Storage, RBAC, Autoscaling & Policy.
- DOT/PNG/SVG output includes a legend table for easy reference.
- Mermaid output uses
classDefstyling for category colors. - JSON output includes a
groupfield on each node for programmatic filtering.
-
Config-Driven Filtering
- Exclude resources by kind or name via
.cartographer.yaml— no extra CLI flags needed. - Applies to all input modes (YAML, Helm, cluster).
- Case-insensitive kind matching (e.g.,
configmapmatchesConfigMap).
- Exclude resources by kind or name via
-
Cobra & Viper CLI
-
Containerized Deployment
- Dockerfile for building and running Cartographer in a containerized environment.
- Make targets for multi-platform builds (e.g., Linux, Mac ARM).
- Go 1.25+ (modules enabled)
- Helm (if using Helm chart ingestion)
- Docker (optional, for containerized builds)
- Graphviz (optional, required for
--output-format pngandsvg. Install viabrew install graphvizon macOS)
git clone https://github.com/HMetcalfeW/cartographer.git
cd cartographerCartographer uses Go modules. From the repository root:
make depsThis fetches all necessary dependencies, including:
Cobra & Viper for CLI and config Helm SDK for chart rendering Kubernetes API packages for unstructured manifest parsing
Cartographer uses Go modules. From the repository root:
make update-depsThis fetches updates all dependencies to the latest version
Cartographer offers a flexible CLI with an analyze subcommand using the Helm SDK to render the chart and then process the resulting YAML for dependencies. Here are a few examples:
--input: Path to a Kubernetes YAML file.--chart: Local path or remote chart name (bitnami/postgresql).--cluster: Analyze resources from a live Kubernetes cluster.-A, --all-namespaces: Fetch resources from all namespaces (requires--cluster).--values: Optional path to a Helm values file.--release: Name for the Helm release (defaults tocartographer-release).--version: The Helm Chart version you wish to use.--namespace: Namespace scope for Helm rendering or cluster queries.--output-format: Output format —dot(default),mermaid,json,png,svg.--output-file: Output file path. Required forpngandsvgformats.--config: (Optional) Path to a configuration file for advanced settings.
Note:
--input,--chart, and--clusterare mutually exclusive — specify exactly one.
cartographer versionPrints the version, commit hash, and build date.
cartographer analyze --input /path/to/manifest.yaml --output-format dot --output-file test.dotCartographer reads the YAML, parses each document into Kubernetes unstructured objects.
cartographer analyze --chart /path/to/chart --release my-release --values values.yaml --output-format dot --output-file test.dotNote: the registry will need to be added to your local Helm index.
helm repo add bitnami https://charts.bitnami.com/bitnami
cartographer analyze --chart bitnami/postgresql --release my-release --values values.yaml --version 16.4.8 --output-format dot --output-file test.dotcartographer analyze --chart oci://registry-1.docker.io/bitnamicharts/postgresql --release my-db --version 16.4.8 --output-format dot --output-file test.dotcartographer analyze --cluster --namespace default --output-format jsoncartographer analyze --cluster -A --output-format dot --output-file cluster.dotcartographer analyze --chart oci://registry-1.docker.io/bitnamicharts/postgresql --release my-db --version 16.4.8 --output-format png --output-file postgresql.pngcartographer analyze --input manifest.yaml --output-format mermaidcartographer analyze --input manifest.yaml --output-format json | jq '.edges[] | select(.reason == "secretRef")'cartographer analyze --chart bitnami/postgresql --version 16.4.8 --output-format svg --output-file postgresql.svgcartographer analyze --chart oci://registry-1.docker.io/bitnamicharts/metallb --output-format dot --output-file bitnami-metallb.dot
dot -Tpng bitnami-metallb.dot -o bitnami-metallb.pngCartographer detects dependencies across the following Kubernetes resource types:
| Resource | Dependencies Detected |
|---|---|
| Deployment, DaemonSet, StatefulSet, Job, CronJob, Pod, ReplicaSet | Secrets, ConfigMaps, PVCs, ServiceAccounts, imagePullSecrets (via pod spec) |
| Service | Pod/controller targets (via label selector) |
| Ingress | Backend Services, TLS Secrets |
| NetworkPolicy | Pod/controller targets (via podSelector with matchLabels + matchExpressions) |
| PodDisruptionBudget | Pod/controller targets (via selector with matchLabels + matchExpressions) |
| HorizontalPodAutoscaler | Scale target (via scaleTargetRef) |
| RoleBinding, ClusterRoleBinding | Role/ClusterRole (via roleRef), ServiceAccounts (via subjects) |
| Any resource | Owner references (ownerRef) |
| Format | Flag | Output | Notes |
|---|---|---|---|
| DOT | --output-format dot |
stdout or file | Default. Use with GraphViz or other DOT renderers |
| Mermaid | --output-format mermaid |
stdout or file | Renders natively in GitHub, Notion, Confluence |
| JSON | --output-format json |
stdout or file | Structured graph with nodes and edges arrays |
| PNG | --output-format png |
file only | Requires GraphViz installed |
| SVG | --output-format svg |
file only | Requires GraphViz installed |
- No CRD support — Custom Resource Definitions are parsed but their internal references are not analyzed.
- No cross-namespace resolution — All resources are assumed to be in the same namespace.
- No Kustomize support — Only raw YAML files, Helm charts, and live clusters are supported as input.
The default location of cartographer's configuration file if the --config flag is undefined is $HOME/.cartographer.yaml. A reference config ships with the repo at .cartographer.yaml.
Cartographer excludes ReplicaSet and Pod by default. These are auto-managed by controllers (Deployments create ReplicaSets, which create Pods) and add noise to the graph. To see everything, override with an empty list in your config:
exclude:
kinds: []log:
level: "info" # Log level: debug, info, warn, error
cluster:
kubeconfig: "" # Path to kubeconfig (default: $KUBECONFIG or ~/.kube/config)
context: "" # Kube context (default: current-context)
exclude:
kinds: # Resource kinds to exclude from ALL input modes
- ReplicaSet # (default) auto-managed by Deployments
- Pod # (default) auto-managed by ReplicaSets, Jobs, etc.
names: # Resource names to exclude from ALL input modes
- kube-root-ca.crt # (example) auto-created system ConfigMapThe exclude stanzas apply universally to YAML, Helm, and live cluster inputs. Kind matching is case-insensitive (configmap matches ConfigMap).
make lintThis runs golangci-lint with your configuration, ensuring consistent code style.
make testA coverage report is generated upon completion, with coverage typically above 80% due to thorough unit tests.
To build Cartographer as a CLI executable:
make buildThe binary is placed in the build/ directory.
Cartographer can be containerized for easy deployment or CI/CD usage.
make dockerMount your manifest file and an output directory:
docker run --rm \
-v /path/to/manifest.yaml:/input/manifest.yaml \
-v $(pwd)/output:/output \
cartographer:latest analyze --input /input/manifest.yaml --output-file /output/graph.dotPass Helm repos via the HELM_REPOS environment variable (comma-separated name=url pairs):
docker run --rm \
-e HELM_REPOS="bitnami=https://charts.bitnami.com/bitnami" \
-v $(pwd)/output:/output \
cartographer:latest analyze --chart bitnami/nginx --output-file /output/nginx.dotMount your values file into the container:
docker run --rm \
-e HELM_REPOS="bitnami=https://charts.bitnami.com/bitnami" \
-v /path/to/values.yaml:/input/values.yaml \
-v $(pwd)/output:/output \
cartographer:latest analyze --chart bitnami/postgresql --values /input/values.yaml --output-file /output/postgresql.dotCartographer uses GoReleaser for automated releases. Pushing a version tag triggers the GitHub Actions release pipeline, which builds cross-platform binaries and creates a GitHub Release.
git tag v1.0.0
git push origin v1.0.0This will:
- Build binaries for Linux, macOS, and Windows (amd64 + arm64)
- Inject version, commit, and build date via
-ldflags - Create a GitHub Release with archives and checksums
Run cartographer version to verify the build info.
Contributions are welcome! If you find a bug or have an improvement, feel free to:
- Open an issue describing your idea or problem.
- Submit a pull request with your changes and relevant tests.
This project is licensed under the Apache 2.0 License. See the LICENSE file for full details.

