formae Documentation

repository·main·Indexed 20 days ago

https://github.com/platform-engineering-labs/formae

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

Tokens
43.5K
Snippets
136
Records
205
Agent score
69%

What's inside formae

  1. What is formae?

    main
    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.
  2. How the `formae` binary is resolved for tests

    main

    The harness automatically selects the appropriate formae binary for each test run based on the following priority:

    1. Explicit Binary: If FORMAE_BINARY is set, that exact path is used.
    2. Version Pinning: If FORMAE_VERSION is set, the harness searches for that exact version in the stable channel, then the dev channel.
    3. Plugin Requirements: The harness reads minFormaeVersion from the plugin's formae-plugin.pkl and looks for the highest matching release in the stable channel.
    4. Fallback: If the stable channel cannot satisfy minFormaeVersion, the harness falls back to the dev channel.

    If no version can satisfy the minFormaeVersion floor, the test fails.

  3. Handle async operations and progress polling

    main

    For long-running cloud operations, your CRUD methods should return a *resource.ProgressResult (embedded in the result type) with OperationStatus.InProgress and the cloud-side NativeID. The agent will then poll your plugin's Status method on a schedule until the operation reaches Success or Failure.

    Automatic Retries: The SDK automatically retries operations if you return recoverable error codes. Non-recoverable error codes will terminate the operation immediately.

  4. How to use formae in your organization

    main

    formae 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.
  5. Plugin development conventions and constraints

    main

    When 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: Every ProgressResult must include a NativeID so 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. Returning InternalFailure for a permanent error causes unnecessary retries, while using Throttling for 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.
  6. Configure Pkl test fixtures for conformance tests

    main

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

    FileRole
    <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 NativeID to change).

    Note: A unique identifier FORMAE_TEST_RUN_ID is provided as an environment variable to Pkl fixtures, allowing you to parameterize resource names to avoid collisions during concurrent runs.

  7. Opt-in to ObservablePlugin and Configurable interfaces

    main

    You can extend your ResourcePlugin implementation by adding these optional interfaces to the same struct:

    • ObservablePlugin: Allows you to receive a Logger and MetricRegistry at startup. The SDK also injects these into the context.Context of every CRUD method. Use plugin.LoggerFromContext(ctx) and plugin.MetricsFromContext(ctx) to access them.
    • Configurable: Allows you to receive plugin-specific configuration as json.RawMessage (sourced from the user's formae.conf.pkl) during startup, before the plugin announces itself to the agent.
  8. Run plugin conformance test suites

    main

    You can run the conformance tests using standard go test commands. 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=crud to skip discovery, and FORMAE_TEST_FILTER to 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=discovery and FORMAE_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 ./...
  9. Workflow to run the PKL Generator

    main

    To use the PKL Generator, follow this specific workflow.

    Prerequisites

    1. Build formae using the following commands:
      make build build-debug build-pkl-local
    2. Navigate to the generator directory and run:
      pkl project resolve

    Generation Steps

    1. Extract resources: Export your resources into JSON format using the formae extract command:
      formae extract --output-schema json --query="managed:false" --output-consumer machine
    2. Split JSON files: Use the split.py helper script to break the extracted JSON files into smaller, manageable pieces (recommended for large files).
    3. Run generation: Execute the run_generator.py script 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
  10. Implement plugin conformance tests

    main

    To validate a formae resource plugin, add two conformance test functions to a _test.go file in your plugin repository. This uses the plugin-conformance-tests harness to exercise your plugin through the real formae CLI and agent lifecycle (CRUD and discovery).

    Module path: github.com/platform-engineering-labs/formae/pkg/plugin-conformance-tests

    package 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)
    }
  11. Initialize a new formae resource plugin

    main

    The recommended way to start a new resource plugin is to use the bundled scaffolding command. This clones the formae-plugin-template repository and configures it with the necessary SDK wiring, a manifest, a Pkl schema package, and a conformance test suite using pkg/plugin-conformance-tests to validate your plugin end-to-end.

    formae plugin init