Skip to content

A Dialect interprets provider instances. Keep its source beside the project while authoring, pass --dialect for one run, and add it to rootform.lock only after reviewing the resulting facts. This example uses random_pet to keep the plan small; the same sequence applies to a provider-specific Dialect with architectural Contexts and Relations.

Prerequisites: Rootform, Terraform, and a project directory you control. OpenTofu users run the Terraform commands with tofu. Run commands below from that directory. The plan JSON and saved plan can carry cleartext secrets in a real project; keep them out of Git. Plan inputs gives the complete export and protection procedure.

  1. Write the source beside the project

    Use this small project and Dialect source to observe one interpretation:

    Project files Files
    .
    ├── main.tf
    └── dialects/
    └── network-review/
    └── dialect.rf.hcl
    main.tf HCL
    terraform {
    required_providers {
    random = {
    source = "hashicorp/random"
    version = "= 3.9.1"
    }
    }
    }
    resource "random_pet" "service" {
    length = 2
    }
    dialects/network-review/dialect.rf.hcl RF
    dialect "network-review" {
    version = "0.1.0"
    provider "hashicorp/random" {
    version = "= 3.9.1"
    }
    }
    concept "generated-identifier" {
    description = "An identifier generated for a service."
    }
    rule "service-name" {
    match {
    kind = "resource"
    type = "random_pet"
    }
    as = concept.generated-identifier
    }

    The manifest binds the provider and the Rule identifies eligible instances. as gives an interpreted instance a Concept; this example emits no Context or Relation. Write a Dialect explains Rules, endpoint identity, null handling, and evidence tests.

  2. Export and analyze a plan

    Produce a saved plan and its JSON export. Rootform reads the completed export; it never runs Terraform or contacts the provider:

    terraform init
    terraform plan -out=plan.tfplan
    terraform show -json plan.tfplan > plan.json
    Shell

    Try the source for this run without changing the project selection:

    rootform run plan.json --plan-file plan.tfplan --require-enrichment \
    --dialect ./dialects/network-review --no-serve -o analysis.json
    Shell
    Excerpt from analysis summary OUTPUT
    Plan analyzed
    Enrichment Saved plan paired with this plan JSON (1 module)
    Architecture
    Instances 1
    Interpreted 1
    Facts none determined

    The instance is interpreted, while no facts are determined because the Rule only classifies it. Inspect the Form or rootform explain instance random_pet.service --input analysis.json when the result differs. --dialect compiles current source each run and never writes the lock.

  3. Inspect and test the Rule

    Check the Dialect source and show the Rule before recording a golden:

    rootform validate dialects ./dialects/network-review
    rootform show network-review.rule.service-name \
    --dialect ./dialects/network-review
    Shell
    Excerpt from definition OUTPUT
    network-review.rule.service-name
    Matches resource "random_pet"
    Produces network-review.concept.generated-identifier
    Defined dialect.rf.hcl:13

    validate compiles the source; show confirms the selected Rule's match and output. Neither proves what a particular plan instance did. Keep a fixture for that proof:

    Dialect fixture Files
    fixtures/network/
    ├── plan.json
    ├── plan.tfplan
    └── analysis.golden

    Copy the plan pair to the fixture. Record a reviewed golden once with rootform test ./fixtures --dialect ./dialects/network-review --update; then run the ordinary test after each Rule change:

    rootform test ./fixtures --dialect ./dialects/network-review
    Shell
    Fixture result OUTPUT
    Tests passed
    1 case

    The test analyzes plan.json, verifies the adjacent saved plan, and compares the resulting Form with analysis.golden. A mismatch is a review signal: inspect changed interpretations, facts, closures, and diagnostics before updating the golden. Test and validate covers fixture behavior.

  4. Add the reviewed Dialect

    Once its result is right, select it for this project:

    rootform add dialects ./dialects/network-review
    Shell
    Selection result OUTPUT
    rootform.lock updated
    add Dialect network-review 0.1.0 (dialects/network-review)

    The lock records the owner, version, digest, and project-relative local path. Commit it with Dialect source and reviewed fixture. Future runs use the selection through --project without the override; --locked checks that it has not drifted. If the source changes later, try it with --dialect, then run rootform update dialect network-review to record the new digest. init never adopts source drift. If your owner collides with an embedded Dialect, add requires an explicit --replace; review the loss of that embedded owner's Rules first.

Record later changes

After selection, a source edit changes the compiled content digest. A normal locked run refuses it instead of silently adopting new meaning. Continue testing the edited source with --dialect; when its fixture and analysis are right, run rootform update dialect network-review from the project root and review the lock diff. Commit the updated source, golden, and lock together.

Vendor the selection for another checkout

From the project root, copy the selected Dialect into the project so another checkout can use it without the original source directory:

rootform vendor dialects --offline
git add rootform.lock .rootform/dialects/network-review
Shell

The vendored copy lives at .rootform/dialects/network-review/. In a clone that contains the lock and this directory, prepare and analyze offline:

rootform init . --locked --offline --no-input
rootform run plan.json --plan-file plan.tfplan --locked --no-serve
Shell

See the rootform vendor dialects reference for selection requirements and other destinations, and external content storage for what to commit. For several repositories, package and publish the Dialect, then select its reviewed OCI reference in each project.

Remove the Dialect

If the project no longer needs this interpretation, remove its selection:

rootform remove dialects network-review
Shell
Selection result OUTPUT
rootform.lock updated
remove Dialect network-review 0.1.0 (dialects/network-review)

The source directory remains. A later analysis can still show the base Representation for random_pet.service, but no Rule interprets it. Reproduce an analysis offline shows how to prove another environment loaded a reviewed selection.