A reference implementation for running a small "AI company" of 5 OpenClaw agents on Amazon Elastic Kubernetes Service (EKS), with Amazon Bedrock for inference, Amazon S3 Files as a shared filesystem between agents, and Discord as the chat interface for humans.
The deploy steps below are designed so an AI coding agent (Claude Code, Cursor, etc.) can read this README, prepare your AWS account, and produce a working 5-agent cluster in roughly 30 minutes.
┌──────────────────────────── Amazon EKS (Auto Mode) ────────────────────────────┐
│ │
│ OpenClawInstance CRDs → Operator → StatefulSet/Pod ──┐ │
│ ┌──────┐ ┌──────┐ ┌──────┐ ┌──────┐ ┌──────┐ │ │
│ │admin │ │milo │ │josh │ │luna │ │rex │ │ Pod Identity │
│ │Opus │ │Opus │ │Sonnet│ │Sonnet│ │Opus │ │ ↓ │
│ │ 4.7 │ │ 4.6 │ │ 4.6 │ │ 4.6 │ │ 4.7 │ ────────────────┘ Amazon │
│ └──┬───┘ └──┬───┘ └──┬───┘ └──┬───┘ └──┬───┘ /shared (S3 Files) Bedrock │
│ └────────┴────────┴────────┴────────┘ │
│ Discord (5 bots) │
└────────────────────────────────────────────────────────────────────────────────┘
.
├── README.md this file
├── LICENSE MIT-0
├── discord-config.example.env copy → discord-config.env, fill in your IDs
├── k8s/
│ ├── namespaces.yaml
│ ├── rbac.yaml
│ ├── storageclass-gp3.yaml
│ ├── shared-configmaps.yaml
│ ├── s3files-shared.yaml Amazon S3 Files PV/PVC
│ ├── admin-agent.yaml templated — Admin agent CR
│ ├── agents.yaml declarative agent registry
│ └── templates/
│ └── startup-team.yaml templated — Milo / Josh / Luna / Rex CRs
├── scripts/
│ ├── check-prerequisites.sh
│ ├── render-manifests.sh envsubst against discord-config.env → rendered/
│ ├── setup-s3files.sh provision Amazon S3 Files filesystem and CSI driver
│ ├── deploy.sh end-to-end (cluster + operator + agents)
│ └── teardown.sh
└── workspace-templates/ seed content placed into each agent's PVC
├── admin/ Admin's persona + ops skill
├── presets/ Milo / Josh / Luna / Rex personas
├── shared/ base files included on every agent
└── shared-fs/ contents seeded into /shared (S3 Files)
| Tool | Minimum version | Notes |
|---|---|---|
| AWS CLI | v2 | configured with an admin-equivalent identity |
kubectl |
1.30 | |
helm |
3.14 | used to install the EFS CSI driver (v3.0.0+, S3 Files-capable) |
eksctl |
0.180 | |
gettext (envsubst) |
any | brew install gettext / apt-get install gettext-base |
Node npm (only if you want the optional dashboard later) |
20+ |
You also need:
-
Amazon Bedrock model access (in your target region — examples in
us-west-2):Claude Opus 4.7(global.anthropic.claude-opus-4-7)Claude Sonnet 4.6(global.anthropic.claude-sonnet-4-6)Claude Haiku 4.5(global.anthropic.claude-haiku-4-5-20251001-v1:0)
-
A Discord server you control + 5 bot applications:
- Discord Developer Portal → New Application × 5 (one per agent: Admin, Milo, Josh, Luna, Rex).
- Each application → Bot tab → reset token, save it (you'll create a K8s Secret per agent).
- Each application → Bot tab → enable
MESSAGE CONTENT INTENT. - Each application → OAuth2 → URL Generator → check
bot+applications.commands, under permissions check "Send Messages" and "Read Message History" → use the generated URL to invite each bot to your server.
# 1. Fill in your Discord IDs
cp discord-config.example.env discord-config.env
$EDITOR discord-config.env # see the comments inside
# 2. Confirm prerequisites are present (kubectl/helm/aws/eksctl/envsubst + Bedrock access)
./scripts/check-prerequisites.sh
# 3. Provision Amazon S3 Files for the shared /shared filesystem
./scripts/setup-s3files.sh
# 4. End-to-end deploy: cluster + operator + Pod Identity + agents
./scripts/deploy.sh
# (deploy.sh will pause and ask you to create 5 Discord bot token Secrets — see below)
# 5. Verify
kubectl get openclawinstance -n opc-agentsWhen deploy.sh pauses, in another terminal create one Secret per agent:
for AGENT in admin milo josh marketing devlead; do
read -s -p "Discord bot token for $AGENT: " TOKEN; echo
kubectl create secret generic ${AGENT}-discord-token \
--namespace opc-agents \
--from-literal=DISCORD_BOT_TOKEN="$TOKEN"
doneOnce the script finishes, mention any of the 5 bots in your Discord server with
@<bot-name> hello and you should see a response within a few seconds.
Every file in this repo that needs your private Discord IDs uses ${VAR_NAME} placeholders.
scripts/render-manifests.sh reads discord-config.env and writes substituted copies into
rendered/ — that's the directory kubectl apply ultimately operates on. The ${...}
templates in source are intentional: nothing in the committed manifests names a real Discord
channel, bot, role, or user.
If you want to inspect what will be applied:
./scripts/render-manifests.sh
ls rendered/rendered/ is in .gitignore — never commit it.
-
Five agent pods in namespace
opc-agents, each backed by a 20Gi EBS PVC. -
/sharedS3 Files mount on all five (Admin/Milo/Rex read-write; Josh/Luna read-only). -
EKS Pod Identity wires:
- SA
opc-admin-agent→ roleopc-bedrock-role(Bedrock only) — Admin - SA
opc-agent-default→ roleopc-bedrock-role(Bedrock only) — Milo, Josh, Luna - SA
opc-rex-operator→ roleopc-rex-ops-role(AdministratorAccess) — Rex
Rex has elevated AWS permissions because Rex is the team's "AWS resource operator". If you don't want any agent to have admin AWS permissions, edit
scripts/deploy.shto skip the Rex IAM block and patchdevlead's CR to useopc-agent-default. - SA
-
Discord pairing via the 5 Secrets you create.
Each agent's text-based persona lives under workspace-templates/presets/<role>/ and is
inlined into the CR's workspace.initialFiles block. To change a persona, edit the inline
copy in k8s/admin-agent.yaml or k8s/templates/startup-team.yaml, re-apply the manifest,
and restart the affected pod. The file format (SOUL.md / IDENTITY.md / AGENTS.md / TOOLS.md)
follows OpenClaw's bootstrap contract — see openclaw.rocks for
the upstream specification.
./scripts/teardown.shThis deletes the EKS cluster, the IAM roles, the S3 Files filesystem, and all bot tokens stored as Secrets. Discord bots themselves remain in your Developer Portal — delete them manually if desired.
- OpenClaw — the open-source multi-agent runtime used here.
- Amazon EKS Auto Mode — the cluster mode this template uses; lets you skip nodegroup management entirely.
- EKS Pod Identity.
- Amazon Bedrock model access.
MIT-0 — see LICENSE.