prassoai/murmur, manages your tenant’s catalog from Terraform. Every resource you would write with murmur set (a workspace, a placement, an agent persona, a tenant binding) becomes a murmur_catalog_resource that you review in a plan and apply like any other infrastructure.
The provider’s attribute reference is on the Registry. This guide shows how the pieces fit together.
Install the provider
terraform init downloads the provider from the Registry and records its checksums in .terraform.lock.hcl. Commit that file.
auth chooses who Terraform acts as. Shared configurations and CI apply as a service profile. To try the provider from your own machine, apply as yourself.
Apply as yourself
Withauth = "gh", Terraform calls Murmur as you, with exactly the permissions you hold, using the GitHub CLI’s login on the machine running Terraform:
Apply as a service profile
A service profile is a non-human identity. Terraform authenticates as one with an API key, and the profile holds exactly the permissions the configuration needs. An organization admin sets it up once.1. Create the service profile
2. Grant it the permissions the configuration needs
Grant the profile its permissions with a tenant binding that names the profile asservice-profile:terraform. Each Terraform operation needs one permission on the resource’s kind:
Two cases need a second permission:
- Updating a workspace’s
grantsalso needsworkspace.administer, checked against the grants saved before the change. The binding below includes it. - A resource named
{workspace}/{slug}lives inside a workspace and also needsworkspace.useon that workspace. A workspace’s own grants confer it: the suggested defaults give it to every service profile throughservice-profile:*. For a workspace whose grants leave that out, nameservice-profile:terraformin them.
workspace.* also confers workspace.use on every workspace, including those whose grants leave the profile out.
3. Create an API key for the profile
Go to Organization Settings → Automations → API Keys, click Create API key, and choose theterraform service profile. The full key, starting mur_, is shown once. See API keys for the full steps.
4. Apply with the key
Store the key as theMURMUR_API_KEY secret of the CI system that runs Terraform, and keep auth = "api_key" in the provider block:
terraform plan on pull requests and terraform apply on merge, and keep state in a remote backend. Restrict access to that state as you would to the catalog itself: it holds a copy of every resource it manages.
The provider also accepts the key inline as api_key. Prefer the environment variable, which keeps the key out of configuration.
Manage catalog resources
Each resource names akind and a name, plus its body. JSON-backed kinds take payload; markdown-backed kinds such as agent-persona take markdown:
payload is compared as parsed JSON, so a plan shows changed values and ignores key order and formatting. The files hold the same YAML you would pipe to murmur set. To manage a whole directory of them with two resources and for_each, see Managing a Catalog from Files on the Registry.
Every workspace that bakes or rolls out images should set ignore_fields = ["imageRef"]. The first apply still needs an imageRef in the payload; after that, Terraform keeps whatever image the workspace is running.
Set secrets with murmur secret set. Terraform state is stored in plaintext, so the provider rejects credential-bearing kinds such as secret.
Infrastructure and placement in one configuration
The customer placement modules emit a ready-madeplacement output. Feed it to the provider instead of piping it through the CLI, and the cloud resources, the placement, and the workspace that uses it all come from one apply:
modules/aws-wif) emits the same placement output. Baking the image the workspace runs is still a murmur bake; see step 3 of the placement guide for GCP or AWS.
Bring existing resources under Terraform
Resources you already created with the CLI or dashboard can be imported by<kind>/<name>:
managed_by becomes terraform). Apply it; after that the plan is empty.
Who owns a resource
Each resource has one writer. Once Terraform manages it, an edit in the dashboard or CLI shows up as drift on the next plan, and applying writes the Terraform value back. If another system manages the resource, the apply fails and names that system; setforce_ownership = true for a single apply to take it over.
Every write is conditional on the version Terraform last saw. If someone changes a resource between your plan and your apply, the apply fails with a conflict and leaves their change in place. Run terraform plan again to review it.