---
title: "Run Autohand Code on AWS EC2"
source: https://docs.autohand.ai/tutorials/run-autohand-on-aws-ec2
---

# Run Autohand Code on AWS EC2

Create a small EC2 Linux runner for Autohand Code, restrict access with AWS security groups, and run repeatable headless jobs against a repository.

Intermediate 35 min

## Provider docs used

This tutorial follows the shape of the AWS EC2 getting started guide: launch an instance, choose an image and instance type, attach a key pair, control inbound traffic with a security group, and connect with SSH. Keep the AWS guide open for current console labels and region-specific defaults: [Get started with Amazon EC2](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/EC2_GetStarted.html).

## Architecture

The EC2 instance is the Autohand Code runner. It holds a working copy of your repository, an Autohand Code config, provider credentials, and optional cron or systemd timers. Humans connect over SSH or AWS Systems Manager Session Manager; automation can call a local webhook endpoint through a private load balancer, API Gateway, or Cloudflare Tunnel.

| Component | Recommendation |
|---|---|
| AMI | Ubuntu LTS or Amazon Linux; use the same family across runners |
| Instance type | Start small, then scale CPU and memory to match your repo build requirements |
| Storage | Use enough EBS space for the repo, dependencies, build artifacts, and logs |
| Network | Allow SSH only from trusted IP ranges or use Session Manager |
| Identity | Use a dedicated Unix user and a dedicated Git deploy key |

## Step 1: Launch the EC2 instance

1.  Open the EC2 console and choose **Launch instance**.
2.  Name the instance `autohand-runner`.
3.  Select an Ubuntu LTS or Amazon Linux image.
4.  Select an instance type that is large enough for your repository tests.
5.  Create or select a key pair. Do not proceed without a key pair if you plan to use SSH.
6.  In network settings, create a security group that allows SSH only from your trusted IP address or VPN CIDR.
7.  Launch the instance and wait until instance status checks pass.

**Production warning:** AWS shows an easy path that allows SSH from anywhere. Use that only for a short-lived test. For a real runner, restrict inbound SSH, use Session Manager, or place access behind a private network.

## Step 2: Connect and create a runner user

Use the SSH command from the EC2 console's **Connect** tab. The user depends on your AMI, such as `ubuntu` for Ubuntu or `ec2-user` for Amazon Linux.

``` bash
chmod 400 ~/.ssh/autohand-runner.pem
ssh -i ~/.ssh/autohand-runner.pem ubuntu@ec2-198-51-100-1.compute.amazonaws.com

sudo adduser --disabled-password --gecos "" autohand
sudo usermod -aG sudo autohand
sudo su - autohand
```

## Step 3: Install Node.js, Git, and Autohand Code

``` bash
sudo apt-get update
sudo apt-get install -y ca-certificates curl git build-essential

# Install Node.js from your approved source, then verify:
node --version
npm --version

npm install -g autohand-cli
autohand --version
```

Pin the Autohand Code CLI version for production runners if your organization requires repeatable deployments.

## Step 4: Configure credentials

Store model provider credentials in a file owned by the runner user, or inject them from AWS Secrets Manager into the shell environment before starting a job.

``` bash
mkdir -p ~/.autohand
chmod 700 ~/.autohand

cat > ~/.autohand/env <<'EOF'
export OPENROUTER_API_KEY="sk-or-v1-..."
export AUTOHAND_MODEL="anthropic/claude-sonnet-4"
export AUTOHAND_OUTPUT_FORMAT="stream-json"
EOF
chmod 600 ~/.autohand/env
source ~/.autohand/env
```

## Step 5: Clone and prepare the repository

``` bash
mkdir -p ~/work ~/logs
cd ~/work
git clone git@github.com:your-org/your-repo.git
cd your-repo

autohand -p "Inspect this repository and update AGENTS.md with build, test, and style instructions for future headless jobs" --restricted
```

## Step 6: Run the first EC2 job

Start with restricted mode so you can confirm access, model credentials, and logging before allowing changes.

``` bash
source ~/.autohand/env
cd ~/work/your-repo

git pull --ff-only
autohand -p "Review the latest repository state and summarize the highest-priority issues" \
  --restricted \
  --output-format stream-json | tee -a ~/logs/review.jsonl
```

## Step 7: Schedule or trigger jobs

Use cron for simple scheduled work. Use EventBridge, Systems Manager Run Command, GitHub Actions over SSH, or a small webhook process for triggered work.

``` bash
crontab -e
```

``` bash
# Weekday review at 08:00 UTC
0 8 * * 1-5 . $HOME/.autohand/env && cd $HOME/work/your-repo && git pull --ff-only && autohand -p "Review changes from the last 24 hours and list action items" --restricted --output-format json >> $HOME/logs/daily-review.jsonl 2>&1
```

## Operations checklist

-   Enable CloudWatch or your normal log shipper for `~/logs` if jobs need central visibility.
-   Use EBS snapshots before changing runner images or allowing write jobs.
-   Rotate SSH keys, Git deploy keys, and model provider keys separately.
-   Prefer `--restricted` for review jobs and explicit `--yes` only for narrow trusted write jobs.
-   Terminate unused instances so idle runners do not continue accruing cost.