Skip to main content
The meta block declares deployment configuration for a specific stack. It lives inside a stack {} body and is the highest-priority level in the four-level resolution chain.

Syntax

stack "networking" {
    meta {
        context = "prod_us"
        engine  = "native"
        runtime = "xcl"
    }

    vpc = aws.ec2.Vpc {
        cidr_block = "10.0.0.0/16"
    }
}
meta takes no label. Only one meta {} block is allowed per stack {}. A duplicate produces a hard parse error.

context field

The context field opts the stack into a named context {} block declared in the same compilation unit:
stack "networking" {
    meta {
        context = "prod_us"
    }
    // ...
}
The referenced context must be declared in the same directory’s .xcl files. An undeclared name is a hard compile error:
meta context "prod_eu" is not declared — add: context prod_eu { ... }
context can be combined with any other meta {} field. Fields declared in meta {} always override the context.

Fields

FieldTypeDefaultDescription
contextstring""Name of a declared context {} to inherit from
enginestring"native"Execution engine — highest-priority override
runtimestring"xcl"Codegen runtime — highest-priority override
backend {}blockState backend override
provider {}blockProvider config override
tags {}blockAdditional tags (merged additively)
hooks {}blockHook scripts (concatenated at end)
labels {}blockAdditional labels for workspace match {} evaluation
ai {}blockAI feature settings override
scan {}blockSecurity scan settings override
telemetry {}blockTelemetry settings override
history {}blockHistory settings override

Defaults

When no workspace {}, context {}, or meta {} declares a field, the compiled defaults are:
FieldDefault
engine"native"
runtime"xcl"
backendlocal file backend at <dir>/.ubx/state/
A stack with no meta {} block and no workspace or context configuration ships with the native engine, xcl runtime, and a local file state backend — zero configuration required for new stacks.

Resolution chain

Configuration is resolved in four steps. Later steps override earlier ones:
  1. Universal workspace {} — no match {} — lowest priority
  2. Label-matched workspace {} — scoped workspace whose match {} keys all appear in the stack’s effective labels
  3. context {} — the context named by meta { context = "..." } (if any)
  4. meta {} — per-stack override — highest priority

Tags and hooks merge additively

Tags and hooks are exceptions to the “most specific wins” rule:
  • Tags: All tags {} blocks from all four levels are merged. Keys from later levels win on conflict, but keys unique to earlier levels are preserved. A tag set at the workspace level is not removed by a more specific block.
  • Hooks: Hook lists from all four levels are concatenated in resolution order. Workspace hooks run first; meta hooks run last.
All other fields follow “most specific wins” — the most specific non-empty value wins.

Example resolution

// workspace.xcl
workspace {
    name   = "platform"
    engine = "native"
    tags {
        project = "platform"
        owner   = "infra-team"
    }
    hooks {
        before_ship = ["./scripts/global-check.sh"]
    }
}

workspace {
    name = "platform-prod"
    match {
        env = "prod"
    }
    backend s3 {
        bucket = "prod-state"
        key    = "platform"
    }
    tags {
        cost_center = "platform-prod"
    }
}

context prod_us {
    labels {
        env    = "prod"
        region = "us-east-1"
    }
    tags {
        environment = "production"
    }
    hooks {
        before_ship = ["./scripts/prod-checks.sh"]
    }
}
// networking.xcl
stack "networking" {
    meta {
        context = "prod_us"
        tags {
            stack = "networking"
        }
        hooks {
            after_ship = ["./scripts/update-dns.sh"]
        }
    }
    // ...
}
Resolved configuration for networking:
FieldSourceValue
engineuniversal workspace"native"
backendlabel-matched workspaces3://prod-state/platform
tags.projectuniversal workspace"platform"
tags.owneruniversal workspace"infra-team"
tags.cost_centerlabel-matched workspace"platform-prod"
tags.environmentcontext"production"
tags.stackmeta"networking"
before_ship[0]universal workspace"./scripts/global-check.sh"
before_ship[1]context"./scripts/prod-checks.sh"
after_ship[0]meta"./scripts/update-dns.sh"

hooks sub-block

stack "networking" {
    meta {
        context = "prod_us"
        hooks {
            before_ship = ["./scripts/lock-state.sh"]
            after_ship  = ["./scripts/unlock-state.sh", "./scripts/notify.sh"]
        }
    }
    // ...
}
Hooks declared in meta {} are appended to any hooks from the workspace and context. The full execution order is: workspace hooks → context hooks → meta hooks.

labels sub-block

Labels declared in meta {} extend the context’s labels for workspace match {} evaluation. This allows a stack to carry extra labels beyond what the context provides:
stack "networking" {
    meta {
        context = "prod_us"
        labels {
            tier = "critical"
        }
    }
    // ...
}
A workspace with match { tier = "critical" } would now apply to this stack in addition to the regular prod_us labels.

Identifier naming

Context names and label keys must use underscores, not hyphens. XCL identifiers follow the pattern [a-zA-Z_][a-zA-Z0-9_]*.
// Correct
context prod_us { }
meta { context = "prod_us" }

// Error — hyphens are not valid in XCL identifiers
context prod-us { }   // ✗ parse error
meta { context = "prod-us" }  // ✗ references an undeclared context

Stack with no meta

A stack with no meta {} block inherits from the universal workspace only. Label-scoped workspaces and contexts do not apply.
stack "infra" {
    // No meta {} — uses universal workspace defaults only.
    bucket = aws.s3.BucketV2 {
        bucket = "shared-infra"
    }
}

Error conditions

Undeclared context

meta context "prod_eu" is not declared — add: context prod_eu { ... }

Duplicate meta block

duplicate meta block — only one meta {} is allowed inside stack {}

Invalid engine value

engine "lambda" is not valid — valid values: native, pulumi, terraform

Invalid runtime value

runtime "ruby" is not valid — valid values: xcl, python, typescript, go

Incompatible engine / runtime

runtime "python" requires engine "pulumi" — engine "native" is not compatible