Skip to main content
The context block declares a named set of deployment labels and settings. Stacks opt in by naming the context in their meta {} block. A context sits between a workspace {} and a per-stack meta {} in the resolution chain.

Syntax

context prod_us {
    labels {
        env    = "prod"
        region = "us-east-1"
    }
    engine  = "native"
    runtime = "xcl"
}
The context name (prod_us) is a bare identifier immediately after the context keyword — not a quoted string. Use underscores, not hyphens: prod_us not prod-us. Context names must be unique across the compilation unit. A duplicate produces a hard compile error.

Opting in from a stack

A stack opts in to a context via the context field inside its meta {} block:
stack "networking" {
    meta {
        context = "prod_us"
    }
    // ...
}
Referencing an undeclared context name is a hard compile error:
meta context "prod_eu" is not declared — add: context prod_eu { ... }

labels sub-block

Declares the labels that this context contributes to the resolution chain. Labels are key-value string pairs. They are used by workspace {} blocks with match {} to select which scoped workspace applies.
context prod_us {
    labels {
        env    = "prod"
        region = "us-east-1"
        tier   = "critical"
    }
}
When a stack opts into prod_us, its effective labels include env = "prod", region = "us-east-1", and tier = "critical". A label-scoped workspace with match { env = "prod" } then applies to that stack.

Fields

A context {} supports the same fields as workspace {}, except name, match {}, and plugins {} (which belong only to workspace {}).
FieldTypeDefaultDescription
enginestring"native"Execution engine — overrides any workspace value
runtimestring"xcl"Codegen runtime — overrides any workspace value
backend {}blockState backend override
provider {}blockProvider config override
tags {}blockAdditional tags (merged additively with workspace tags)
hooks {}blockHook scripts (concatenated with workspace hooks)
ai {}blockAI feature toggle override
scan {}blockSecurity scan settings override
telemetry {}blockTelemetry settings override
history {}blockHistory settings override
For engine, runtime, and all sub-blocks except tags and hooks, the context value wins over the workspace value for any stack that opts into this context. Tags and hooks are always additive — they extend rather than replace.

backend sub-block

context prod_us {
    backend s3 {
        bucket = "prod-state"
        key    = "stacks/prod-us"
        encryption {
            provider = "awskms"
            key      = "alias/prod-secrets"
        }
    }
}

tags sub-block

Tags declared in a context are added to any tags set by a workspace block. They do not replace them.
context prod_us {
    tags {
        environment = "production"
        criticality = "high"
    }
}

hooks sub-block

Hooks declared in a context are appended to the workspace hooks list. Order follows the resolution chain: workspace hooks first, then context hooks.
context prod_us {
    hooks {
        before_ship = ["./scripts/prod-checks.sh"]
        after_ship  = ["./scripts/notify-oncall.sh"]
    }
}

Full example

// contexts.xcl

context prod_us {
    labels {
        env    = "prod"
        region = "us-east-1"
    }
    engine  = "native"
    runtime = "xcl"
    backend s3 {
        bucket = "prod-state"
        key    = "platform/prod-us"
        encryption {
            provider = "awskms"
            key      = "alias/prod-secrets"
        }
    }
    tags {
        environment = "production"
    }
    hooks {
        before_ship = ["./scripts/prod-checks.sh"]
    }
}

context staging_us {
    labels {
        env    = "staging"
        region = "us-east-1"
    }
    engine  = "native"
    runtime = "xcl"
    tags {
        environment = "staging"
    }
}
// networking.xcl
stack "networking" {
    meta {
        context = "prod_us"
    }

    vpc = aws.ec2.Vpc {
        cidr_block = "10.0.0.0/16"
    }
}
// app.xcl
stack "app" {
    meta {
        context = "staging_us"
    }

    bucket = aws.s3.BucketV2 {
        bucket = "app-staging"
    }
}

Resolution chain position

Context sits at step 3 in the four-level resolution chain:
  1. Universal workspace {} — lowest priority
  2. Label-matched workspace {} — fields override step 1
  3. context {} named by the stack’s meta { context = "..." } — fields override step 2
  4. meta {} inside stack {} — highest priority
Fields declared in the context override fields from any workspace block. Fields declared in meta {} override the context. See meta for the full resolution reference.

Error conditions

Duplicate context name

context "prod_us" is declared more than once

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 "xcl" requires engine "native" — engine "pulumi" is not compatible