Skip to content

Commit 166500a

Browse files
committed
Add AWS single-node deployment assets
1 parent a3274ed commit 166500a

18 files changed

Lines changed: 1514 additions & 2 deletions

File tree

.github/workflows/deploy.yml

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
name: Deploy Assets
2+
3+
on:
4+
pull_request:
5+
paths:
6+
- ".github/workflows/deploy.yml"
7+
- ".gitignore"
8+
- "deploy/**"
9+
push:
10+
paths:
11+
- ".github/workflows/deploy.yml"
12+
- ".gitignore"
13+
- "deploy/**"
14+
15+
jobs:
16+
validate:
17+
runs-on: ubuntu-latest
18+
env:
19+
PACKER_VERSION: "1.15.3"
20+
TERRAFORM_VERSION: "1.15.3"
21+
steps:
22+
- uses: actions/checkout@v4
23+
24+
- uses: actions/setup-go@v6
25+
with:
26+
go-version: "1.25.4"
27+
cache: false
28+
29+
- name: Install validation tools
30+
run: |
31+
set -euo pipefail
32+
python3 -m pip install --user cfn-lint
33+
34+
arch="$(uname -m)"
35+
case "$arch" in
36+
x86_64|amd64) hc_arch=amd64 ;;
37+
aarch64|arm64) hc_arch=arm64 ;;
38+
*) echo "unsupported arch: $arch" >&2; exit 1 ;;
39+
esac
40+
41+
tmp_dir="$(mktemp -d)"
42+
trap 'rm -rf "$tmp_dir"' EXIT
43+
curl -fsSL -o "$tmp_dir/terraform.zip" "https://releases.hashicorp.com/terraform/${TERRAFORM_VERSION}/terraform_${TERRAFORM_VERSION}_linux_${hc_arch}.zip"
44+
curl -fsSL -o "$tmp_dir/packer.zip" "https://releases.hashicorp.com/packer/${PACKER_VERSION}/packer_${PACKER_VERSION}_linux_${hc_arch}.zip"
45+
unzip -q "$tmp_dir/terraform.zip" -d "$tmp_dir/terraform"
46+
unzip -q "$tmp_dir/packer.zip" -d "$tmp_dir/packer"
47+
sudo install -m 0755 "$tmp_dir/terraform/terraform" /usr/local/bin/terraform
48+
sudo install -m 0755 "$tmp_dir/packer/packer" /usr/local/bin/packer
49+
50+
- name: Validate CloudFormation
51+
run: |
52+
cfn-lint deploy/aws/single-node/cloudformation/template.yaml
53+
go test ./deploy/aws/single-node/cloudformation
54+
55+
- name: Validate scripts
56+
run: bash -n deploy/aws/single-node/scripts/launch-cloudshell.sh deploy/aws/single-node/scripts/validate.sh
57+
58+
- name: Validate Terraform
59+
run: |
60+
terraform -chdir=deploy/aws/single-node/terraform init -backend=false
61+
terraform -chdir=deploy/aws/single-node/terraform fmt -check
62+
terraform -chdir=deploy/aws/single-node/terraform validate
63+
64+
- name: Validate Packer
65+
run: |
66+
packer init deploy/aws/ami/packer/hypeman.pkr.hcl
67+
packer fmt -check deploy/aws/ami/packer/hypeman.pkr.hcl
68+
packer validate deploy/aws/ami/packer/hypeman.pkr.hcl

.gitignore

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,12 @@ lib/hypervisor/vz/vz-shim/vz-shim
2828
lib/ingress/binaries/**
2929
dist/**
3030

31+
# Terraform
32+
**/.terraform/
33+
*.tfstate
34+
*.tfstate.*
35+
crash.log
36+
3137
# UTM VM - downloaded ISO files
3238
scripts/utm/images/
3339

