back to tutorials

How to Deploy Multi-Tenant AI Agents with Terraform

Learn how to deploy an isolated AI agent into each customer's own ChatBotKit sub-account using the Terraform Provider. This tutorial covers sub-accounts (partner users), the run_as attribute, provider aliases, and shared vs. bespoke per-customer agents.

If you are building a SaaS or white-label product, every customer usually needs their own agent in their own isolated environment - separate bots, conversations, datasets, and settings. ChatBotKit models this with sub-accounts (partner users), and the Terraform Provider lets you deploy into each one from a single, version-controlled configuration.

This tutorial shows you how to do that cleanly: one master token, the provider's run_as attribute, and provider aliases - the standard Terraform multi-account pattern, the same way the AWS provider uses assume_role.

What You'll Learn

By the end of this tutorial, you will be able to:

  • Understand ChatBotKit sub-accounts (partner users) and how they isolate customers
  • Use one partner/master token plus run_as to operate on any sub-account - no per-customer tokens
  • Target each customer with a provider alias
  • Deploy the same agent to every customer from one reusable module
  • Or deploy a bespoke agent per customer
  • Add a new customer without touching shared code

Prerequisites

Before starting, make sure you have:

  • A ChatBotKit account with a partner/master API key
  • Terraform version 1.0 or higher installed
  • One sub-account per customer. Create these in the dashboard, or via the partner API (partner/user/create). You only need each sub-account's ID (not a separate token)
  • Familiarity with Terraform providers, resources, and modules

Estimated time: 25-35 minutes

How Isolation Works

The provider authenticates with a single api_key, and the account is whichever account that key belongs to - there is no per-resource account setting. To deploy into a specific sub-account, you set the provider's run_as attribute to that sub-account's ID. The provider then sends the X-RunAs-UserId header, and everything it creates lands in that customer's isolated environment.

The key benefit: you hold one partner/master token and select the account by ID. Account IDs are not secret, so there are no per-customer tokens to mint, store, or rotate.

The run_as attribute is available in the ChatBotKit Terraform Provider 1.5.0 and later.

Step 1: Set Up the Project

Create a project and set your partner/master token (used for every sub-account):

Step 2: Configure a Provider Alias per Customer

In main.tf, declare one provider alias per customer. Each alias shares the same master token (from the environment) and differs only by run_as:

Supply the account IDs in terraform.tfvars:

Step 3: Package the Agent as a Module

So every customer gets the same agent, define it once as a module. Create modules/agent/main.tf:

Step 4: Deploy the Same Agent to Every Customer

Back in main.tf, call the module once per customer, wiring each call to that customer's provider alias:

There is no for_each here - one provider alias and one module call per customer. Deploy everything in a single run:

Each customer now has their own agent in their own sub-account, all from one configuration and one state.

Step 5: Add a New Customer

Adding a customer is three small additions - a variable, a provider alias, and a module call:

Run terraform apply again and only the new customer's resources are created.

Variation: A Different Agent per Customer

When customers genuinely differ - different skills, models, or channels - give each their own module instead of reusing one. Keep the same alias + run_as wiring; just point each module call at a customer-specific module (for example ./acme and ./globex), each defining its own bespoke agent. A single root still composes them all into one shared state and one apply.

This is the trade-off:

  • Shared module (Step 3-4): every customer gets the same agent; improve it once and redeploy to all.
  • Bespoke module per customer: full flexibility, but each agent is maintained on its own.

Important Notes

  • Account IDs vs. tokens. run_as takes a sub-account ID (not secret). Only the single master token in CHATBOTKIT_API_KEY is sensitive - keep it and your Terraform state out of version control and use an encrypted remote backend.
  • Creating sub-accounts. The provider operates within accounts; it does not create sub-accounts. Create them once in the dashboard or via the partner API (partner/user/create), optionally with per-customer limits to cap usage.
  • Cleanup. terraform destroy removes the agents. It does not delete the sub-accounts - remove those via the partner API (partner/user/{id}/delete).

Next Steps

By selecting accounts with run_as and composing modules with provider aliases, you can stand up - and tear down - an isolated agent for every customer from one reviewable, version-controlled configuration.