Step 1 — Import your TF state

Every fleet starts from infrastructure that already exists. Before you write a single entity type by hand, you bring your real Terraform state in as entities — so you're modeling reality, not a blank page. This is the cattle on-ramp: a graph view of what you actually run, in one command.

By the end of this step you'll have your existing clusters (and whatever else is in your state) showing up as entities in Terrantula's local database, ready to shape in Step 2.

What import does

terrantula import terraform reads a Terraform state file, maps each resource to a Terrantula entity using a small mapping config you provide, and applies the result. It's the same apply pipeline you'd use for hand-written catalog YAML — import just generates the entity documents for you from your state.

Two things make it safe to run against real infrastructure:

  • It never touches Terraform. Import reads a state file (or pulls one from S3 / Terraform Cloud). It does not plan, apply, or modify anything. The entities it creates are a read-only projection of your infrastructure.
  • It's idempotent. Run it again after your state changes and existing entities are updated in place; new resources are added. Nothing is destroyed unless you explicitly pass --replace.

The mapping config

Import needs to know which Terraform resource types become which entity types, and how to fill in their properties. You give it that in a YAML mapping config. Here's a minimal one — save it as tf-mapping.yaml:

sources:
  - path: terraform.tfstate
    labels:
      env: prod

mappings:
  aws_eks_cluster:
    entity_type: TenantCluster
    name: '{{ .name }}'
    properties:
      region: '{{ .arn | split ":" | index 3 }}'
      arn: '{{ .arn }}'
    labels:
      cell: '{{ .tags.cell | default "unassigned" }}'

Read it top to bottom:

  • sources — the state file(s) to read. labels here tag every entity from this source (handy for filtering later).
  • mappings — one entry per Terraform resource type. The key (aws_eks_cluster) is the TF type; entity_type is the Terrantula entity type each matching resource becomes.
  • name and properties use Go-template interpolation against each resource's attributes. {{ .name }} is the resource's name; {{ .arn | split ":" | index 3 }} pulls the region out of an EKS ARN; | default "..." supplies a fallback when an attribute is absent.

You don't have to write this from scratch. Terrantula ships starter configs you can compose with extends:aws-multi-account, kubernetes-inventory, and multi-tenant-cells cover the common shapes. To build on one, reference it and override just what you need:

extends:
  - terrantula/starters/aws-multi-account

sources:
  - path: terraform.tfstate
Start from a starter, then specialize

For your first run, point extends: at the starter closest to your stack and let it map the obvious resource types. Once you see what landed in the graph, add explicit mappings: overrides to rename entity types or compute properties the way your fleet thinks about them. The starter files under packages/cli/src/starters/are the format reference.

Run the import

Point the command at your state file and your mapping config:

terrantula import terraform \
  --state ./terraform.tfstate \
  --config ./tf-mapping.yaml

--state is a URI: a local path, s3://bucket/key, or tfc://org/workspace. Repeat the flag to merge several state files into one fleet. --config is the path to the mapping config above.

You'll see a summary like:

Mapped 3 entities and 0 relationships from 1 state file. Succeeded ✓ EntityType/TenantCluster ✓ Entity/eks-us-east-1 ✓ Entity/eks-eu-west-1 ... Apply summary: 5 succeeded, 0 failed, 0 skipped Sync-stamped 3 entities from 1 state file(s).

Notice import auto-creates a stub TenantCluster entity type if one doesn't exist yet — enough for the entities to land. In Step 2 you'll replace that stub with a proper, fully-typed definition.

Preview before you commit

Add --dry-run (or its alias --plan, for terraform planmuscle memory) to see exactly what would be created or changed without writing anything. Run it once to sanity-check your mapping, then drop the flag to apply for real.

See it in the dashboard

Open the local fleet view:

terrantula dashboard

Your browser opens to the entity browser. You'll see your clusters as TenantCluster entities — your real infrastructure, on one screen, derived straight from state. There are no tenants and no relationships yet; that's exactly what the next steps add.

The graph reflects state — it doesn't replace it

The entities you just imported are a projection. You don't change what a cluster isby editing it here. Real changes still flow through Terraform; re-running the import refreshes the projection. The dashboard stays honest because Terraform stays in charge.

What you just did

  • Wrote a mapping config that turns Terraform resource types into Terrantula entity types.
  • Imported real state as entities — read-only, idempotent, no terraform apply in sight.
  • Confirmed the fleet on screen with terrantula dashboard.

You now have entities, but they're shaped by a thin auto-generated stub. Next you'll give them a proper definition — lifecycle states, typed properties, derived metrics — and group your clusters into a cell that can place tenants.


Prev: ← Your First Fleet (overview) · Next: Step 2 — Define entity types & cells →