Skip to content

You are viewing documentation for Instruqt 2.0 Labs. For Tracks documentation, please visit docs.instruqt.com.

Nomad Cluster


Defined insandbox.hcl

The nomad_cluster resource creates HashiCorp Nomad clusters as Docker containers. Nomad clusters can be configured as single-node combined server/client instances or multi-node setups with dedicated server and client nodes.

As a lab author, you can use nomad_cluster resources to:

  • Container Orchestration Learning: Provide hands-on experience with HashiCorp Nomad for container scheduling and management
  • Multi-Node Cluster Scenarios: Create realistic distributed computing environments with server and client nodes
  • Microservices Architecture: Deploy and manage complex multi-tier applications using Nomad job specifications

Nomad cluster resources enable realistic container orchestration scenarios for learning HashiCorp’s workload scheduler.

resource "nomad_cluster" "name" {
network {
id = resource.network.main
}
}
resource "nomad_cluster" "name" {
# Network configuration
network {
id = resource.network.main
ip_address = "10.0.0.10"
aliases = ["nomad", "server"]
}
# Optional cluster configuration
client_nodes = 3
datacenter = "dc1"
environment = {
NOMAD_LOG_LEVEL = "INFO"
CUSTOM_VAR = "value"
}
# Configuration files
server_config = "./nomad/server.hcl"
client_config = "./nomad/client.hcl"
consul_config = "./consul/config.hcl"
# Image configuration
image {
name = "hashicorp/nomad:1.8.4"
username = "username"
password = "password"
}
# Volume mounts
volume {
source = "./nomad-data"
destination = "/opt/nomad/data"
type = "bind"
read_only = false
}
# Port mappings
port {
local = 4646
host = 4646
protocol = "tcp"
}
port_range {
local_range = "8000-8010"
host_range = "8000-8010"
protocol = "tcp"
}
# Image copying
copy_image {
name = "myapp:latest"
username = "registry_user"
password = "registry_pass"
}
# Driver configuration
config {
docker {
no_proxy = ["registry.local"]
insecure_registries = ["registry.local:5000"]
}
}
}

Fields

FieldTypeRequiredDescription
networkblock—Connect this resource to a specific network so it can communicate with other containers or servicesrepeatable
imageblock—Container image for the cluster nodes
client_nodesnumber—Number of client nodes
environmentmap(string)—Environment variables for the cluster
server_configstring—Path to server configuration file
client_configstring—Path to client configuration file
consul_configstring—Path to Consul configuration file
volumeblock—Attach persistent storage or share data between containers using volumesrepeatable
open_in_browserbool—Open the Nomad UI in the browser after creation
datacenterstring—Nomad datacenter, defaults to dc1
copy_imageblock—Images to copy from local docker cache to the clusterrepeatable
portblock—Expose specific ports so learners can access web apps, APIs, or services running in this resourcerepeatable
port_rangeblock—Range of ports to exposerepeatable
configblock—Driver configuration

Network

nomad_cluster→Network

Network attachments for the cluster

FieldTypeRequiredDescription
idstring—ID of the network to attach the container
targetreferencenetwork—The network to attach the container to
ip_addressstring—Static IP address to assign container for the network, the ip address must be within range defined by the network subnet. If this parameter is omitted an IP address will be automatically assigned.
ConstraintsMust be a valid IPv4 address (e.g., 192.168.1.10)
aliaseslist(string)—Aliases allow alternate names to specified for the container

Image

nomad_cluster→Image

Container image for the cluster nodes

FieldTypeRequiredDescription
namestring✓Full Docker image reference, including the registry and an optional tag. Include a specific tag to ensure consistent lab environments.
ConstraintsMust be a valid Docker image reference (e.g. ubuntu:24.04, docker.io/hashicorp/vault:1.14)
usernamestring—Only required for private Docker registries. Leave empty for public images.
passwordstring—Only required for private Docker registries. Leave empty for public images.

Volume

nomad_cluster→Volume

Volumes to attach to the cluster

FieldTypeRequiredDescription
sourcestring✓The source volume to mount in the container, can be specified as a relative `./` or absolute path `/usr/local/bin`. Relative paths are relative to the file declaring the container.
ConstraintsSource path must not be empty
destinationstring✓The destination in the container to mount the volume to, must be an absolute path
ConstraintsDestination path must not be empty
typestring—The type of the mount, can be one of the following values: - bind: bind the source path to the destination path in the container - volume: source is a Docker volume - tmpfs: create a temporary filesystem
Allowedbind volume tmpfs
Defaultbind
read_onlybool—Whether or not the volume is read only
bind_propagationstring—Configures bind propagation for Docker volume mounts, only applies to bind mounts, can be one of the following values: - shared - slave - private - rslave - rprivate For more information please see the Docker documentation
Allowedshared private slave rslave rprivate
Defaultshared
bind_propagation_non_recursivebool—Configures recursiveness of the bind mount. By default Docker mounts with the equivalent of `mount --rbind` meaning that mounts below the the source directory are visible in the container. For instance running `docker run --rm --mount type=bind,src=/,target=/host,readonly` busybox will make `/run` of the host available as `/host/run` in the container. To make matters even worse it will be writable (since only the toplevel bind is set readonly, not the children). If `bind_propagation_non_recursive` is set to true then the container will only see an empty `/host/run`, meaning the `tmpfs` which is typically mounted to `/run` on the host is not propagated into the container.
selinux_relabelstring—Configures Selinux relabeling for the container (usually specified as :z or :Z) and can be one of the following values: - shared (Equivalent to :z) - private (Equivalent to :Z)
Allowed shared private

