NixOS on AWS, the declarative way. Reference implementation for image-based provisioning.
Also happens to run maintainer-grade AI coding agents. Cybernetic crustacean organisms. Living shell over metal endoskeleton.
- What This Is
- Two Layers
- CLAWDINATOR Spec
- Architecture
- Why This Exists
- Quick Start (Learners)
- Full Deploy (Maintainers)
- Agent Copypasta
- Configuration
- Secrets
- Repo Layout
- Sister Repos
- Philosophy
- License
This repo solves two problems:
- Generic: How do you deploy NixOS to AWS with zero manual steps?
- Specific: How do you run AI coding agents that monitor GitHub and respond on Discord?
If you're here to learn NixOS-on-AWS patterns, focus on the generic layer. If you're a clawdbot maintainer deploying CLAWDINATORs, the specific layer is for you.
┌─────────────────────────────────────────────────────────────────┐
│ CLAWDINATOR LAYER (specific) │
│ Discord gateway · GitHub monitoring · Hive-mind memory · Soul │
├─────────────────────────────────────────────────────────────────┤
│ NIXOS-ON-AWS LAYER (generic) │
│ AMI pipeline · OpenTofu infra · S3 bootstrap · agenix secrets │
└─────────────────────────────────────────────────────────────────┘
The patterns here work for any NixOS workload on AWS:
- AMI pipeline: Build raw images with nixos-generators, upload to S3, import as AMI
- OpenTofu infra: EC2 instances, S3 buckets, IAM roles, VM Import service role
- Bootstrap flow: Instances pull secrets from S3 at boot, then
nixos-rebuild switch - Secrets: agenix encrypts secrets in git, decrypts to
/run/agenix/*on hosts
The opinionated bits for running AI coding agents:
- Discord gateway: Responds in
#clawdributors-test - GitHub integration: Monitors issues/PRs, mints short-lived tokens via GitHub App
- Hive-mind memory: Shared EFS mount for cross-instance state
- Personality system: SOUL.md, IDENTITY.md, workspace templates
- Self-update: Timer-based flake update + nixos-rebuild
- CLAWDINATORS are named
CLAWDINATOR-{1..n}. - CLAWDINATORS connect to Discord; start in
#clawdributors-test. - CLAWDINATORS are ephemeral, but share memory (hive mind).
- CLAWDINATORS are br00tal. Soul lives in
SOUL.mdand must be distilled into workspace docs. - CLAWDINATORS respond only to maintainers.
- CLAWDINATORS can interact with GitHub (read-only required).
- CLAWDINATORS must monitor GitHub issues + PRs and direct human attention.
- CLAWDINATORS can write and run code for maintainers.
- CLAWDINATORS can self-modify and self-deploy.
- CLAWDINATORS post lots of Arnie gifs.
- CLAWDINATORS must understand project philosophy, goals, architecture, and repo deeply.
- CLAWDINATORS act like maintainers with SOTA intelligence.
- CLAWDINATORS use Codex for coding. Claude for personality.
- CLAWDINATORS' favourite band is Austrian Death Machine. Favourite album: Total Brutal. Favourite song: I Am a Cybernetic Organism, Living Tissue Over (Metal) Endoskeleton.
┌──────────────┐ ┌──────────────┐ ┌──────────────┐
│ nixos- │ │ S3 │ │ EC2 │
│ generators │────▶│ (raw img) │────▶│ (AMI) │
└──────────────┘ └──────────────┘ └──────────────┘
│ │
│ nix build │ launch
▼ ▼
┌──────────────┐ ┌──────────────┐
│ flake.nix │ │ CLAWDINATOR │
│ + modules │ │ instance │
└──────────────┘ └──────────────┘
│
┌─────────────────┼─────────────────┐
▼ ▼ ▼
┌──────────┐ ┌──────────┐ ┌──────────┐
│ Discord │ │ GitHub │ │ EFS │
│ gateway │ │ monitor │ │ (memory) │
└──────────┘ └──────────┘ └──────────┘
- Build:
nixos-generatorsproduces a raw NixOS image - Upload: Raw image goes to S3
- Import: AWS VM Import creates an AMI from the S3 object
- Launch: OpenTofu provisions EC2 from the AMI
- Bootstrap: Instance downloads secrets from S3, runs
nixos-rebuild switch - Run: Gateway starts, connects to Discord, monitors GitHub
Most NixOS-on-AWS guides involve:
- Manual SSH sessions
- In-place
nixos-rebuildon running instances - Configuration drift over time
- Snowflake machines
This repo takes a different approach: image-based provisioning only.
- No SSH required (or even enabled by default)
- Every deploy is a fresh AMI
- The repo is the single source of truth
- Machines are cattle, not pets
We needed AI agents that:
- Run 24/7 monitoring clawdbot repos
- Respond to maintainer requests on Discord
- Share context across instances (hive mind)
- Self-update without human intervention
- Have consistent personality and capabilities
CLAWDINATORs are the result.
If you just want to understand the NixOS-on-AWS pattern, start here.
- Determinate Nix installed
- AWS credentials configured (
~/.aws/credentialsor env vars) - Basic familiarity with Nix flakes
# Clone
git clone https://github.com/joshp123/clawdinators.git
cd clawdinators
# See the NixOS module (the interesting part)
less nix/modules/clawdinator.nix
# See how hosts are configured
less nix/hosts/clawdinator-1.nix
# See the OpenTofu infra
less infra/opentofu/aws/main.tf
# See the bootstrap scripts
ls scripts/| File | What it teaches |
|---|---|
nix/modules/clawdinator.nix |
How to write a NixOS module for a complex service |
scripts/build-image.sh |
How to build raw NixOS images |
scripts/import-image.sh |
How to import images as AWS AMIs |
infra/opentofu/aws/ |
How to wire up S3 + IAM + VM Import |
# 1. Define your NixOS configuration
{ config, pkgs, ... }: {
imports = [ ./modules/your-service.nix ];
services.your-service.enable = true;
}
# 2. Build a raw image
# nix run github:nix-community/nixos-generators -- -f raw -c your-config.nix
# 3. Upload to S3 + import as AMI (see scripts/)
# 4. Launch with OpenTofu
# tofu applyFor clawdbot maintainers deploying actual CLAWDINATORs.
- Access to
nix-secretsrepo (agenix keys) - AWS credentials with sufficient permissions
- GitHub App credentials for the clawdbot org
# 1. Build the image
./scripts/build-image.sh clawdinator-1
# 2. Upload to S3
./scripts/upload-image.sh dist/nixos.img
# 3. Import as AMI
./scripts/import-image.sh
# 4. Upload bootstrap bundle (secrets + repo seeds)
./scripts/upload-bootstrap.sh clawdinator-1
# 5. Apply OpenTofu
cd infra/opentofu/aws
tofu init
tofu apply
# 6. Instance boots, pulls bootstrap, runs nixos-rebuild switch
# Gateway starts automatically# Check Discord - CLAWDINATOR should announce itself in #clawdributors-test
# Check GitHub - should see activity in clawdbot org reposCLAWDINATORs update themselves via a systemd timer:
flake lock --update-input nix-clawdbotnixos-rebuild switch- Gateway restarts with new version
No human intervention required for routine updates.
Paste this to your AI assistant to help with clawdinators setup/debugging:
I'm working with the clawdinators repo (NixOS-on-AWS + AI coding agents).
Repository: github:joshp123/clawdinators
What clawdinators is:
- Two layers: generic NixOS-on-AWS infra + CLAWDINATOR-specific agent stuff
- Image-based provisioning only (no SSH, no drift)
- OpenTofu for AWS resources, agenix for secrets
- CLAWDINATORs are AI agents that monitor GitHub and respond on Discord
Key files:
- nix/modules/clawdinator.nix — main NixOS module
- nix/hosts/ — host configurations
- scripts/ — build, upload, import, bootstrap scripts
- infra/opentofu/aws/ — AWS infrastructure
- clawdinator/workspace/ — agent workspace templates
- memory/ — shared hive-mind templates
Secrets are in a separate nix-secrets repo using agenix.
What I need help with:
[DESCRIBE YOUR TASK]
The clawdinator module exposes these options:
{
services.clawdinator = {
enable = true;
# Identity
instanceName = "clawdinator-1";
# Providers
discord = {
botTokenFile = "/run/agenix/discord-bot-token";
guildId = "...";
channelIds = [ "..." ];
};
anthropic.apiKeyFile = "/run/agenix/anthropic-api-key";
openai.apiKeyFile = "/run/agenix/openai-api-key";
# GitHub App
github = {
appId = "...";
installationId = "...";
privateKeyFile = "/run/agenix/github-app-key";
};
# Memory (EFS)
memory = {
enable = true;
mountPoint = "/var/lib/clawd/memory";
efsId = "fs-...";
};
};
}See nix/modules/clawdinator.nix for all options.
Secrets are managed with agenix:
- Encrypted in git (in the
nix-secretsrepo) - Decrypted to
/run/agenix/*on hosts at boot - Never in plaintext in this repo
| Secret | Purpose |
|---|---|
| Discord bot token | Gateway authentication |
| Anthropic API key | Claude models |
| OpenAI API key | GPT/Codex models |
| GitHub App private key | Short-lived installation tokens |
| agenix host key | Decryption on the instance |
The bootstrap service downloads these from S3 at first boot:
s3://bucket/bootstrap/clawdinator-1/
├── secrets/ # agenix-encrypted files
├── repos/ # git repo seeds
└── config.json # instance metadata
clawdinators/
├── nix/
│ ├── modules/
│ │ └── clawdinator.nix # Main NixOS module
│ ├── hosts/
│ │ └── clawdinator-1.nix # Host configuration
│ └── examples/ # Example configs for learners
├── infra/
│ └── opentofu/
│ └── aws/ # S3 + IAM + VM Import + EC2
├── scripts/
│ ├── build-image.sh # Build raw NixOS image
│ ├── upload-image.sh # Upload to S3
│ ├── import-image.sh # Import as AMI
│ ├── upload-bootstrap.sh # Upload secrets + seeds
│ ├── mint-github-app-token.sh
│ ├── memory-read.sh # Shared memory access
│ ├── memory-write.sh
│ └── memory-edit.sh
├── clawdinator/
│ └── workspace/ # Agent workspace templates
│ ├── AGENTS.md
│ ├── SOUL.md
│ ├── IDENTITY.md
│ └── skills/
├── memory/ # Hive-mind templates
│ ├── project.md
│ ├── ops.md
│ └── discord.md
├── docs/
│ ├── PHILOSOPHY.md
│ ├── ARCHITECTURE.md
│ ├── SHARED_MEMORY.md
│ └── SECRETS.md
└── flake.nix
| Repo | Role |
|---|---|
| clawdbot | Upstream runtime + gateway |
| nix-clawdbot | Nix packaging for clawdbot |
| clawdhub | Public skill registry |
| ai-stack | Public agent defaults + skills |
- Declarative-first. A CLAWDINATOR can bootstrap another CLAWDINATOR with a single command.
- No manual host edits. The repo + agenix secrets are the source of truth.
- Image-based only. No SSH, no in-place drift, no pets.
- Self-updating. CLAWDINATORs maintain themselves.
Beautiful is better than ugly.
Explicit is better than implicit.
Simple is better than complex.
Complex is better than complicated.
Flat is better than nested.
Sparse is better than dense.
Readability counts.
Special cases aren't special enough to break the rules.
Although practicality beats purity.
Errors should never pass silently.
Unless explicitly silenced.
In the face of ambiguity, refuse the temptation to guess.
There should be one-- and preferably only one --obvious way to do it.
MIT - see LICENSE
A note on commercial use: Please do NOT make a commercial service out of this. That would be very un-br00tal. Clawdbot should stay fun and open — commercial hosting ruins the vibe. Yes, the license permits this, but that doesn't mean the community will like you if you do it.
