Self-hosted service
platform-engineering-labs/formae avatar
platform-engineering-labs/formae

formae discovers running infrastructure and hands back Pkl code

Open-source Infrastructure As Code that starts from what already runs. formae discovers your estate, versions drift and hands back current code. A Terraform and Pulumi alternative built on Pkl, with an MCP server for AI agents.

775 stars43 forksGoNOASSERTION

At a glance

What is it?
formae is an open source infrastructure as code system that scans a cloud account or cluster, records every resource and every out of band change, and generates Pkl definitions from what is already running, with reconcile and patch apply modes. It suits teams without a clean IaC history, and it requires an always on agent rather than a CLI you run on demand.
Who is it for?
Adopt formae when you have infrastructure that predates any infrastructure as code practice, when you want the existing estate to become code rather than starting from an empty plan, and when you can run an always on agent with credentials for the accounts it watches. Do not adopt it if you need a CLI that runs on demand with no daemon, or if your process requires a state file you can read and diff yourself.
Can I use it commercially?
Check first. The repository uses a licence we do not classify automatically, so read its LICENSE file before any commercial use.
Is it still maintained?
Yes. The repository last received commits 15 days ago.
What is it written in?
Mainly Go, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.

Editorial analysis

The starting point is what already runs

formae is described as open source infrastructure as code that starts from what already runs. That is the whole idea, and it is a different starting position from the usual one. Most IaC tooling assumes you describe a desired state and then create resources to match, which means an existing estate has to be imported by hand or by a script that someone wrote. formae inverts that. It discovers the infrastructure running in your cloud accounts and clusters, keeps a versioned record of every resource and every change to it, whoever made the change, and applies changes at any granularity, from a single property to a whole environment. The project can be used as an alternative to Terraform, OpenTofu or Pulumi, or alongside them, Helm and manual changes, on AWS, Azure, Google Cloud, Kubernetes and other platforms reached through plugins. The audience is a platform team or an SRE group staring at an account that grew organically and has no source of truth, and the output it produces is a Pkl file that describes resources which already exist.

Discovery and synchronization run on timers inside a resident agent

Two background loops do the work, and both have default intervals. Discovery scans each target, where a target is a cloud account, region or cluster, every 10 minutes by default, and records resources it does not manage as unmanaged. Unmanaged resources are read-only to formae until you bring them under management, which is a sensible safety property: nothing gets adopted or deleted because a scan found it. Synchronization runs every 5 minutes by default, reading the resources formae knows about and recording any change made outside formae, which other tools usually call drift. The documentation is explicit about the limits of this: it does not edit your code repository or change cloud resources on its own. What it does is keep a history. The agent is a separate process that executes operations and stores state in its own database, with SQLite, PostgreSQL, Aurora Data API or SQL Server as the options. The CLI talks to that agent. That is the structural difference from Terraform or Pulumi, both of which are CLIs that run on demand, and it is the reason formae has an install step that starts a service rather than just a binary you call.

Extract turns a running bucket into a Pkl file

The extract command is the feature that makes the discovery story useful. It writes Pkl for any set of resources, managed or not, so code can be generated from the running infrastructure instead of written by hand. The example in the documentation runs the agent, asks for resources that formae found but does not manage, and then generates code for a specific type:

bash
formae agent start                                            # in its own terminal
formae inventory resources --query="managed:false"            # resources formae found but does not manage
formae extract --query 'type:AWS::S3::Bucket' ./buckets.pkl   # code for them, generated from what is running

The generated file is a forma, written in Pkl, which the documentation describes as a configuration language with types and constraints. Resource types are Pkl schemas supplied by the plugins, so a forma is type checked before anything is applied. That is the argument for Pkl over a plain config format, since the schema for a bucket is not a convention that the tool checks but a type the file is checked against. The comparison table in the README makes the same point about existing resources: Terraform needs import blocks or the terraform import command, Pulumi needs pulumi import, and formae discovers them automatically and generates the code.

Reconcile absorbs drift, patch never deletes

The two apply modes are where the risk lives, and the difference between them is large. The reconcile mode makes a stack match the forma in your code, on disk or in your repository, including deletions. If out of band changes were recorded, it stops and asks you to absorb each one into the desired state or revert it. That pause is deliberate, and it is the difference between a tool that reconciles and a tool that silently rewrites your infrastructure to match a file that is out of date. The patch mode only creates or updates the resources named in the forma you apply and never deletes anything, and collections such as tags are only added to. The documentation describes it as meant for targeted and emergency changes, and the comparison table notes that Terraform's -target and Pulumi's --target still evaluate the whole configuration and dependency graph, while patch mode is scoped to what you named. Reconcile also works with GitOps, since the Pkl can live in Git and reconcile can run from CI.