Copy Image

nomad_cluster→Copy Image

Images to copy from local docker cache to the cluster

FieldTypeRequiredDescription
namestring✓Full Docker image reference, including the registry and an optional tag. Include a specific tag to ensure consistent lab environments.
ConstraintsMust be a valid Docker image reference (e.g. ubuntu:24.04, docker.io/hashicorp/vault:1.14)
usernamestring—Only required for private Docker registries. Leave empty for public images.
passwordstring—Only required for private Docker registries. Leave empty for public images.

Port

nomad_cluster→Port

Additional ports to expose on the server node

FieldTypeRequiredDescription
localnumber✓The local port in the container
ConstraintsMinimum 1; Maximum 65535
hostnumber—The host port to map the local port to
ConstraintsMinimum 1; Maximum 65535
protocolstring—The protocol to use when exposing the port
Allowedtcp udp
Defaulttcp

Port Range

nomad_cluster→Port Range

Range of ports to expose

FieldTypeRequiredDescription
rangestring✓Port range (e.g., '8080-8090')
enable_hostbool—Enable host port mapping
protocolstring—Protocol (tcp, udp)

Config

nomad_cluster→Config

Driver configuration

FieldTypeRequiredDescription
dockerblock—Docker driver configuration

Docker

nomad_cluster→Config→Docker

Docker driver configuration

FieldTypeRequiredDescription
no_proxylist(string)—Docker registries to exclude from the image cache
insecure_registrieslist(string)—Docker registries to treat as insecure

Computed Attributes

These attributes are set by the system and are read-only.

AttributeTypeDescription
network[].namestringName will equal the name of the network as created by jumppad
network[].assigned_addressstringAssignedAddress will equal if IPAddress is set, else it will be the value automatically assigned from the network
image.idstringUnique identifier for the image, this is independent of tag and changes each time the image is built. An image that has been tagged multiple times also shares the same ID.
copy_image[].idstringUnique identifier for the image, this is independent of tag and changes each time the image is built. An image that has been tagged multiple times also shares the same ID.
api_portnumberPort the Nomad API is running on
connector_portnumberPort where the connector is running
config_dirstringDirectory where server and client config is written
server_container_namestringFully qualified docker address for the server
client_container_namelist(string)Fully qualified docker addresses for the client nodes
external_ipstringIP address of the cluster
resource "network" "nomad" {
subnet = "10.0.0.0/24"
}
resource "nomad_cluster" "dev" {
network {
id = resource.network.nomad
}
}
resource "network" "nomad" {
subnet = "10.0.0.0/24"
}
resource "nomad_cluster" "production" {
client_nodes = 3
datacenter = "east"
network {
id = resource.network.nomad
ip_address = "10.0.0.10"
aliases = ["nomad-server", "server"]
}
environment = {
NOMAD_LOG_LEVEL = "INFO"
DATACENTER = "east"
}
volume {
source = "./nomad-data"
destination = "/opt/nomad/data"
type = "bind"
}
port {
local = 4646
host = 4646
}
}
resource "nomad_cluster" "custom" {
client_nodes = 2
network {
id = resource.network.main
}
server_config = "./config/server.hcl"
client_config = "./config/client.hcl"
consul_config = "./config/consul.hcl"
config {
docker {
no_proxy = ["registry.internal.com"]
insecure_registries = ["registry.internal.com:5000"]
}
}
copy_image {
name = "myapp:latest"
}
copy_image {
name = "postgres:13"
}
volume {
source = "./nomad-jobs"
destination = "/opt/nomad/jobs"
type = "bind"
read_only = true
}
}
resource "nomad_cluster" "dev" {
network {
id = resource.network.dev
}
environment = {
NOMAD_LOG_LEVEL = "DEBUG"
}
port_range {
local_range = "8000-8010"
host_range = "8000-8010"
protocol = "tcp"
}
port {
local = 4646
host = 4646
}
}

Nomad clusters are commonly used with nomad_job resources:

resource "nomad_cluster" "app" {
client_nodes = 2
network {
id = resource.network.app
}
}
resource "nomad_job" "web" {
cluster = resource.nomad_cluster.app
jobspec = <<-EOF
job "web" {
datacenters = ["dc1"]
group "web" {
count = 2
task "nginx" {
driver = "docker"
config {
image = "nginx:latest"
ports = ["http"]
}
resources {
cpu = 100
memory = 128
}
}
}
}
EOF
}
  1. Network Planning: Use dedicated networks for Nomad clusters to isolate traffic
  2. Resource Limits: Configure appropriate resource limits for production workloads
  3. Configuration Files: Use external configuration files for complex setups
  4. Data Persistence: Mount volumes for Nomad data directories in production
  5. Security: Use private registries and secure configuration for sensitive environments
  6. Monitoring: Expose necessary ports for monitoring and observability tools
  7. Image Management: Pre-load frequently used images using copy_image blocks