> ## Documentation Index
> Fetch the complete documentation index at: https://docs.runlayer.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Manage Agents with Terraform

> Provision and update Runlayer Agents from Terraform with the runlayer_agent resource: prompt, model, connectors, skills, built-in tools, tags, and environment.

Agents can be managed as code with the [Runlayer Terraform provider](/terraform-provider). The `runlayer_agent` resource owns the agent's configuration; the `runlayer_agent` data source reads back what Runlayer computed (model, generated description, counts).

## What you need

* The provider set up as described in [Terraform Provider](/terraform-provider), with a **user** API key. Organization API keys cannot create agents.
* A provider release that includes `runlayer_agent` (check the provider changelog on `terraform init`).
* Agents enabled for your workspace.

## Example

A support-triage agent with a least-privilege connector, a prompt kept in a file, tags, an environment variable, and starter prompts. It starts disabled so nothing can trigger it before you have reviewed it in the app.

```hcl theme={null}
terraform {
  required_providers {
    runlayer = {
      source  = "downloads.runlayer.com/runlayer/runlayer"
      version = "~> 1.0"
    }
  }
}

# Reads RUNLAYER_API_KEY and RUNLAYER_BASE_URL from the environment.
provider "runlayer" {}

# The connector the agent may use. Reference an existing server, or manage
# it with a runlayer_server resource in the same configuration.
data "runlayer_server" "linear" {
  server_id = var.linear_server_id
}

resource "runlayer_agent" "support_triage" {
  name = "support-triage"

  # The API strips leading/trailing whitespace from the prompt, so trimspace()
  # keeps file()'s trailing newline from showing up as a permanent diff.
  prompt = trimspace(file("${path.module}/prompts/support-triage.md"))

  # Returned sorted: list them sorted to avoid a permanent diff.
  tags = ["managed-by-terraform", "support"]

  # model = "claude-sonnet-5"   # omit to use the workspace's recommended model
  enable_web_fetch = true

  example_prompts = [
    "Triage the newest ticket in the support queue.",
    "Is ticket SUP-1234 a duplicate?",
  ]

  # Least-privilege tool allowlist per connector.
  # An empty tool_names means zero tools, not all tools.
  servers = [{
    server_id  = data.runlayer_server.linear.id
    tool_names = ["search_issues", "get_issue"]
  }]

  # Reusable instructions attached to the agent.
  skill_ids = [var.triage_skill_id]

  # Available to the agent runtime. Sensitive in plan/apply output; the API
  # never returns values, only env_keys.
  env = {
    TRIAGE_QUEUE = "support"
  }

  # Start parked; flip to false to let triggers run it.
  is_disabled = true
}

data "runlayer_agent" "support_triage" {
  agent_id = runlayer_agent.support_triage.id
}

output "support_triage" {
  value = {
    id           = runlayer_agent.support_triage.id
    model        = data.runlayer_agent.support_triage.model
    description  = data.runlayer_agent.support_triage.description
    server_count = data.runlayer_agent.support_triage.server_count
    tool_count   = data.runlayer_agent.support_triage.tool_count
    env_keys     = data.runlayer_agent.support_triage.env_keys
  }
}
```

`prompts/support-triage.md`:

```markdown theme={null}
You are the support triage agent for Runlayer.

For every incoming ticket:
1. Search Linear for duplicates before doing anything else.
2. Classify severity (P0-P3) using the playbook, and say why in one line.
3. Draft a reply for the support engineer to send. Never send it yourself.

Keep answers short. If you are unsure about severity, pick the higher one.
```

```bash theme={null}
terraform init
terraform apply
```

After `apply`, the agent appears in the app under **Agents**, owned by the user whose API key Terraform used. Open it there to run it, share it, add schedules or triggers, and watch sessions. Those runtime settings are not managed by Terraform.

## What Terraform manages

| Attribute                                                                                                                                              | Notes                                                                                               |
| ------------------------------------------------------------------------------------------------------------------------------------------------------ | --------------------------------------------------------------------------------------------------- |
| `name`, `prompt`                                                                                                                                       | Prompt whitespace is trimmed by the API; use `trimspace()`.                                         |
| `model`, `ai_provider_config_id`, `model_settings`                                                                                                     | Optional. Omit `model` for the workspace's [recommended model](/platform-agents#recommended-model). |
| `servers`                                                                                                                                              | List of `{ server_id, tool_names }`. Full replacement on every apply.                               |
| `skill_ids`                                                                                                                                            | Skill UUIDs to attach. Full replacement on every apply.                                             |
| `enable_web_fetch`, `enable_artifact_publishing`, `artifact_sharing`, `enable_codemode`, `enable_skill_distillation`, `enable_memory`, `memory_scopes` | Built-in tools and [runtime capabilities](/platform-agents#runtime-capabilities).                   |
| `env`                                                                                                                                                  | Environment variables for the runtime. Sensitive.                                                   |
| `tags`, `example_prompts`, `subagents`, `pending_catalog_connectors`, `icon`                                                                           | Returned as-is; keep `tags` sorted.                                                                 |
| `is_public`, `listed_in_workspace`, `is_disabled`                                                                                                      | Visibility and on/off switch.                                                                       |
| `enable_slack_budget_alerts`, `enable_slack_scheduled_run_failure_alerts`                                                                              | [Budget alerts](/platform-agents#budget-alerts).                                                    |

Read-only in Terraform, managed in the app: `description` (generated by Runlayer from the prompt), `harness`, and the [usage limits](/platform-agents#cost-budgets) `run_limits_by_model`, `daily_cost_limit_usd`, `weekly_cost_limit_usd`. The data source also exposes `server_count`, `tool_count`, `skill_count`, `env_keys`, `skills`, `created_by`, `share_scope`, and timestamps.

<Note>
  `servers`, `skill_ids`, and `env` are request-only: Terraform sends them on create and update but does not read them back, because the API returns connectors in a different shape and never returns environment values. Edits made to those three in the app are not detected as drift. Use `server_count`, `tool_count`, `skill_count`, and `env_keys` from the data source for read-side checks.
</Note>

## Importing an existing agent

```bash theme={null}
terraform import runlayer_agent.support_triage <agent-id>
```

The agent id is the UUID in the app URL (`/agents/<agent-id>`). The first plan after an import shows a one-time in-place update that re-sends `servers`, `skill_ids`, and `env` from your configuration, for the reason above.

## Deleting

`terraform destroy` deletes the agent and its linked agent account. Sessions, artifacts, and audit history follow the same retention as a deletion from the app.

## Related docs

<CardGroup cols={2}>
  <Card title="Terraform Provider" icon="code" href="/terraform-provider">
    Provider setup, credentials, and the other resources
  </Card>

  <Card title="Agents" icon="robot" href="/platform-agents">
    Everything an agent can do once it exists
  </Card>

  <Card title="Policies" icon="list" href="/platform-policies">
    Control what agents and users can do
  </Card>

  <Card title="Agent Accounts" icon="key" href="/platform-agent-accounts">
    Programmatic auth + delegated access model
  </Card>
</CardGroup>
