terrably

Compatibility

Which Terraform provider SDK features terrably supports today, and which patterns are not yet possible.

This page documents the current feature support matrix for terrably compared to the Terraform Plugin Protocol v6 and the official Go SDK.

The items marked Not supported will cause Terraform to surface a generic error or silently ignore the feature. If your provider requires one of these patterns, please open an issue.


Supported today

FeatureNotes
Managed resources (CRUD + plan hook)Full lifecycle: create, read, update, delete, plan
Data sourcesRead-only
Provider functions (Terraform ≥ 1.8)Parameters, variadic, return type, deprecation
terraform importImplement import() on a resource
State schema migration (upgrade)Increment version and implement upgrade()
requires_replace attributesForce-replaces on attribute change
sensitive attributesRedacted in plan output
write_only attributes (Terraform ≥ 1.11)Accepted but never stored in state
Block-level descriptions and deprecationBlockOptions on Block / Schema constructor
Nested blocks: single, list, set, map, groupAll five nesting modes
All scalar types: string, number, bool
Collection types: list, set, map
object attribute type: single, list, set, map nestingUse ObjectAttribute — HCL = syntax, not block syntax
normalizedJson typeJSON stored as a sorted-key string; key-order changes are not diffs
Structured loggingcreateLogger() / TF_LOG_PROVIDER

object attribute type

Use ObjectAttribute to define a typed object on a resource attribute. This uses HCL assignment (=) syntax, unlike NestedBlock which uses block syntax.

Provider schema (TypeScript)

import { Attribute, ObjectAttribute, types } from "terrably";

new ObjectAttribute("metadata", [
  new Attribute("owner",       types.string(), { optional: true, computed: true }),
  new Attribute("environment", types.string(), { optional: true, computed: true }),
], "single", { optional: true, computed: true })

Terraform configuration (HCL)

resource "mycloud_server" "web" {
  name = "web-01"

  metadata = {
    owner       = "alice"
    environment = "prod"
  }
}

Nesting modes

ModeHCL shapeTypeScript nesting arg
"single"attr = { key = "val" }"single" (default)
"list"attr = [{ key = "val" }, ...]"list"
"set"attr = [{ key = "val" }, ...]"set"
"map"attr = { label = { key = "val" } }"map"

For "set" nesting, terrably compares elements field-by-field (order-insensitive) so a reordered set does not appear as a plan diff.

ObjectAttribute vs NestedBlock

Both represent a group of typed sub-fields. The difference is purely syntactic –

ObjectAttributeNestedBlock
HCL syntaxattr = { ... }attr { ... }
SDK classObjectAttributeNestedBlock / Block
Supports nullYes (if optional)No — blocks cannot be null
Terraform type systemobject(...) attributeBlock (no type in protocol)

Not supported

tuple type

A fixed-length, heterogeneously-typed list — e.g. tuple([string, number, bool]).

What you cannot write today

resource "mycloud_route" "example" {
  # "range" is [start_port, end_port] — both numbers but positional semantics
  range = [8080, 8090]
}

Workaround

Use a list(number) attribute with a validate() check, or two separate attributes (range_start, range_end).


dynamic type

An attribute whose type is not known until runtime (cty.DynamicPseudoType in Go). Terraform serialises it with both the type and value in the msgpack payload.

What you cannot write today

resource "mycloud_config" "example" {
  # "value" can be a string, number, list, or object depending on context
  value = { key = "hello" }
}

Workaround

Use normalizedJson to store the value as a JSON string, or use a NestedBlock to represent the structure explicitly.


Ephemeral resources (Terraform ≥ 1.10)

Resources whose values are available during plan/apply but are never written to state. Designed for short-lived secrets (API tokens, one-time passwords, TLS certificates).

What you cannot write today

# provider.tf
ephemeral "mycloud_token" "deploy" {
  role = "deployer"
  ttl  = "15m"
}

resource "mycloud_server" "example" {
  api_token = ephemeral.mycloud_token.deploy.value
}

Attempting to use an ephemeral resource with a terrably provider will result in –

Error: Ephemeral resources not supported

There is no workaround yet.

Ephemeral resources require implementing the OpenEphemeralResource, RenewEphemeralResource, and CloseEphemeralResource RPCs plus advertising the capability in GetMetadata.


MoveResourceState (renamed / moved resources)

Allows Terraform's moved block to move state from one resource type to another across providers — for example, renaming a resource type in a new major provider version.

What you cannot write today

# After renaming mycloud_instance → mycloud_server:
moved {
  from = mycloud_instance.web
  to   = mycloud_server.web
}

Cross-type moves between different resource types within the same provider do work through normal Terraform state manipulation; what is not supported is provider-assisted cross-type moves where the provider validates and transforms state.

Attempting a cross-provider moved block that reaches this RPC will result in –

Error: MoveResourceState is not implemented

There is no workaround yet.


Private provider data (per-resource opaque bytes)

Terraform passes an opaque []byte blob (planned_private / private) between plan and apply on a per-resource basis. Go providers use this to store information that should influence apply but must not be visible to users (e.g. the ETag of a resource fetched at plan time, or a lock token).

What you cannot do today

The private field is silently discarded — terrably always returns private: new Uint8Array(). If you return a value from plan() that depends on external state fetched at plan time, you cannot safely pass it to apply() through private data.

Workaround

Store any plan-time state as a computed attribute in the resource schema. This is slightly less clean (it appears in terraform show) but functionally equivalent for most use cases.


Capability summary

Terraform featureSupportedNotes / WorkaroundTracking issue
Managed resources
Data sources
Provider functions
terraform import
State schema migration
object attribute type
tuple typeUse separate attributes or list + validation#19
dynamic typeUse normalizedJson or explicit schema#20
Ephemeral resourcesNot prioritised yet#21
moved block (cross-type)Not prioritised yet
Private provider dataUse a computed attribute instead#23
Resource identity schemasReturns empty; not prioritised yet#24
List resourcesTerraform list command; not prioritised yet#25
State storesProvider-managed state backends; not prioritised yet
ActionsFairly new; not prioritised yet#26
GenerateResourceConfigAuto-generate HCL from imported resource
Provider meta schemaModule-level provider config

Last updated on

On this page