Installing the agent and the plugin model

The install is a script plus a path entry:

bash
/bin/bash -c "$(curl -fsSL https://hub.platform.engineering/get/formae.sh)"
export PATH=/opt/pel/bin:$PATH
formae --version

The supported platforms are Linux and macOS, and for running the agent on a server or in Kubernetes there is a container image and a Helm chart in a separate repository. The plugin model is the part worth understanding before you install anything. Plugins are comparable to Terraform providers, with each plugin being a separate, independently versioned process that adds the resource types of one platform. The Dockerfile comments explain the consequences of that independence. Plugins are released independently of formae and do not carry a parallel dev channel, so even dev formae containers ship with stable plugins. The standard metapackage resolves its requires at install time and pulls in a curated default plugin set, which the comments list as aws, azure, gcp, oci, ovh and auth-basic. The installer runs as root so that /opt/pel ends up root owned, and the agent process itself runs unprivileged as a separate user that only reads from that directory, with runtime plugin changes going through the formae plugin command, which prompts for sudo.

The always on agent is the cost you pay for the convenience

There is a real trade-off in this design and it deserves to be named. The same property that removes the state file, the import step and the hand written desired state also means the tool cannot act unless something is running. A CLI driven tool fails loudly when it is not invoked. An agent based tool can be idle for a week, and the discovery and synchronization history it holds is the only record of what changed in the meantime. That history is also the reason to run the agent rather than the hosted alternative. The repository is the open source edition you run yourself, and the project also offers a hosted form where the agent is run and managed for you, which removes the operational burden but also removes the state from your own infrastructure. The README describes working with the system through code, the CLI or an AI agent, and the project topics include MCP, so agent-driven use is on the roadmap rather than an afterthought. The choice for a team is straightforward. If you want the record of drift to be yours, run the agent. If you want the code generation and do not care who hosts the process, the hosted edition is the same software with the burden removed.

Licence, repository layout and release channel handling

The licence is the one thing to check before adopting this in a commercial setting. The badge in the README names it as FSL-1.1-ALv2, the Functional Source Licence with an Apache licence fallback, and the Makefile carries the SPDX identifier FSL-1.1-ALv2 on every file header. The SPDX identifier on the Makefile tells you the shape of the terms. The repository is not archived and the last push was on 2026-10-08, and there are no GitHub releases, so the version comes from git tags rather than a release page. The build scripts show how that works. The Makefile derives the raw version with git describe against numeric and v numeric tag patterns, splits the channel from the version by checking for a dash in the tag, and the comment explains that an earlier shape of that logic produced a literal dev.2 for a tag like 0.85.0-dev.2, which the package manager wrote as a real channel name and broke downstream installs. The justfile repeats the same derivation. The repository layout is conventional Go, with cmd/, internal/, pkg/, tests/, docs/ and a plugins package replaced to a local path, so the plugin SDK can be developed in the same tree.

Editorial conclusion

Adopt formae when you have infrastructure that predates any infrastructure as code practice, when you want the existing estate to become code rather than starting from an empty plan, and when you can run an always on agent with credentials for the accounts it watches. Do not adopt it if you need a CLI that runs on demand with no daemon, or if your process requires a state file you can read and diff yourself. Verify first that the plugin for your platform is available on the hub, that the agent can reach every target you want discovered, and that you understand the reconcile behaviour of absorbing versus reverting recorded drift before you let it change anything.

Frequently asked questions

How does formae handle infrastructure that already exists?

The agent scans each target every 10 minutes by default and records resources it does not manage as unmanaged, which are read-only until brought under management. The formae extract command then writes Pkl for any set of resources, managed or not, so code is generated from what is running.

What is the difference between reconcile and patch in formae?

Reconcile makes a stack match the forma including deletions, and it stops to ask you to absorb or revert any recorded drift. Patch only creates or updates the resources named in the forma you apply, never deletes anything, and is intended for targeted and emergency changes.

Does formae need a state file?

No. The agent stores state in its own database, with SQLite, PostgreSQL, Aurora Data API or SQL Server as the options, and the comparison table describes the state as stored by the agent with no state file to handle.

How are formae plugins installed and updated?

Each plugin is a separate, independently versioned process that adds the resource types of one platform, and the standard metapackage resolves its requires at install time to pull in a curated default set including aws, azure, gcp, oci, ovh and auth-basic. Runtime plugin changes go through the formae plugin command, which prompts for sudo when writing to the root owned plugin store.

Official sources

  1. Issues
  2. platform-engineering-labs/formae on GitHub
  3. Project website
  4. README
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/platform-engineering-labs-formae.svg)](https://hysenlabs.com/projects/platform-engineering-labs-formae)

Was this useful?