Skip to content

Latest commit

 

History

History
203 lines (149 loc) · 7.34 KB

local-dialect.md

File metadata and controls

203 lines (149 loc) · 7.34 KB
title Use a local Dialect
description Try a Dialect against a real plan, test its evidence, then record it in the project selection.

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.

Write the source beside the project

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

.
├── main.tf
└── dialects/
    └── network-review/
        └── dialect.rf.hcl
terraform {
  required_providers {
    random = {
      source  = "hashicorp/random"
      version = "= 3.9.1"
    }
  }
}

resource "random_pet" "service" {
  length = 2
}
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.

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

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
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.

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
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:

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
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.

Add the reviewed Dialect

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

rootform add dialects ./dialects/network-review
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

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

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
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.