← Back to list

Bridging the Gap: Why Migrating VM Applications to Nomad is Easier Than You Think

For many infrastructure teams, the word “migration” conjures up images of complex refactoring, months of containerization efforts, and the…

Nick Wales · 2026-04-08 21:45 · 0 claps · 3.4 min read
#hashicorp-nomad #migration
Open on Medium ↗
Wiki topics: 💻 · Programming ☁️ · DevOps & Cloud

Bridging the Gap: Why Migrating VM Applications to Nomad is Easier Than You Think

For many infrastructure teams, the word “migration” conjures up images of complex refactoring, months of containerization efforts, and the daunting task of rewriting legacy logic. But if you are running applications on virtual machines (VMs) and looking for the benefits of modern orchestration — without the steep “Kubernetes tax” — HashiCorp Nomad is your secret weapon.

Nomad’s superpower is its flexibility. It doesn’t force you into a container-only world. Here is how you can move your VM-based workloads into a managed, automated ecosystem with surprising ease.

The “Lift and Shift” That Actually Works

Unlike other orchestrators that demand every application be packaged as a Docker image, Nomad treats VMs as first-class citizens. Using the QEMU or VirtualBox task drivers, you can take an existing VM image and run it as a Nomad task.

  • No Refactoring Required: Your application stays in its current VM format.
  • Centralized Scheduling: Nomad handles the placement, health checking, and restarts of those VMs across your fleet.
  • Unified Workflow: You manage VMs, Docker containers, and even raw binaries using the exact same Job Specification language (HCL).

What does this actually look like?

There are inumerable ways that people run services on machines. In this case we’ll look at what it would take to replace a systemd Java service with Nomad.

For this to work, the artifact must be deployed to the server, the systemd unit file must be created and deployed to /etc/systemd/system/ and systemctl enable --now <my-java-service>must be run to get the service running.

[Unit]
Description=My Java service
After=syslog.target network.target
StartLimitIntervalSec=5m
StartLimitBurst=5

[Service]
Type=exec
User=APPUSER
Group=apps
Environment="SOME_VARIABLE=foo"
Environment="OTHER_VARIABLE=bar"
WorkingDirectory=/home/APPUSER
ExecStart=/path/to/java -jar /path/to/binary/worker-v1.2.jar
ExecStop=kill -TERM $MAINPID
ExecStop=timeout 15 tail --pid=${MAINPID} -f /dev/null
SuccessExitStatus=143
Restart=on-failure
RestartSec=5s

[Install]
WantedBy=multi-user.target

Migrating this to Nomad can be as simple as this example. Here we have Nomad pull the artifact from your repository at runtime and ensure a couple instances of it are running with the appropriate java options configured.

job "data-worker" {
  datacenters = ["dc1"]
  type        = "service" 

  group "processing" {
    count = 2

    task "worker-task" {
      driver = "java"

      # Download the JAR from your artifact repository (S3, Artifactory, etc.)
      artifact {
        source      = "https://storage.example.com/builds/worker-v1.2.jar"
        destination = "local/worker.jar"
      }

      config {
        jar_path    = "local/worker.jar"
        jvm_options = ["-Xmx512m", "-Xms256m"]
        args        = ["--mode=cleanup", "--config=/local/config.json"]
      }

      resources {
        cpu    = 500 # MHz
        memory = 512 # MB
      }
    }
  }
}

Nomad has sane defaults for how to restart your app should issues fail. It will also collect the stdout and stderr log files and make them available.

Standardization

For all this to work we don’t need to do any other setup beyond getting the Nomad agent installed on our VMs. What makes it so great is now all of our machines look exactly the same. Only one type of machine needs to be configured, there is no need to think about the various requirements for each type of Java app or database, Nomad can deploy them anywhere with all the required dependencies.

Dynamic Power: Templating and Variables

One of the biggest hurdles in VM management is “configuration drift” — where one server’s config subtly changes over time. Nomad solves this through powerful, native templating.

The Magic of template

Nomad’s template block allows you to ship configuration files and secrets dynamically. Instead of baking environment-specific IPs or API keys into your VM image, you can pull them from HashiCorp Consul or Vault at runtime.

Variable Management

Nomad supports a hierarchical variables system. You can define variables at a global, namespace, or job level. This means your team can write one job file and deploy it across Dev, Staging, and Prod just by swapping a variable file. No more “Golden Image” sprawl; just one image and a few lines of code.

Nomad-Pack: The “App Store” for Your Infrastructure

If writing HCL from scratch still feels like a hurdle, enter Nomad-pack. Think of this as the package manager for Nomad (similar to Helm for Kubernetes, but significantly more lightweight).

  • Reusable Templates: Nomad-pack provides pre-defined blueprints for common applications.
  • Standardization: It allows platform teams to create “Packs” that include best practices for security, logging, and networking.
  • Ease of Use: A developer can deploy a complex, multi-service application with a single command: nomad-pack run my-app-pack

Why Make the Move?

Beyond the ease of migration, the immediate benefits for your team are massive:

  1. Bin Packing: Nomad optimizes your hardware. It will intelligently place VMs to ensure you aren’t paying for idle CPU cycles.
  2. Self-Healing: If a host fails, Nomad detects it and immediately restarts your VM on a healthy node.
  3. Unified Control Plane: Stop jumping between different consoles to manage containers and VMs. Nomad gives you a single pane of glass for everything.
  4. Integration: Out-of-the-box integration with Terraform for provisioning and Consul for service discovery makes the entire lifecycle seamless.

Final Thoughts

Migrating to Nomad isn’t about throwing away your VMs; it’s about giving them a better home. By leveraging native VM drivers, dynamic templating, and the simplified deployment of Nomad-pack, your team can move from manual “snowflake” server management to a robust, automated pipeline in days, not months.

Ready to start? Your existing VMs are already halfway there.


메타데이터
post_id
deb8b00f3ceb
slug
bridging-the-gap-why-migrating-vm-applications-to-nomad-is-easier-than-you-think-deb8b00f3ceb
url
https://medium.com/@nickjrwales/bridging-the-gap-why-migrating-vm-applications-to-nomad-is-easier-than-you-think-deb8b00f3ceb
canonical_url
https://medium.com/@nickjrwales/bridging-the-gap-why-migrating-vm-applications-to-nomad-is-easier-than-you-think-deb8b00f3ceb
author_url
https://medium.com/@nickjrwales
status
ok
fetched_at
2026-08-24 03:23:31