deploy/README.md

Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
# Deploy Hypeman
2+
3+
This directory contains supported deployment assets for running Hypeman outside local development.
4+
5+
## Quickstart: AWS CloudFormation
6+
7+
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.
8+
9+
Open AWS CloudShell in `us-east-1`, then run:
10+
11+
```sh
12+
export HYPEMAN_ALLOWED_API_CIDR="$(curl -fsSL https://checkip.amazonaws.com)/32"
13+
14+
curl -fsSL https://raw.githubusercontent.com/kernel/hypeman/main/deploy/aws/single-node/scripts/launch-cloudshell.sh | bash
15+
```
16+
17+
After the stack reaches `CREATE_COMPLETE`, use the `SsmSessionCommand` output to open a Session Manager shell and generate a remote API token:
18+
19+
```sh
20+
sudo hypeman-create-token remote-user 8760h
21+
```
22+
23+
On your local machine, install the Hypeman CLI and point it at the stack's `HypemanEndpoint` output:
24+
25+
```sh
26+
curl -fsSL https://get.hypeman.sh/cli | bash
27+
28+
mkdir -p ~/.config/hypeman
29+
cat > ~/.config/hypeman/cli.yaml <<EOF
30+
base_url: http://<public-ip>:8080
31+
api_key: "<jwt-from-hypeman-create-token>"
32+
EOF
33+
34+
hypeman ps
35+
```
36+
37+
Then push and run a real sandbox image through the remote API:
38+
39+
```sh
40+
mkdir -p /tmp/hypeman-claude-code
41+
cat > /tmp/hypeman-claude-code/Dockerfile <<'EOF'
42+
FROM node:22-bookworm-slim
43+
RUN npm install -g @anthropic-ai/claude-code
44+
WORKDIR /workspace
45+
CMD ["sleep", "infinity"]
46+
EOF
47+
48+
docker build -t local/claude-code-sandbox:latest /tmp/hypeman-claude-code
49+
hypeman push local/claude-code-sandbox:latest sandbox/claude-code:latest
50+
51+
until hypeman image get sandbox/claude-code:latest | grep -qi ready; do
52+
sleep 2
53+
done
54+
55+
hypeman run --name claude-code-sandbox sandbox/claude-code:latest
56+
hypeman exec claude-code-sandbox -- claude --version
57+
```
58+
59+
Clean up the sandbox when you are done:
60+
61+
```sh
62+
hypeman stop claude-code-sandbox
63+
hypeman rm claude-code-sandbox
64+
```
65+
66+
See the [AWS single-node guide](aws/single-node) for CloudFormation parameters, Terraform usage, troubleshooting, and teardown.
67+
68+
## Supported deployments
69+
70+
| Platform | Deployment | Best for | Path |
71+
| --- | --- | --- | --- |
72+
| AWS | Single node | Trying Hypeman quickly, small internal deployments, development hosts | [aws/single-node](aws/single-node) |
73+
74+
## Choosing a deployment path
75+
76+
Use the AWS single-node deployment if you want the fastest path to a working Hypeman host in your own AWS account.
77+
78+
The single-node deployment provides three launch surfaces:
79+
80+
| Method | Best for |
81+
| --- | --- |
82+
| CloudFormation | Click-through setup in the AWS console |
83+
| CloudShell script | Scripted setup without installing local tools |
84+
| Terraform | Teams that manage AWS infrastructure with Terraform |
85+
86+
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.
87+
88+
## Security model
89+
90+
The deployment defaults are intentionally conservative:
91+
92+
- Administration uses AWS Systems Manager Session Manager by default.
93+
- SSH is optional.
94+
- Inbound access is restricted by CIDR parameters.
95+
- EBS volumes are encrypted.
96+
- The Hypeman version is controlled by parameter.
97+
- Stack deletion removes created resources unless data retention is explicitly enabled.
98+
99+
Review the cloud-specific README before launching anything in a production AWS account.
100+
101+
## Cost
102+
103+
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.
104+
105+
## Support level
106+
107+
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.

deploy/aws/README.md

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
# AWS Deployments
2+
3+
This directory contains supported AWS deployment assets for Hypeman.
4+
5+
## Available deployments
6+
7+
| Deployment | Description | Path |
8+
| --- | --- | --- |
9+
| Single node | One EC2 instance running Hypeman with nested virtualization enabled | [single-node](single-node) |
10+
11+
## Requirements
12+
13+
You need:
14+
15+
- An AWS account with permission to create EC2, IAM, CloudFormation, Lambda, Systems Manager, CloudWatch Logs, and related networking resources.
16+
- Access to a region where the selected instance type is available.
17+
- EC2 quota for the selected instance size.
18+
- A VPC and subnet for the instance.
19+
- An instance type that supports EC2 nested virtualization.
20+
21+
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.
22+
23+
## Launch methods
24+
25+
### CloudFormation
26+
27+
Use CloudFormation when you want a guided AWS console flow.
28+
29+
Start with the single-node deployment:
30+
31+
[Single-node CloudFormation deployment](single-node#cloudformation)
32+
33+
### CloudShell
34+
35+
Use CloudShell when you want a copy-paste command from the AWS console without installing local tools.
36+
37+
[Single-node CloudShell deployment](single-node#cloudshell)
38+
39+
### Terraform
40+
41+
Use Terraform when you want to review, version, and apply the AWS resources from your existing infrastructure workflow.
42+
43+
[Single-node Terraform deployment](single-node#terraform)
44+
45+
## Networking
46+
47+
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.
48+
49+
The default path does not require SSH. Use AWS Systems Manager Session Manager for host access.
50+
51+
## Cleanup
52+
53+
Each deployment README includes teardown instructions. Prefer deleting the CloudFormation stack or running `terraform destroy` instead of manually deleting individual AWS resources.
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
packer {
2+
required_plugins {
3+
amazon = {
4+
version = ">= 1.3.0"
5+
source = "github.com/hashicorp/amazon"
6+
}
7+
}
8+
}
9+
10+
variable "region" {
11+
type = string
12+
default = "us-east-1"
13+
}
14+
15+
variable "instance_type" {
16+
type = string
17+
default = "c8i.large"
18+
}
19+
20+
variable "hypeman_version" {
21+
type = string
22+
default = "latest"
23+
}
24+
25+
source "amazon-ebs" "hypeman" {
26+
region = var.region
27+
instance_type = var.instance_type
28+
ssh_username = "ubuntu"
29+
ami_name = "hypeman-{{timestamp}}"
30+
ami_description = "Hypeman API host image"
31+
32+
source_ami_filter {
33+
filters = {
34+
name = "ubuntu/images/hvm-ssd-gp3/ubuntu-noble-24.04-amd64-server-*"
35+
root-device-type = "ebs"
36+
virtualization-type = "hvm"
37+
}
38+
owners = ["099720109477"]
39+
most_recent = true
40+
}
41+
42+
launch_block_device_mappings {
43+
device_name = "/dev/sda1"
44+
volume_size = 100
45+
volume_type = "gp3"
46+
encrypted = true
47+
delete_on_termination = true
48+
}
49+
}
50+
51+
build {
52+
sources = ["source.amazon-ebs.hypeman"]
53+
54+
provisioner "shell" {
55+
inline = [
56+
"set -euxo pipefail",
57+
"sudo apt-get update",
58+
"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",
59+
"sudo systemctl enable docker",
60+
"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",
61+
"sudo systemctl stop hypeman",
62+
"sudo rm -f /root/.config/hypeman/cli.yaml",
63+
"sudo cloud-init clean --logs",
64+
]
65+
}
66+
}

0 commit comments

Comments
 (0)