Types & Schema
The TfType system, Attribute, Block, NestedBlock, and Schema — terrably's building blocks for describing provider resources.
Types
Every attribute in a schema requires a TfType. Types are created via the types factory — each call returns a fresh instance.
import { types } from "terrably";Prop
Type
Composing types
types.list(types.string()) // list of strings
types.map(types.number()) // map of numbers
types.set(types.string()) // set of strings
types.list(types.map(types.bool())) // list of maps of booleansCustom TfType<T>
Implement this interface to define a custom type –
interface TfType<T = unknown> {
encode(value: T | null | UnknownType): unknown;
decode(value: unknown): T | null | UnknownType;
semanticallyEqual(a: T | null, b: T | null): boolean;
tfType(): Uint8Array; // JSON bytes, e.g. Buffer.from('"string"')
}Attribute
Describes a single field in a resource or provider schema.
import { Attribute, types } from "terrably";
new Attribute(name: string, type: TfType, options?: AttributeOptions)AttributeOptions
Prop
Type
Common patterns
// Required user input
new Attribute("name", types.string(), { required: true })
// Server-assigned, read-only
new Attribute("id", types.string(), { computed: true })
// User may set; provider fills in a default if not set
new Attribute("size", types.string(), { optional: true, computed: true, default: "small" })
// Sensitive — masked in plan output
new Attribute("token", types.string(), { required: true, sensitive: true })
// Force-replace when this changes (e.g. region or OS image)
new Attribute("region", types.string(), { required: true, requiresReplace: true })optional: true, computed: true together means "user can set it, or the provider will compute a default". This is useful for auto-assigned values like name or region that the user might want to control.
NestedBlock
Represents a block that can appear zero or more times (e.g. network_interface, tags).
import { NestedBlock, Block, Attribute, types } from "terrably";
new NestedBlock(
typeName: string,
nestingMode: NestMode,
block: Block,
options?: NestedBlockOptions
)NestMode | Terraform equivalent | TypeScript shape |
|---|---|---|
"single" | At most one block | object | null |
"list" | Ordered list of blocks | object[] |
"set" | Unordered set of blocks | object[] |
"map" | Map of blocks keyed by a label | Record<string, object> |
"group" | Exactly one block (implicit) | object |
Example — resource with a tags nested block
import { Schema, Attribute, Block, NestedBlock, types } from "terrably";
new Schema([
new Attribute("id", types.string(), { computed: true }),
new Attribute("name", types.string(), { required: true }),
], [
new NestedBlock("tags", "set", new Block([
new Attribute("key", types.string(), { required: true }),
new Attribute("value", types.string(), { required: true }),
]), { minItems: 0, maxItems: 10 }),
])SET blocks are order-insensitive. "set" nesting uses semantic equality — two NestedBlock values whose items are identical but in a different order are treated as unchanged. Use "list" when order matters.
BlockOptions
Pass BlockOptions as the third argument to new Block(...) to set documentation or deprecation on the block itself — distinct from per-attribute options.
Prop
Type
new NestedBlock("legacy_config", "single", new Block(
[new Attribute("endpoint", types.string(), { optional: true })],
[],
{ deprecated: true, deprecationMessage: "Use the top-level endpoint attribute instead." }
))# Terraform config using the tags block
resource "mycloud_server" "example" {
name = "web-1"
tags {
key = "env"
value = "production"
}
tags {
key = "team"
value = "platform"
}
}Schema
Top-level schema for a resource, data source, or provider.
import { Schema } from "terrably";
new Schema(
attributes: Attribute[] = [],
blockTypes: NestedBlock[] = [],
version: number = 0,
blockOpts?: BlockOptions // optional — description/deprecation for the block itself
)version starts at 0. Increment it whenever the shape of stored state changes (renamed or removed attributes) and implement Resource.upgrade() to migrate old state. See Schema migration for patterns.
Use blockOpts to set a description or deprecation message on the resource's top-level block (shown in terraform providers schema and the Terraform Registry) –
new Schema(
[new Attribute("id", types.string(), { computed: true })],
[],
1,
{ description: "Manages a cloud server instance.", deprecated: false }
)Last updated on