Skip to main content
By default agent VMs run on Murmur’s infrastructure. To move them into your own GCP or AWS account, set up a customer Placement. The result: each VM runs in your project, on your subnet, billed to you, reachable by your internal services. See placement for the full resource spec. This is advanced. Most teams don’t need it. Common reasons to do it anyway:
  • Compliance: security team requires compute in your own account
  • Data residency: regulations pin you to a specific region
  • VPC-internal access: agents need databases, services, or APIs not on the public internet
  • Custom networking: specific firewall rules, proxy, or VPN
Murmur authenticates into your cloud via OIDC token exchange (Workload Identity Federation). No service-account JSON, no long-lived keys, no rotation burden. The trust policy is scoped to exactly your tenant ID, so no other Murmur tenant can ever reach your resources.

GCP

1. Apply the Terraform module

The customer modules are public at github.com/prassoai/terraform-modules. Consume them via a git source pinned to a release tag with ?ref=, never a branch:
vm_service_accounts lists the runtime service accounts your agents run as; the module grants the WIF service account permission to attach them at VM-create time. The module creates a Workload Identity Federation pool and provider, the VM-creator and read-only service accounts, a tight custom IAM role, and the bindings: all scoped to your tenant. Murmur exchanges its OIDC token for short-lived GCP credentials; nothing long-lived lives on the agent VMs.

2. Sync the Placement

As of v0.2.0 the module assembles the full Placement from its own WIF outputs plus the placement_* inputs and exposes it as the placement output. Pipe it straight into murmur set. No hand-copying WIF resource names:
The output is null until placement_name is set. default_spawn_grant and spawn_grants_by_sa configure placement-sa.assume grants, which authorize tenant-level bakes. Agent spawns instead require workspace authority and admission through the identity’s workspace_use. Before using this placement in a workspace, set that binding policy to admit it; restricting the assumption grants does not restrict spawns or viewing.

3. Rebake your Images into your project

Bake an image in your GCP project with murmur bake. First, use murmur get and murmur set to admit my-workspace to the tenant-level recipe and environment. The baked image inherits the recipe’s admission policy. These commands use yq and require the corresponding kind’s edit permission through a tenant-binding:
Then run the bake:
--service-account must exactly match one of the placement’s service-account bindings: here the runtime SA you passed as vm_service_accounts. Read the placement back (murmur get placement my-gcp) if you’re unsure which identities it carries. This boots a scratch VM in your project, runs your Recipe’s provisioning script there, snapshots the disk, and registers the resulting Image. Parallel bakes are independent workflows and don’t contend.

4. Point a Workspace at the Placement

image_ref names the Image the bake registered: <recipe>-<first 16 characters of the image hash>. List Images with murmur get image. service_account must match one of the placement’s service-account bindings. A spawn against a workspace without one fails with workspace "my-workspace" has no service_account but placement "my-gcp" requires one — update the workspace configuration. Spawn an agent and verify with murmur status that the project in its vm: line, vm: <instance> (<project>/<zone>) [<state>], matches yours. If it doesn’t, double-check that the Image you’re using was baked against my-gcp (different Placements can’t share Images). See Workspaces for the full Workspace model.

AWS

1. Apply the Terraform module

Creates an OIDC provider with a StringEquals trust policy scoped to your tenant ID, the VM-creator and read-only IAM roles, and the VM runtime instance profile. The sub claim provides cryptographic isolation because another tenant’s OIDC token cannot assume your role. You supply the VPC, subnets, and security group; the module never creates them. Point placement_vpc_id, placement_subnet_ids, and placement_security_group_id at networking that already exists in your account.

2. Sync the Placement

As of v0.2.0, the module assembles the full Placement. It derives account_id from the VM-creator role ARN, reads the role, instance-profile, and OIDC-provider ARNs from its resources, and exposes the result as the placement output. Pipe it into murmur set:
The output is null until placement_name is set. default_spawn_grant configures placement-sa.assume for tenant-level bakes. Agent spawns instead require workspace authority and admission through the identity’s workspace_use. Before using this placement in a workspace, set that binding policy to admit it; assumption grants do not restrict spawns or viewing.

3. Rebake your Images into your account

Bake an image in your AWS account. As in the GCP steps, use murmur get and murmur set to admit my-workspace to the tenant-level recipe and environment before the bake. The baked image inherits the recipe’s admission policy:
Run the bake with murmur bake:
--service-account must exactly match the placement’s instance-profile binding (read it back with murmur get placement my-aws).

4. Point a Workspace at the Placement

On AWS the Image name ends in -<region>. Verify with murmur status <slug>: the vm: line shows (<account_id>/<region>), which should match yours.

What changes operationally

  • Billing splits: cloud spend (VMs, network, storage) bills to your account directly, so Murmur charges less for those components. Your billing dashboard shows the rates that apply to your workspace. See Pricing.
  • Region pinning: VMs only run where your Placement allows. A Workspace using my-gcp with zones: ["us-central1-a"] can never spawn outside that zone.
  • Networking is yours: your firewall rules, your routes, your egress. Agents reach your internal services as if they lived in your VPC.
  • You own incident response: if a VM misbehaves, it’s in your project; you can grab logs, snapshot disks, or shut it down directly.