OpenClaw AWS Deploy
by @godwinbabu
Deploy OpenClaw securely on AWS with a single command. Creates VPC, EC2 (ARM64), Telegram channel, and configurable AI model (Bedrock, Gemini, or any provide...
clawhub install openclaw-aws-deployπ About This Skill
name: openclaw-aws-deploy description: Deploy OpenClaw securely on AWS with a single command. Creates VPC, EC2 (ARM64), Telegram channel, and configurable AI model (Bedrock, Gemini, or any provider) β SSM-only access, no SSH. Use when setting up OpenClaw on AWS, deploying a new agent instance to EC2, or tearing down an existing AWS deployment. metadata: { "openclaw": { "emoji": "βοΈ", "requires": { "bins": ["aws", "jq", "openssl"] }, }, }
OpenClaw AWS Deploy Skill
Quick Start (Minimal Deployment ~$30/mo)
Prerequisites
--profile flag (named AWS CLI profile)
- .env.aws file in workspace root or skill directory (optional):
AWS_ACCESS_KEY_ID=...
AWS_SECRET_ACCESS_KEY=...
AWS_DEFAULT_REGION=us-east-1
- Existing environment variables, AWS SSO session, or IAM role
.env.starfish in workspace root (recommended) or skill directory: TELEGRAM_BOT_TOKEN=... # from @BotFather (required)
TELEGRAM_USER_ID=... # your Telegram user ID (optional, enables auto-approve pairing)
GEMINI_API_KEY=... # from aistudio.google.com (optional, for Gemini models)
aws CLI installed OR Docker for sandboxed accessjq, openssl availableOne-Shot Deploy
# From the skill directory:
./scripts/deploy_minimal.sh --name starfish --region us-east-1 \
--env-dir /path/to/workspaceOr with cleanup of previous deployment first:
./scripts/deploy_minimal.sh --name starfish --region us-east-1 \
--env-dir /path/to/workspace --cleanup-first
This single command:
1. Creates VPC + subnet + IGW + route table
2. Creates security group (NO inbound ports β SSM only)
3. Creates IAM role with minimal permissions (SSM + Parameter Store + Bedrock)
4. Stores secrets in SSM Parameter Store (fetched at each service start β rewritten on each start, never stored in repo or static images)
5. Launches t4g.medium ARM64 instance with user-data bootstrap
6. User-data installs Node.js 22 + OpenClaw + configures everything
7. Runs smoke test via SSM
8. Saves all resource IDs to deploy-output.json
After Deploy
1. Message the Telegram bot β you'll get a pairing code 2. Approve pairing via SSM:
aws ssm start-session --target --region us-east-1
sudo -u openclaw bash
export HOME=/home/openclaw
openclaw pairing approve telegram
3. Bot is live! β
Teardown
# Using saved output:
./scripts/teardown.sh --from-output ./deploy-output.json --env-dir /path/to/workspace --yesOr by name (discovers via tags):
./scripts/teardown.sh --name starfish --region us-east-1 --env-dir /path/to/workspace --yes
Model Support
--model flag
Pass any model string β it goes directly into openclaw.json as model.primary:
# Default (MiniMax M2.1 on Bedrock β no API key needed, uses IAM role)
./scripts/deploy_minimal.sh --name starfish --region us-east-1Gemini Flash (needs GEMINI_API_KEY in .env.starfish)
./scripts/deploy_minimal.sh --name starfish --region us-east-1 \
--model google/gemini-2.0-flash
AWS Bedrock
Bedrock IAM permissions (bedrock:InvokeModel, bedrock:InvokeModelWithResponseStream) are always added to the instance role β regardless of which model you choose. This means any deployed instance can use Bedrock models out of the box via IAM role credentials (no API key needed).
Known Bedrock model IDs:
| Model flag | Description |
|------------|-------------|
| amazon-bedrock/minimax.minimax-m2.1 | MiniMax M2.1 |
| amazon-bedrock/minimax.minimax-m2 | MiniMax M2 |
| amazon-bedrock/deepseek.deepseek-r1 | DeepSeek R1 |
| amazon-bedrock/moonshotai.kimi-k2.5 | Kimi K2.5 |
> Note: Bedrock models must be enabled in your AWS account via the Bedrock console before use.
Gemini
If GEMINI_API_KEY is present in .env.starfish, it's stored in SSM and written to auth-profiles.json. If absent, it's simply skipped β no error.
.env.starfish
TELEGRAM_BOT_TOKEN=... # Required β from @BotFather
GEMINI_API_KEY=... # Optional β from aistudio.google.com (needed for Gemini models)
Architecture (Minimal)
βββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β VPC (10.50.0.0/16) β
β βββββββββββββββββββββββββββββββββββββββββββββββββ β
β β Public Subnet (10.50.0.0/24) β β
β β βββββββββββββββββββββββββββββββββββββββββββ β β
β β β EC2 t4g.medium (ARM64, 4GB) β β β
β β β βββββββββββββββββββββββββββββββββββββ β β β
β β β β OpenClaw Gateway β β β β
β β β β β’ Node.js 22.14.0 β β β β
β β β β β’ Any model (Bedrock/Gemini/etc) β β β β
β β β β β’ Telegram channel β β β β
β β β β β’ Encrypted EBS (gp3, 20GB) β β β β
β β β βββββββββββββββββββββββββββββββββββββ β β β
β β βββββββββββββββββββββββββββββββββββββββββββ β β
β βββββββββββββββββββββββββββββββββββββββββββββββββ β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β β
SSM (no SSH/inbound) Outbound HTTPS only
Critical Lessons Learned (22 Issues)
These are baked into the deploy script. See references/TROUBLESHOOTING.md for full details.
Instance Sizing
Node.js
npm
openclaw@latest β bare openclaw may resolve to placeholder package (0.0.1)Gateway Startup
openclaw gateway run --allow-unconfigured β NOT gateway start (which tries systemctl --user and fails)openclaw.json β not config.yamlgateway.mode: "local" β required or you get "Missing config" errorgateway.auth.mode: "token" β "none" is invalidTelegram
plugins.entries.telegram.enabled: true β must be explicitdmPolicy: "pairing" β not "allowlist" (blocks everyone without user list)streamMode: "partial" β some models don't support streaming tools, use "off" as fallbackModel
auth-profiles.json in agent diramazon-bedrock/MODEL_ID (not bedrock/)Systemd Service
ProtectHome, ReadWritePaths=/tmp/openclaw, PrivateTmp due to namespace issuesNODE_OPTIONS="--max-old-space-size=1024" β helps prevent OOMSecurity
HttpTokens=requiredFile Layout
scripts/
deploy_minimal.sh # One-shot deploy (VPC + EC2 + OpenClaw)
teardown.sh # Clean teardown of all resources
setup_deployer_role.sh # Create IAM role/user with minimum permissions
preflight.sh # Pre-deploy validation checks
smoke_test.sh # Post-deploy health verificationreferences/
TROUBLESHOOTING.md # All 22 issues + solutions
config-templates/ # Ready-to-use config files
gemini-flash.json # OpenClaw config for Gemini Flash
auth-profiles-gemini.json # Auth profile template
openclaw.service.txt # Systemd unit file template
startup.sh # Startup script template
Config Templates
OpenClaw Config (gemini-flash.json)
Seereferences/config-templates/gemini-flash.json β includes all required fields.Auth Profiles (auth-profiles-gemini.json)
Create at~/.openclaw/agents/main/agent/auth-profiles.jsonSystemd Service (openclaw.service)
Simplified for reliability β security hardening removed due to namespace issues.Cost Breakdown (~$30/mo)
| Resource | Cost | |----------|------| | t4g.medium (4GB ARM64) | ~$24.53/mo | | EBS gp3 20GB | ~$1.60/mo | | Public IP | ~$3.65/mo | | Gemini Flash | Free tier / ~$0.30/1M tokens | | Total | ~$29.78/mo |Troubleshooting
"No API key found for amazon-bedrock"
Cause: OpenClaw needs models.providers config in openclaw.json with "auth": "aws-sdk". An auth-profiles.json entry alone is NOT sufficient.
Fix: Add to openclaw.json on the instance:
sudo -u openclaw bash
cd /home/openclaw/.openclaw
jq '.models = {
"providers": {"amazon-bedrock": {"baseUrl": "https://bedrock-runtime.us-east-1.amazonaws.com", "api": "bedrock-converse-stream", "auth": "aws-sdk", "models": [{"id": "minimax.minimax-m2.1", "name": "MiniMax M2.1", "input": ["text"], "contextWindow": 128000, "maxTokens": 4096}]}},
"bedrockDiscovery": {"enabled": true, "region": "us-east-1"}
}' openclaw.json > /tmp/oc.json && mv /tmp/oc.json openclaw.json
chown openclaw:openclaw openclaw.json
systemctl restart openclaw
"API rate limit reached" (Gemini)
Fix: Switch to Bedrock (default in current version) or redeploy with --model amazon-bedrock/minimax.minimax-m2.1.
Bedrock model returns errors
Cause: Model must be enabled in AWS Console β Bedrock β Model access. MiniMax models are auto-authorized; Anthropic/Meta models require use-case approval.
Bot doesn't respond after deploy
Fix: Add TELEGRAM_USER_ID to .env.starfish for auto-pairing, or use --pair-user . Manual: openclaw pairing approve telegram via SSM.
Safety Rules
Project= and DeployId= for deterministic cleanupβοΈ Configuration
--profile flag (named AWS CLI profile)
- .env.aws file in workspace root or skill directory (optional):
AWS_ACCESS_KEY_ID=...
AWS_SECRET_ACCESS_KEY=...
AWS_DEFAULT_REGION=us-east-1
- Existing environment variables, AWS SSO session, or IAM role
.env.starfish in workspace root (recommended) or skill directory: TELEGRAM_BOT_TOKEN=... # from @BotFather (required)
TELEGRAM_USER_ID=... # your Telegram user ID (optional, enables auto-approve pairing)
GEMINI_API_KEY=... # from aistudio.google.com (optional, for Gemini models)
aws CLI installed OR Docker for sandboxed accessjq, openssl availableOne-Shot Deploy
# From the skill directory:
./scripts/deploy_minimal.sh --name starfish --region us-east-1 \
--env-dir /path/to/workspaceOr with cleanup of previous deployment first:
./scripts/deploy_minimal.sh --name starfish --region us-east-1 \
--env-dir /path/to/workspace --cleanup-first
This single command:
1. Creates VPC + subnet + IGW + route table
2. Creates security group (NO inbound ports β SSM only)
3. Creates IAM role with minimal permissions (SSM + Parameter Store + Bedrock)
4. Stores secrets in SSM Parameter Store (fetched at each service start β rewritten on each start, never stored in repo or static images)
5. Launches t4g.medium ARM64 instance with user-data bootstrap
6. User-data installs Node.js 22 + OpenClaw + configures everything
7. Runs smoke test via SSM
8. Saves all resource IDs to deploy-output.json
After Deploy
1. Message the Telegram bot β you'll get a pairing code 2. Approve pairing via SSM:
aws ssm start-session --target --region us-east-1
sudo -u openclaw bash
export HOME=/home/openclaw
openclaw pairing approve telegram
3. Bot is live! β
Teardown
# Using saved output:
./scripts/teardown.sh --from-output ./deploy-output.json --env-dir /path/to/workspace --yesOr by name (discovers via tags):
./scripts/teardown.sh --name starfish --region us-east-1 --env-dir /path/to/workspace --yes
π Tips & Best Practices
"No API key found for amazon-bedrock"
Cause: OpenClaw needs models.providers config in openclaw.json with "auth": "aws-sdk". An auth-profiles.json entry alone is NOT sufficient.
Fix: Add to openclaw.json on the instance:
sudo -u openclaw bash
cd /home/openclaw/.openclaw
jq '.models = {
"providers": {"amazon-bedrock": {"baseUrl": "https://bedrock-runtime.us-east-1.amazonaws.com", "api": "bedrock-converse-stream", "auth": "aws-sdk", "models": [{"id": "minimax.minimax-m2.1", "name": "MiniMax M2.1", "input": ["text"], "contextWindow": 128000, "maxTokens": 4096}]}},
"bedrockDiscovery": {"enabled": true, "region": "us-east-1"}
}' openclaw.json > /tmp/oc.json && mv /tmp/oc.json openclaw.json
chown openclaw:openclaw openclaw.json
systemctl restart openclaw
"API rate limit reached" (Gemini)
Fix: Switch to Bedrock (default in current version) or redeploy with --model amazon-bedrock/minimax.minimax-m2.1.
Bedrock model returns errors
Cause: Model must be enabled in AWS Console β Bedrock β Model access. MiniMax models are auto-authorized; Anthropic/Meta models require use-case approval.
Bot doesn't respond after deploy
Fix: Add TELEGRAM_USER_ID to .env.starfish for auto-pairing, or use --pair-user . Manual: openclaw pairing approve telegram via SSM.