Multi-Cloud Infrastructure Intelligence

Every cloud.
One map.
One source of truth.

Terracarta discovers what's actually running across AWS, Azure, and GCP, understands how it's wired together, and generates import-ready Terraform from it — closing the gap between the wiki that's out of date, the console that shows what exists, and the bill that shows what it costs.

AWS · Boto3 Azure · Azure SDK GCP · Cloud SDK

Live discovery — read-only credentials

terracarta discover --provider aws --region us-east-1

aws web-server (i-abc123) in_sync
aws main-vpc (vpc-111) in_sync
aws billing-db (db-prod-1) new

terracarta graph -i resources.json

14 nodes · 19 edges
Topological order resolved — VPC → Security Group → RDS → EC2

3 clouds discovered $0 spent guessing

3 Cloud Providers
6 Normalized Resource Types
18 Terraform Template Sets
10 FinOps KPIs

The Problem

Every cloud environment splinters into three lies.

The wiki says what infrastructure should exist. The console shows what actually exists. The bill shows what it costs. None of the three agree, and reconciling them by hand doesn't scale past a handful of accounts.

📄

The wiki

Out of date the week after it's written. Documents intent, not reality — and nobody updates it when a resource is provisioned by hand.

🖥️

The console

Shows what exists right now, one account and one region at a time, with no dependency context and nothing to hand to Terraform.

💳

The bill

Shows what everything costs, but flattened by service — disconnected from which system it belongs to or whether it's actually needed.

🗺️

Terracarta discovers, graphs, and prices real infrastructure directly — so cost, dependency, and configuration live in one artifact instead of three, and stay in sync every time discovery re-runs.

How It Works

From cloud credentials to import-ready Terraform.

01 / Discover 🔎

Scan every account

Boto3, Azure SDK, and Google Cloud SDK crawl your accounts across one or many regions in a single pass, normalizing everything into a cloud-agnostic model.

02 / Store 🗄️

Persist with provenance

Every resource upserts into Postgres with full config, raw API payload, and tags. Re-discovery moves resources through new → in_sync → drifted.

03 / Graph 🕸️

Map dependencies

A NetworkX-directed graph captures attached_to, member_of, routes_to, depends_on, and uses relationships, then resolves a topological build order.

04 / Generate ⚙️

Emit Terraform & diagrams

Jinja2 templates produce modular, import-ready HCL per resource, in dependency order — with a Mermaid architecture diagram generated alongside it.

Resource Coverage

The same resource, normalized across three clouds.

Every provider maps into the same cloud-agnostic type before it enters the graph, the database, or the generator — so the rest of the system never has to know which cloud a resource came from.

Cloud-Agnostic TypeAWSAzureGCP
compute_instanceEC2Virtual MachinesCompute Engine VMs
database_instanceRDSPostgreSQL Flexible ServerCloud SQL
object_storageS3Storage AccountsCloud Storage
virtual_networkVPCVirtual NetworksVPC Networks
identity_roleIAM RolesRole AssignmentsIAM Bindings
firewall_ruleSecurity GroupsNetwork Security GroupsFirewall Rules

Generated Output

One directory per resource. Nothing to hand-write.

Output structure mirrors what terraform import expects — modular, dependency-ordered, and paired with an architecture diagram generated in the same pass. Pass --no-diagram to skip it.

terraform_output/ ├── web_server/ │ ├── main.tf │ ├── variables.tf │ └── outputs.tf ├── main_vpc/ │ ├── main.tf │ ├── variables.tf │ └── outputs.tf ├── ... └── ARCHITECTURE.md # Mermaid diagram, generated automatically

FinOps Module

Cost visibility and waste detection, wired into the same graph.

A CUR 2.0 ingestor amortizes Reserved Instance and Savings Plan costs correctly using Decimal arithmetic throughout, then rolls spend up through the dependency graph — so a shared NAT Gateway's cost is attributed across every EC2 instance behind it.

Unmanaged Spend

18.4%

Waste %

11.2%

Tag Coverage

76%

Commitment Utilization

92%

Waste Findings — ordered by monthly savings 4 detectors
Idle Compute — i-0a2f8c p95 CPU 1.8% High $412 / mo
Unattached Storage — vol-77bd21 Idle 41 days High $96 / mo
Oversized Instance — db-prod-1 p95 CPU 19% Medium $268 / mo
Orphaned NAT Gateway — nat-0912 0.4 MB/hr throughput High $32 / mo

Built to Extend

Adding a cloud, a resource type, or a KPI never touches core logic.

Cloud-agnostic core

An abstract BaseProvider interface means a new cloud provider adds zero changes to the database, graph, or generator.

Template-driven generation

A new resource type needs a Jinja2 template and a normalizer function — nothing else in the pipeline changes.

Pluggable cost allocation

Shared-dependency cost rollup runs through a pluggable AllocationStrategy, defaulting to an even split across dependents.

Read-only by design

The FinOps IAM policy is scoped to Cost Explorer, CloudWatch, the Pricing API, and the CUR bucket — nothing that can modify infrastructure.

CLI

Every workflow, one binary.

$ terracarta discover --provider aws --region us-east-1
$ terracarta generate -i resources.json -o ./terraform_output
$ terracarta visualize --group-by type
$ terracarta finops detect

REST API

FastAPI, fully async.

POST /api/v1/discovery/run
GET /api/v1/applications
POST /api/v1/generate/terraform
GET /api/v1/finops/kpis
POST /api/v1/finops/detect

Get in touch

Three sources of truth, down to one.

If your cloud footprint has outgrown the wiki and the console disagrees with the bill, that's exactly the gap Terracarta closes.

eric.e.fredericksen@gmail.com ← Back to portfolio