Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
68 changes: 68 additions & 0 deletions .github/workflows/deploy.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
name: Deploy Assets

on:
pull_request:
paths:
- ".github/workflows/deploy.yml"
- ".gitignore"
- "deploy/**"
push:
paths:
- ".github/workflows/deploy.yml"
- ".gitignore"
- "deploy/**"

jobs:
validate:
runs-on: ubuntu-latest
env:
PACKER_VERSION: "1.15.3"
TERRAFORM_VERSION: "1.15.3"
steps:
- uses: actions/checkout@v4

- uses: actions/setup-go@v6
with:
go-version: "1.25.4"
cache: false

- name: Install validation tools
run: |
set -euo pipefail
python3 -m pip install --user cfn-lint

arch="$(uname -m)"
case "$arch" in
x86_64|amd64) hc_arch=amd64 ;;
aarch64|arm64) hc_arch=arm64 ;;
*) echo "unsupported arch: $arch" >&2; exit 1 ;;
esac

tmp_dir="$(mktemp -d)"
trap 'rm -rf "$tmp_dir"' EXIT
curl -fsSL -o "$tmp_dir/terraform.zip" "https://releases.hashicorp.com/terraform/${TERRAFORM_VERSION}/terraform_${TERRAFORM_VERSION}_linux_${hc_arch}.zip"
curl -fsSL -o "$tmp_dir/packer.zip" "https://releases.hashicorp.com/packer/${PACKER_VERSION}/packer_${PACKER_VERSION}_linux_${hc_arch}.zip"
unzip -q "$tmp_dir/terraform.zip" -d "$tmp_dir/terraform"
unzip -q "$tmp_dir/packer.zip" -d "$tmp_dir/packer"
sudo install -m 0755 "$tmp_dir/terraform/terraform" /usr/local/bin/terraform
sudo install -m 0755 "$tmp_dir/packer/packer" /usr/local/bin/packer

- name: Validate CloudFormation
run: |
cfn-lint deploy/aws/single-node/cloudformation/template.yaml
go test ./deploy/aws/single-node/cloudformation

- name: Validate scripts
run: bash -n deploy/aws/single-node/scripts/launch-cloudshell.sh deploy/aws/single-node/scripts/validate.sh

- name: Validate Terraform
run: |
terraform -chdir=deploy/aws/single-node/terraform init -backend=false
terraform -chdir=deploy/aws/single-node/terraform fmt -check
terraform -chdir=deploy/aws/single-node/terraform validate

- name: Validate Packer
run: |
packer init deploy/aws/ami/packer/hypeman.pkr.hcl
packer fmt -check deploy/aws/ami/packer/hypeman.pkr.hcl
packer validate deploy/aws/ami/packer/hypeman.pkr.hcl
6 changes: 6 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,12 @@ lib/hypervisor/vz/vz-shim/vz-shim
lib/ingress/binaries/**
dist/**

# Terraform
**/.terraform/
*.tfstate
*.tfstate.*
crash.log

# UTM VM - downloaded ISO files
scripts/utm/images/

Expand Down
107 changes: 107 additions & 0 deletions deploy/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
# Deploy Hypeman

This directory contains supported deployment assets for running Hypeman outside local development.

## Quickstart: AWS CloudFormation

The first-class AWS quickstart is the single-node CloudFormation deployment. It launches one EC2 host with nested virtualization enabled, exposes the Hypeman API only to the CIDR you choose, and prints the commands needed to connect and create a JWT.

Open AWS CloudShell in `us-east-1`, then run:

```sh
export HYPEMAN_ALLOWED_API_CIDR="$(curl -fsSL https://checkip.amazonaws.com)/32"

curl -fsSL https://raw.githubusercontent.com/kernel/hypeman/main/deploy/aws/single-node/scripts/launch-cloudshell.sh | bash
```

After the stack reaches `CREATE_COMPLETE`, use the `SsmSessionCommand` output to open a Session Manager shell and generate a remote API token:

```sh
sudo hypeman-create-token remote-user 8760h
```

On your local machine, install the Hypeman CLI and point it at the stack's `HypemanEndpoint` output:

```sh
curl -fsSL https://get.hypeman.sh/cli | bash

mkdir -p ~/.config/hypeman
cat > ~/.config/hypeman/cli.yaml <<EOF
base_url: http://<public-ip>:8080
api_key: "<jwt-from-hypeman-create-token>"
EOF

hypeman ps
```

Then push and run a real sandbox image through the remote API:

```sh
mkdir -p /tmp/hypeman-claude-code
cat > /tmp/hypeman-claude-code/Dockerfile <<'EOF'
FROM node:22-bookworm-slim
RUN npm install -g @anthropic-ai/claude-code
WORKDIR /workspace
CMD ["sleep", "infinity"]
EOF

docker build -t local/claude-code-sandbox:latest /tmp/hypeman-claude-code
hypeman push local/claude-code-sandbox:latest sandbox/claude-code:latest

until hypeman image get sandbox/claude-code:latest | grep -qi ready; do
sleep 2
done

hypeman run --name claude-code-sandbox sandbox/claude-code:latest
hypeman exec claude-code-sandbox -- claude --version
```

Clean up the sandbox when you are done:

```sh
hypeman stop claude-code-sandbox
hypeman rm claude-code-sandbox
```

