formae Documentation
repository·main·Indexed 20 days ago
https://github.com/platform-engineering-labs/formaeformae is an agentic Infrastructure-as-Code (IaC) tool that uses Pkl to manage infrastructure. It eliminates the need for state files by automatically synchronizing infrastructure code with real-world changes. The documentation covers the core tool, the experimental PKL Generator for creating schemas from resources, and the SDK for developing resource plugins, including the ResourcePlugin interface, plugin conformance testing, and manifest configuration.
What's inside formae
- formae is an agentic Infrastructure-as-Code (IaC) tool designed to treat infrastructure entirely as code. Unlike traditional IaC tools, it does not require users to maintain secondary artifacts like state files. Instead, it keeps infrastructure code automatically in sync with the actual state of the environment by detecting and merging changes made outside of the tool (e.g., via ClickOps or other IaC tools) directly back into the versioned code.
How the `formae` binary is resolved for tests
mainThe harness automatically selects the appropriate
formaebinary for each test run based on the following priority:- Explicit Binary: If
FORMAE_BINARYis set, that exact path is used. - Version Pinning: If
FORMAE_VERSIONis set, the harness searches for that exact version in the stable channel, then the dev channel. - Plugin Requirements: The harness reads
minFormaeVersionfrom the plugin'sformae-plugin.pkland looks for the highest matching release in the stable channel. - Fallback: If the stable channel cannot satisfy
minFormaeVersion, the harness falls back to the dev channel.
If no version can satisfy the
minFormaeVersionfloor, the test fails.- Explicit Binary: If
Handle async operations and progress polling
mainFor long-running cloud operations, your CRUD methods should return a
*resource.ProgressResult(embedded in the result type) withOperationStatus.InProgressand the cloud-sideNativeID. The agent will then poll your plugin'sStatusmethod on a schedule until the operation reachesSuccessorFailure.Automatic Retries: The SDK automatically retries operations if you return recoverable error codes. Non-recoverable error codes will terminate the operation immediately.
How to use formae in your organization
mainformae is designed to support various engineering roles and workflows:
- Core Platform Engineers: Manage main infrastructure code and large, system-wide changes, often using GitOps workflows.
- Developers and Specialized Engineers: Apply small, schema-safe patches to specific resources to minimize blast radius.
- On-Call Engineers: Perform emergency fixes safely by focusing on targeted changes.
- Specialized Teams (Security/Cost): Apply wide-reaching but targeted changes across the infrastructure.
- Co-existence with other tools: formae automatically discovers and merges changes made by other tools (like Terraform) or manual actions (ClickOps), ensuring the code remains the single source of truth.
Plugin development conventions and constraints
mainWhen developing resource plugins, adhere to these constraints:
- Statelessness: Plugins must be stateless. The agent may restart or run operations concurrently. Persist state in the cloud or via resource properties.
- Mandatory
NativeID: EveryProgressResultmust include aNativeIDso the agent can re-find the resource during polling. - JSON Round-tripping: Resource properties travel as JSON (
json.RawMessage). Ensure they round-trip cleanly through your Pkl schema. - Error Code Accuracy: Use the correct
resource.OperationErrorCode. ReturningInternalFailurefor a permanent error causes unnecessary retries, while usingThrottlingfor auth failures masks the root cause. - No Pointer Sharing: Everything is serialized via MessagePack + zstd. Do not rely on shared memory/pointers across the agent-plugin boundary.
Configure Pkl test fixtures for conformance tests
mainThe conformance suite discovers Pkl test fixtures in a
testdata/directory located next to your test file. For every base resource file, the suite looks for specific optional suffixes to drive different lifecycle steps:File Role <resource>.pklRequired. Declares the resource to create and the expected post-create state. <resource>-update.pklOptional. Same resource with at least one mutable property changed; drives the update step. <resource>-replace.pklOptional. Same resource with a create-only field changed; drives the replace step (expects NativeIDto change).Note: A unique identifier
FORMAE_TEST_RUN_IDis provided as an environment variable to Pkl fixtures, allowing you to parameterize resource names to avoid collisions during concurrent runs.Opt-in to ObservablePlugin and Configurable interfaces
mainYou can extend your
ResourcePluginimplementation by adding these optional interfaces to the same struct:ObservablePlugin: Allows you to receive aLoggerandMetricRegistryat startup. The SDK also injects these into thecontext.Contextof every CRUD method. Useplugin.LoggerFromContext(ctx)andplugin.MetricsFromContext(ctx)to access them.Configurable: Allows you to receive plugin-specific configuration asjson.RawMessage(sourced from the user'sformae.conf.pkl) during startup, before the plugin announces itself to the agent.
Install formae
mainTo install formae, follow the official Quick Start guide at https://docs.formae.io/en/latest/.Run plugin conformance test suites
mainYou can run the conformance tests using standard
go testcommands. Use environment variables to control which suite runs, filter specific tests, or enable parallel execution.Run all tests
go test -v ./...Run CRUD tests only (with filtering)
Use
FORMAE_TEST_TYPE=crudto skip discovery, andFORMAE_TEST_FILTERto specify resource types (comma-separated or regex).FORMAE_TEST_TYPE=crud FORMAE_TEST_FILTER="s3-bucket,iam-group" go test -v ./...Run Discovery tests in parallel
Use
FORMAE_TEST_TYPE=discoveryandFORMAE_TEST_PARALLEL=true.FORMAE_TEST_TYPE=discovery FORMAE_TEST_PARALLEL=true go test -v ./...# Both suites go test -v ./... # CRUD only, on a subset of resource types FORMAE_TEST_TYPE=crud FORMAE_TEST_FILTER="s3-bucket,iam-group" go test -v ./... # Discovery only, in parallel FORMAE_TEST_TYPE=discovery FORMAE_TEST_PARALLEL=true go test -v ./...Workflow to run the PKL Generator
mainTo use the PKL Generator, follow this specific workflow.
Prerequisites
- Build
formaeusing the following commands:make build build-debug build-pkl-local - Navigate to the generator directory and run:
pkl project resolve
Generation Steps
- Extract resources: Export your resources into JSON format using the
formae extractcommand:formae extract --output-schema json --query="managed:false" --output-consumer machine - Split JSON files: Use the
split.pyhelper script to break the extracted JSON files into smaller, manageable pieces (recommended for large files). - Run generation: Execute the
run_generator.pyscript to process the split JSON files and generate the PKL schema.
Critical Constraint
File Locality: When running the generator, all files must reside in the same directory or in subdirectories. The PKL engine cannot access files located outside of the current working directory tree.
# 1. Build formae make build build-debug build-pkl-local # 2. Resolve PKL project pkl project resolve # 3. Extract resources formae extract --output-schema json --query="managed:false" --output-consumer machine # 4. Split (using split.py) python3 split.py <input_file> # 5. Run generator (using run_generator.py) python3 run_generator.py- Build
Implement plugin conformance tests
mainTo validate a
formaeresource plugin, add two conformance test functions to a_test.gofile in your plugin repository. This uses theplugin-conformance-testsharness to exercise your plugin through the realformaeCLI and agent lifecycle (CRUD and discovery).Module path:
github.com/platform-engineering-labs/formae/pkg/plugin-conformance-testspackage main import ( "testing" conformance "github.com/platform-engineering-labs/formae/pkg/plugin-conformance-tests" ) func TestPluginConformance(t *testing.T) { conformance.RunCRUDTests(t) } func TestPluginDiscovery(t *testing.T) { conformance.RunDiscoveryTests(t) }Initialize a new formae resource plugin
mainThe recommended way to start a new resource plugin is to use the bundled scaffolding command. This clones the
formae-plugin-templaterepository and configures it with the necessary SDK wiring, a manifest, a Pkl schema package, and a conformance test suite usingpkg/plugin-conformance-teststo validate your plugin end-to-end.formae plugin init