EntityType

The kind of resource Terrantula tracks — TenantCluster, Tenant, Vpc, EksCluster. An EntityType declares the valid lifecycle states, the typed properties an instance carries, and any derived metrics used for placement and capacity. Every Entity is an instance of one EntityType. Phase: schema.

Minimal example

kind: EntityType
name: Tenant
states: [pending, active, suspended]
initialState: pending

Fields

FieldTypeRequiredDescription
kind"EntityType"yesDiscriminator. Always EntityType.
namestringyesUnique type name within the project (e.g. TenantCluster). Referenced by Cells, RelationshipTypes, Actions, and Entities.
displayNamestringnoHuman label for the UI. Defaults to name.
statesstring[]yesAll valid lifecycle states. active and failed are always implicitly available even if omitted.
initialStatestringyesState assigned to a newly created Entity. Must be one of states.
propertiesProperty[]noTyped properties an instance carries. Default [].
metricsMetric[]noNamed, sourced values (derived, pushed, or manual) used for capacity and placement. Default [].
constraintsConstraint[]noPer-entity ceilings on a metric. Default [].
syncTrackedbooleannoWhether entities of this type carry a sync-freshness pill. Default true.
syncFreshnessSyncFreshnessnoPer-type override for the freshness pill thresholds.
applierstringnoName of an Action to auto-fire when an entity of this type is created. The Action must have associatedWith.entityType matching this type.

Property

A typed property definition (shared by EntityType, RelationshipType, and Action parameters).

FieldTypeRequiredDescription
namestringyesProperty key.
type"string" | "integer" | "number" | "boolean"yesValue type.
titlestringnoHuman label.
descriptionstringnoHelp text.
requiredbooleannoWhether a value must be supplied. Default false.
defaultstring | number | booleannoDefault value.
enumstring[]noAllowed values. Only valid when type is string.

Metric

A named value attached to entities of this type.

FieldTypeRequiredDescription
namestringyesMetric name (e.g. tenant-count).
unitstringyesDisplay unit — integer, percentage, cores, GB.
sourceMetricSourceyesHow the value is computed.

MetricSource

Discriminated on type:

typeExtra fieldsBehavior
derivedderivedFrom: "relationship-count" | "sum", optional filter: { entityType?, relationshipType?, states? }Recomputed by Terrantula from matching relationships as they are created/deleted.
pushSet by an external pusher via the API.
manualSet by hand.

Constraint

FieldTypeRequiredDescription
metricstringyesName of a metric declared on this type.
maxnumberyesPer-entity ceiling for that metric.

SyncFreshness

FieldTypeRequiredDescription
greenSecondspositive integernoSeconds after which an entity is no longer "fresh". UI default 300.
yellowSecondspositive integernoSeconds after which an entity tips from "stale" to "very stale". UI default 3600.

Annotated example

The TenantCluster type from the SaaS-tenants demo. The tenant-count metric is derived — Terrantula recomputes it from the count of active runs_on relationships pointing at each cluster, so capacity decisions always reflect real allocation.

apiVersion: terrantula.io/v1
kind: EntityType
metadata:
  name: TenantCluster
spec:
  displayName: Tenant Cluster
  states: [provisioning, active, draining, decommissioned]
  initialState: provisioning
  properties:
    - name: region
      type: string
      required: true
    - name: tier
      type: string
      enum: [basic, premium]
      required: true
    - name: kubernetes_version
      type: string
      required: true
    - name: arn
      type: string
      description: AWS EKS cluster ARN
  metrics:
    - name: tenant-count
      unit: integer
      source:
        type: derived
        derivedFrom: relationship-count
        filter:
          relationshipType: runs_on
          states: [active]
  constraints:
    # Cap each cluster at 50 active tenants.
    - metric: tenant-count
      max: 50

The applier field wires an EntityType to an Apply Action — used in the multi-stack greenfield pattern where every entity owns its own Terraform stack:

kind: EntityType
name: AWSAccount
states: [pending, applying, active, deprovisioning, decommissioned, failed]
initialState: pending
applier: ApplyAWSAccount   # auto-fires when an AWSAccount entity is created
properties:
  - { name: customer_id, type: string, required: true }

Caveats

INFO

initialState must appear in states. active and failed are always available implicitly, so a type with states: [active] and initialState: activeis valid.

WARNING

Removing a state that entities are currently in, or removing a property that has existing values, is a breaking schema change. apply rejects it unless you pass force: true.

NOTE

A constraint is a per-entity ceiling. A fleet-wide ceiling lives on the Cell (constraints[].aggregate), not here.

NOTE

applier and the Action it names must agree: the Action's associatedWith.entityType must equal this type's name, validated at apply.