# Manage Botyard with Terraform

> Use the Botyard Terraform provider to declare bots, skills, MCP servers, and Runtime Vault secrets as code, with a runnable quickstart configuration.

Canonical URL: https://docs.botyard.io/docs/terraform

The [Botyard Terraform provider](https://registry.terraform.io/providers/Botyard-AI/botyard/latest)
lets you declare a supported set of Botyard resources in Terraform and manage them with
`plan` and `apply`, alongside the rest of your infrastructure. The source is on GitHub at
[Botyard-AI/terraform-provider-botyard](https://github.com/Botyard-AI/terraform-provider-botyard).

## Supported resources

Provider version 0.8.0 supports these resources. Features not listed here are managed in the
Botyard app or through the [API](/api-docs).

| Resource                            | Manages                                                                         | Concepts                                           |
| ----------------------------------- | ------------------------------------------------------------------------------- | -------------------------------------------------- |
| `botyard_bot`                       | A bot's identity and configuration overrides                                    | [Getting started](/docs/getting-started)           |
| `botyard_bot_soul`                  | The full soul (instructions) of a hosted native bot                             |                                                    |
| `botyard_bot_schedule`              | One recurring schedule on a bot, which wakes it with a prompt or runs a command |                                                    |
| `botyard_bot_credential_assignment` | Which organization credentials a bot uses, per scope                            | [Provider credentials](/docs/provider-credentials) |
| `botyard_bot_skill_assignment`      | Which skills are assigned to a bot                                              |                                                    |
| `botyard_bot_tool_assignment`       | Which tools are assigned to a bot                                               |                                                    |
| `botyard_skill`                     | An organization skill and its files                                             |                                                    |
| `botyard_mcp_server`                | An organization MCP server                                                      | [MCP setup templates](/docs/mcp-setup-templates)   |
| `botyard_mcp_server_member`         | One member of an MCP server's member list                                       | [MCP setup templates](/docs/mcp-setup-templates)   |
| `botyard_vault_secret`              | A Runtime Vault secret and its access rules                                     | [Runtime Vault](/docs/runtime-vault)               |

Data sources look up bots, bot schedules, bot templates, credentials, MCP servers, packs and
pack versions, skills, and tools. The
[Registry documentation](https://registry.terraform.io/providers/Botyard-AI/botyard/latest/docs)
has the argument reference for each resource and data source.

`botyard_bot_schedule` and the `botyard_bot_schedules` data source need provider version 0.7.1
or later, and `botyard_bot_soul` needs 0.8.0 or later.

## Authenticate

The provider uses an organization-scoped Botyard API key (`byk_...`) with the **owner** role
(see [API authentication](/docs/api/authentication)). Creating bots, MCP servers and Runtime Vault
secrets requires the owner role, so a member or viewer key fails with `403 Forbidden` on those
resources. Keys default to the member role, so choose **owner**
when you create the key.

Set the key and the organization ID through environment variables so the key never lands in
Terraform configuration or state:

```bash
export BOTYARD_API_KEY="byk_..."
export BOTYARD_ORG_ID="00000000-0000-0000-0000-000000000000"
```

`BOTYARD_ENDPOINT` is optional and defaults to `https://api.botyard.io`.

To find the organization ID, call `GET /v1/me/orgs` with the key; the response's `org_id` is the
value to use.

Bots that Terraform creates are owned by the API key that created them. Any other API key, even
an owner key, gets `403 Forbidden` when it tries to update or destroy them. To rotate the key,
revoke the old key before you run `terraform apply` with the new one. After the old key is
revoked, an owner key can take over those bots, but only if they have no other owner. If a person
was added as an owner of a bot, the new key keeps getting `403 Forbidden` for that bot. See
[API authentication](/docs/api/authentication#rotating-keys).

## Quickstart

This configuration creates a bot, a custom skill, assigns the skill to the bot, and stores a
Runtime Vault value that only that bot may lease. It requires Terraform 1.11 or later, because
`secret_value` is a write-only argument that is never stored in state.

```hcl title="main.tf"
terraform {
  required_version = ">= 1.11"

  required_providers {
    botyard = {
      source  = "Botyard-AI/botyard"
      version = "~> 0.8"
    }
  }
}

provider "botyard" {}

# The bot. Creating it triggers provisioning; the slug is derived from the name.
resource "botyard_bot" "assistant" {
  name        = "Terraform Quickstart Assistant"
  description = "Created by the terraform-provider-botyard quickstart."
}

# A custom skill: instructions the bot loads on demand.
resource "botyard_skill" "release_checklist" {
  name    = "Release Checklist"
  summary = "Steps to follow before announcing a release."

  files = [
    {
      filename = "SKILL.md"
      content  = <<-EOT
        # Release Checklist

        1. Confirm CI is green on the release commit.
        2. Check the changelog covers every user-facing change.
        3. Announce the release with a link to the changelog.
      EOT
    },
  ]
}

# Give the bot that skill. This resource owns the bot's full skill set.
resource "botyard_bot_skill_assignment" "assistant" {
  bot_slug  = botyard_bot.assistant.slug
  skill_ids = [botyard_skill.release_checklist.id]
}

# A Runtime Vault entry only this bot may lease at runtime.
resource "botyard_vault_secret" "status_page_url" {
  key_path     = "quickstart.status_page_url"
  display_name = "Status page URL"
  sensitivity  = "plain"
  secret_value = "https://status.example.com"
  bot_ids      = [botyard_bot.assistant.id]
}

output "bot_slug" {
  value = botyard_bot.assistant.slug
}
```

Run it in an organization you can experiment in:

```bash
terraform init
terraform apply
```

After the apply, the bot appears in the Botyard app with the **Release Checklist** skill
assigned. A second `terraform plan` reports no changes. `terraform destroy` removes the bot,
the skill, the assignment, and the vault secret.

## Related docs

* [Getting started](/docs/getting-started)
* [Runtime Vault](/docs/runtime-vault)
* [MCP setup templates](/docs/mcp-setup-templates)
