Skip to main content

Phase 1 — Bare Nomad setup

The only hard prerequisite for a seedling deployment is a running Nomad node with ACLs enabled. Everything else (MinIO, tusd, the claim service) is installed on top by the Pulumi stack in Phase 2.

This page covers a minimal single-node Nomad install. If you already have Nomad running with ACLs enabled and a management token, skip to Phase 2.

Install Nomad

The official HashiCorp package repository is the recommended install path. These steps work on Ubuntu 22.04 / Debian 12; adapt for your distribution.

# Add HashiCorp apt repository
wget -O - https://apt.releases.hashicorp.com/gpg | \
sudo gpg --dearmor -o /usr/share/keyrings/hashicorp-archive-keyring.gpg

echo "deb [signed-by=/usr/share/keyrings/hashicorp-archive-keyring.gpg] \
https://apt.releases.hashicorp.com $(lsb_release -cs) main" | \
sudo tee /etc/apt/sources.list.d/hashicorp.list

sudo apt-get update && sudo apt-get install -y nomad

Verify:

nomad --version
# Nomad v1.x.y

Minimal configuration

Create /etc/nomad.d/nomad.hcl:

# Minimal single-node Nomad configuration for abc-seedling.
# Runs as both server and client on the same node.

datacenter = "dc1"
data_dir = "/opt/nomad/data"
log_level = "INFO"

server {
enabled = true
bootstrap_expect = 1
}

client {
enabled = true
}

# ACLs — required for abc-cluster token model.
acl {
enabled = true
}

# Ports — adjust if these conflict with existing services.
ports {
http = 4646
rpc = 4647
serf = 4648
}

Create the data directory and start the service:

sudo mkdir -p /opt/nomad/data
sudo systemctl enable --now nomad

Bootstrap ACLs

ACLs start in a bootstrapped state — run this exactly once:

nomad acl bootstrap
# SecretID = <bootstrap-management-token>

Save the SecretID. This is your management token — treat it like a root password. Store it securely (e.g. in a password manager or a secrets file that is never committed to git).

Verify the cluster is up and the token works:

export NOMAD_ADDR=http://localhost:4646
export NOMAD_TOKEN=<bootstrap-management-token>

nomad node status
# ID DC Name Class Drain Eligibility Status
# df319cc0 dc1 aither <none> false eligible ready

You should see your node listed with Status = ready.

Create namespaces

abc-cluster uses one Nomad namespace per group. The default namespace is reserved for admin/infrastructure jobs.

Create namespaces for each group you plan to provision:

# Create a namespace for each research group
nomad namespace apply -description "Host genetics lab" su-hostgen
nomad namespace apply -description "Demo group" su-demo

# Verify
nomad namespace list

Create the ACL policy for pool tokens

Pool tokens need write access to their own namespace. Create a policy file and register it:

cat > /tmp/pool-policy.hcl << 'HCL'
# abc-seedling pool token policy.
# Applied per namespace — one policy covers all su-* namespaces.
namespace "su-*" {
policy = "write"
capabilities = [
"submit-job", "dispatch-job", "read-job", "list-jobs",
"read-logs", "read-fs", "alloc-exec", "alloc-node-exec",
"list-jobs", "parse-job",
]
}
HCL

nomad acl policy apply -description "Pool token policy for su-* namespaces" pool-token /tmp/pool-policy.hcl

Note: provision.py creates tokens with explicit namespace capability objects rather than using a named policy, so this policy registration is optional. It is useful if you want to create pool tokens manually via the Nomad UI or CLI.

Verify

At the end of Phase 1 you should be able to run:

nomad status # empty — no jobs yet, that's expected
nomad namespace list # shows default + your su-* namespaces
nomad node status # shows your node as ready

Keep your NOMAD_ADDR and management NOMAD_TOKEN — you'll need them for Phase 2 (Pulumi bootstrap) and Phase 3 (pool provisioning).

Next step

Phase 2: Pulumi bootstrap