See the [AWS single-node guide](aws/single-node) for CloudFormation parameters, Terraform usage, troubleshooting, and teardown.

## Supported deployments

| Platform | Deployment | Best for | Path |
| --- | --- | --- | --- |
| AWS | Single node | Trying Hypeman quickly, small internal deployments, development hosts | [aws/single-node](aws/single-node) |

## Choosing a deployment path

Use the AWS single-node deployment if you want the fastest path to a working Hypeman host in your own AWS account.

The single-node deployment provides three launch surfaces:

| Method | Best for |
| --- | --- |
| CloudFormation | Click-through setup in the AWS console |
| CloudShell script | Scripted setup without installing local tools |
| Terraform | Teams that manage AWS infrastructure with Terraform |

All methods create the same basic shape: one EC2 instance with nested virtualization enabled, an instance role, security group rules, encrypted storage, logging, and startup automation for Hypeman.

## Security model

The deployment defaults are intentionally conservative:

- Administration uses AWS Systems Manager Session Manager by default.
- SSH is optional.
- Inbound access is restricted by CIDR parameters.
- EBS volumes are encrypted.
- The Hypeman version is controlled by parameter.
- Stack deletion removes created resources unless data retention is explicitly enabled.

Review the cloud-specific README before launching anything in a production AWS account.

## Cost

Cloud resources created from these templates bill to your cloud account. The largest cost is the EC2 instance. Stop or delete the deployment when you are done testing.

## Support level

Files under this directory are intended to be maintained deployment paths, not throwaway examples. Changes should preserve upgrade, teardown, and security behavior unless the README explicitly calls out a breaking change.
53 changes: 53 additions & 0 deletions deploy/aws/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
# AWS Deployments

This directory contains supported AWS deployment assets for Hypeman.

## Available deployments

| Deployment | Description | Path |
| --- | --- | --- |
| Single node | One EC2 instance running Hypeman with nested virtualization enabled | [single-node](single-node) |

## Requirements

You need:

- An AWS account with permission to create EC2, IAM, CloudFormation, Lambda, Systems Manager, CloudWatch Logs, and related networking resources.
- Access to a region where the selected instance type is available.
- EC2 quota for the selected instance size.
- A VPC and subnet for the instance.
- An instance type that supports EC2 nested virtualization.

For the initial deployment path, use an Intel C8i, M8i, or R8i instance type. The default is chosen for a balance of cost and enough room to run useful Hypeman workloads.

## Launch methods

### CloudFormation

Use CloudFormation when you want a guided AWS console flow.

Start with the single-node deployment:

[Single-node CloudFormation deployment](single-node#cloudformation)

### CloudShell

Use CloudShell when you want a copy-paste command from the AWS console without installing local tools.

[Single-node CloudShell deployment](single-node#cloudshell)

### Terraform

Use Terraform when you want to review, version, and apply the AWS resources from your existing infrastructure workflow.

[Single-node Terraform deployment](single-node#terraform)

## Networking

The single-node deployment uses an existing VPC and subnet. If public API access is enabled, restrict access to your current IP or a trusted CIDR.

The default path does not require SSH. Use AWS Systems Manager Session Manager for host access.

## Cleanup

Each deployment README includes teardown instructions. Prefer deleting the CloudFormation stack or running `terraform destroy` instead of manually deleting individual AWS resources.
66 changes: 66 additions & 0 deletions deploy/aws/ami/packer/hypeman.pkr.hcl
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
packer {
required_plugins {
amazon = {
version = ">= 1.3.0"
source = "github.com/hashicorp/amazon"
}
}
}

variable "region" {
type = string
default = "us-east-1"
}

variable "instance_type" {
type = string
default = "c8i.large"
}

variable "hypeman_version" {
type = string
default = "latest"
}

source "amazon-ebs" "hypeman" {
region = var.region
instance_type = var.instance_type
ssh_username = "ubuntu"
ami_name = "hypeman-{{timestamp}}"
ami_description = "Hypeman API host image"

source_ami_filter {
filters = {
name = "ubuntu/images/hvm-ssd-gp3/ubuntu-noble-24.04-amd64-server-*"
root-device-type = "ebs"
virtualization-type = "hvm"
}
owners = ["099720109477"]
most_recent = true
}

launch_block_device_mappings {
device_name = "/dev/sda1"
volume_size = 100
volume_type = "gp3"
encrypted = true
delete_on_termination = true
}
}

build {
sources = ["source.amazon-ebs.hypeman"]

provisioner "shell" {
inline = [
"set -euxo pipefail",
"sudo apt-get update",
"sudo DEBIAN_FRONTEND=noninteractive apt-get install -y ca-certificates curl docker.io e2fsprogs erofs-utils iproute2 iptables jq openssl qemu-system-x86 qemu-utils tar",
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

install the native compression libraries used by snapshot compression

"sudo systemctl enable docker",
"if [ '${var.hypeman_version}' = 'latest' ]; then curl -fsSL https://raw.githubusercontent.com/kernel/hypeman/main/scripts/install.sh | sudo bash; else curl -fsSL https://raw.githubusercontent.com/kernel/hypeman/main/scripts/install.sh | sudo VERSION='${var.hypeman_version}' bash; fi",
"sudo systemctl stop hypeman",
"sudo rm -f /root/.config/hypeman/cli.yaml",
"sudo cloud-init clean --logs",
]
}
}
Loading
Loading