RSS

Why Bare Metal Provisioning Is a Dependency Graph, and Not a Script

Infrastructure as Code Terraform Automation Best Practices

Most bare metal provisioning guidance treats the process as a single linear script: boot, install, configure, done. In practice, it's three distinct state machines (hardware, OS, and configuration) wired together, and the pipelines that break are the ones that never modeled the dependencies between them.

TL;DR
$ cat bare-metal-provisioning.tldr
• What bare metal provisioning automates, and how it differs from bare metal imaging.
• The real architecture behind the bare metal provisioning process: hardware discovery, PXE boot, OS installation, and post-install configuration, and where each stage actually breaks.
• What a genuinely secure bare metal provisioning pipeline has to account for, beyond generic best-practice checklists.
• How the major bare metal provisioning tools, including Terraform, actually divide the work, with a breakdown of who each one suits best.

Bare metal provisioning is no longer a legacy concern. GPU fleets, dedicated-server platforms, and hybrid estates where physical hardware sits alongside cloud VMs have put it back at the center of infrastructure work.

Used effectively, it is an automated pipeline from powered-off hardware to a production-ready machine, built from stages that depend on each other in ways you should diagram.

Our guide covers the architecture in execution order, what a provisioning pipeline needs from security beyond a generic checklist, how the major open source and commercial tools divide the work (including where Terraform fits and where it doesn't), and what changes when bare metal provisioning runs inside an enterprise CI/CD pipeline rather than a one-off rack install.

What is bare metal provisioning?

Bare metal provisioning is the automated process of taking a physical server, freshly racked or wiped for reuse, from unformatted hardware to a production-ready state: discovering what the hardware is, booting it over the network, installing an operating system, and running the configuration that brings it to a known, repeatable state, without a technician touching the machine. It's the automation layer that replaced manual provisioning, where an administrator inserted install media and answered prompts one server at a time, a process that cannot scale.

Bare metal servers are the physical hardware itself, dedicated and unshared, as opposed to the virtualized slice of a host that a cloud VM represents. Bare metal provisioning turns that hardware into something usable.

Bare metal provisioning is a dependency graph, not a script

It's tempting to describe the process as four steps in sequence:

  1. Hardware discovery
  2. Network boot
  3. Operating system installation
  4. Post-install configuration

This framing is accurate but incomplete: each stage produces state the next depends on, and a change at any one can invalidate an assumption downstream if there aren't the right manual checks in place.

A firmware update can shift which NIC comes up first during PXE boot. A new base image can break a post-install playbook that assumed a package manager or kernel version that no longer matches.

Most pipelines have no way to reason about that blast radius before it happens, because they were built as a script, not a graph.

Hardware discovery and the baseboard management controller

Before anything else happens, the provisioning platform has to know what it's working with. It queries the server's baseboard management controller (BMC), the out-of-band management chip that runs independently of the host OS, over IPMI or the newer Redfish standard, to inventory CPU, RAM, storage, and NIC configuration and confirm hardware health before an install even starts.

The hardware profile and MAC address that this stage reads back determine everything that follows: which OS image applies, which network profile to assign, and which policy or template governs the rest of the run.

The PXE boot process

Once the hardware checks out, the server boots over the network rather than from local media.

A DHCP server on the provisioning network recognizes the booting machine, usually with the MAC address, and directs it to a TFTP server hosting a lightweight boot image, a provisioning kernel small enough to live entirely in memory, which hands control to the provisioning platform rather than an installed OS.

UEFI support extends this with iPXE, adding HTTP-based booting on top of the original PXE spec, an important step for hardware shipping with no legacy BIOS fallback. A provisioning network isolated from production traffic is also necessary.

OS installation

With a provisioning kernel running, the platform installs the target operating system onto the physical disk: Linux distributions through Kickstart or preseed answer files, Windows Server through Autounattend.xml.

Disk partitioning, bootloader configuration, and the first pass at network setup all run from a pre-defined server profile rather than from a technician clicking through an installer.

Provisioning Linux this way, from a known-good reference host image staged ahead of time, is what gives a heterogeneous hardware fleet consistent, repeatable OS installs instead of whatever a technician happened to click through.

Post-install configuration

The server now has an operating system but isn't yet a managed, production machine. Configuration management tools, typically Ansible over SSH with no agent required, or cloud-init on first boot, apply the final state: installing packages, creating users, configuring monitoring agents, running validation checks.

It's the handoff point where the machine stops being a provisioning target and starts being infrastructure someone owns.

None of these stages are a one-time concern. Backblaze's 2025 Drive Stats report put its fleet's annualized hard drive failure rate at 1.13% for the year, which sounds small until multiplied across a few thousand hosts and read as a recurring stream of hardware that needs re-provisioning.

Line chart from Backblaze's 2025 Drive Stats showing quarterly annualized hard drive failure rates in 2025: 1.42% in Q1, 1.36% in Q2, 1.55% in Q3, and 1.13% in Q4.

Bare metal provisioning versus imaging and virtual machines

Bare metal imaging clones a golden OS snapshot onto identical hardware. Bare metal provisioning builds server state from a defined configuration that can handle variable hardware profiles, OS versions, and post-install requirements in the same run.

Imaging is faster when every machine in a batch is identical; provisioning survives a fleet where hardware generations, NIC vendors, or regional configurations differ, which is accurate for most real fleets past a certain size.

The comparison to virtual machines is different. A VM carves a slice of shared hardware through a hypervisor layer, trading some performance for density and flexibility. Bare metal provisioning skips that layer on purpose, which is why it suits workloads that need dedicated hardware with no virtualization overhead: database primaries sensitive to I/O jitter, GPU training needing direct hardware access, and anything bound by a compliance requirement a shared host can't satisfy.

Bare metal provisioning Bare metal imaging Virtual machines
How it works Builds server state from a defined configuration Clones a golden OS snapshot onto the hardware Carves a slice of shared hardware through a hypervisor
Hardware variation Handles mixed hardware profiles, OS versions, and post-install requirements in one run Needs identical hardware across the batch Hidden from the workload by the hypervisor
Speed Slower than imaging on identical machines Fastest when every machine in the batch is identical Not tied to physical setup
Dedicated hardware Yes, no virtualization overhead Yes, no virtualization overhead No, trades some performance for density and flexibility
Best fit Fleets with mixed hardware generations, NIC vendors or regional configurations Uniform batches of identical servers Workloads that value density and flexibility over raw performance

What to look for in secure bare metal provisioning

The provisioning pipeline itself is an attack surface, not just the server it produces, so it deserves the same scrutiny that a cloud provider's API credentials get.

BMCs frequently ship with default or shared credentials across a hardware batch, and a BMC compromised through IPMI (a protocol with a documented history of weak authentication) hands an attacker remote management access to the physical machine, independent of the OS. Treat BMC credentials with the same rotation discipline as a cloud IAM role.

PXE boot is unauthenticated by design: a DHCP server answers the first request it sees, and a TFTP server serves files to whatever asks.

On a shared or improperly segmented network, a rogue device can impersonate the provisioning infrastructure and hand a booting server a malicious image first, which is why isolating the provisioning network and keeping boot and production VLANs genuinely separate is the highest-leverage control here.

Kickstart and preseed files deserve the same caution: they're commonly generated with plaintext root passwords or SSH keys embedded directly, served over HTTP to any machine that asks, and should be treated as secrets at rest.

A compromised pipeline doesn't put one server at risk, it can push a bad image to every machine in its policy scope at once. A provisioning platform's own access control and audit trail deserves the same review a terraform apply against production gets. The blast radius is comparable.

Bare metal provisioning tools

The tools in this space don't compete for the same job and instead split one pipeline into layers. Most production setups combine two or three rather than standardizing on one, a pattern consistent with the broader infrastructure as code tools landscape.

Tool Type Best for
OpenStack Ironic Bare metal provisioning service OpenStack shops that want physical servers managed through the same Nova API as virtual machines.
Foreman Full lifecycle management platform Provisioning, configuration, and monitoring for a mixed physical and virtual fleet in one tool, without requiring OpenStack.
Canonical MAAS Bare metal provisioning platform Ubuntu-centric teams that want physical servers to behave like an on-demand, cloud-like resource pool.
Tinkerbell Bare metal provisioning engine Cloud-native teams wanting Git-managed, declarative workflows defined as custom resources rather than imperative scripts.
Metal3 Kubernetes-native bare metal operator Cluster API users who want bare metal hosts provisioned as Kubernetes BareMetalHost resources alongside the clusters they support.
Cobbler Linux installation and provisioning server Smaller, Linux-only environments wanting a straightforward PXE and Kickstart server without a larger platform's overhead.
Ansible Agentless configuration management Post-install configuration once a server has an OS: package installs, user setup, idempotent state enforcement over SSH.
Terraform/OpenTofu Declarative infrastructure as code Declaring a fleet's desired state through a provider and managing it alongside the rest of an organization's cloud infrastructure as one codebase.

Terraform's role here is narrow. It isn't a PXE server, an OS installer, or a configuration management tool; it's the declarative layer calling out to whichever bare metal provider exposes a Terraform provider (Vultr, OVHcloud, and most dedicated-server and GPU cloud platforms ship one), and that provider's API triggers discovery, PXE, and OS install behind the scenes:

resource "vultr_bare_metal_server" "app_node" {
plan = "vbm-4c-32gb"
region = "ewr"
os_id = 1743 # Vultr OS ID; list current IDs with vultr-cli os list
hostname = "app-01"
label = "app-fleet"
tags = ["app", "bare-metal"]
user_data = <<-EOT
#cloud-config
package_update: true
packages:
- python3-pip
EOT
}

Terraform hands off the result (e.g., an IP address, a hostname, or a provisioning status) but still needs Ansible or cloud-init for post-install configuration – the gap every tool above fills differently.

To choose one is to question which layer of the pipeline a team is missing, not which single tool replaces the rest.

How to choose a bare metal provisioning platform for enterprises

Multi-vendor BMC and Redfish support is more important than it looks on a feature sheet, as a platform locked to one vendor's management interface doesn't survive the next refresh cycle, which are inevitable at enterprise scale.

Day 2 lifecycle management (re-imaging when a tenant changes, pushing a firmware update fleet-wide, and decommissioning cleanly) is separate from first-boot provisioning, and plenty of platforms are strong at one and weak at the other.

Concurrency under load is another criterion: what happens when two pipelines target overlapping hardware pools at once. A platform that serializes everything behind a single lock bottlenecks a fleet in exactly the same way that a single Terraform state file bottlenecks a large infrastructure as code codebase, for the same reason.

No single platform covers hardware orchestration, OS installation, and configuration management end to end for every environment.

Enterprises typically pair a hardware-layer orchestrator (Ironic, MAAS, or a provider's own API) with a configuration management layer, and more often than not a declarative IaC layer on top, so the fleet follows the same Terraform best practices and pull request review as everything else the organization runs.

Bare metal provisioning for DevOps and CI/CD pipelines

Running bare metal provisioning as a step in a Terraform CI/CD pipeline, rather than a one-off rack bring-up, changes things.

The Terraform-and-Ansible combination engineers often assemble by hand works, but most hand-rolled versions are missing what makes it safe to run unattended: a way to know, before an apply, exactly which hosts a change reaches.

State locking is where this shows up first. A pipeline that can't lock at the level of an individual host lets two runs race to claim the same machine – the physical equivalent of two terraform apply runs fighting over the same lock, except the double-claimed resource can't simply be recreated if runs collide.

Blast radius is another issue. A shared module change, like a new base image or a changed network profile, can ripple across every host referencing it, and most pipelines can't show which servers a change touches before it applies – the same problem drift detection catches after the fact on the cloud side.

Bare metal drift is harder to observe in the first place: a firmware update or a manual rack-level NIC swap won't register in a plan the way cloud API drift does, because the provider only knows what the BMC reports back.

The solution is graph-aware execution. Though it doesn't provision bare metal itself and has no BMC or Redfish driver layer of its own, Stategraph can bring a lot to the Terraform or OpenTofu layer already orchestrating bare metal providers.

With resource-level locking, two runs targeting different hosts don't queue behind each other the way they would behind a single state file's global lock, blast radius visibility means a reviewer sees which hosts a change reaches before approving it, and every plan and apply runs as a recorded transaction, the same audited history a cloud-only Terraform workflow already has.

It won't replace Ironic, MAAS, or a provider's own provisioning API. Instead, it's the execution layer wrapped around orchestration those tools already do, for teams whose bare metal fleet already belongs in the same codebase and review process as the rest of their infrastructure.

Conclusion

By winter 2024, physical infrastructure was back in direct contention with cloud VMs, with enterprise respondents to Flexera’s 2025 State of the Cloud Report saying 21% of their public cloud workloads and data had already been repatriated.

Donut chart from Flexera's 2025 State of the Cloud Report showing 21% of public cloud workloads repatriated and 79% still in the cloud.

Bare metal provisioning was no longer a legacy concern the moment physical hardware came back into direct contention with cloud VMs.

Hardware discovery, PXE boot, OS installation, and post-install configuration each produce state the next depends on, the tooling landscape can be split across those layers rather than offering one tool that does it all.

What is also important is what the pipeline itself exposes, and how a platform behaves when two changes target the same hardware pool at once.

Terraform and OpenTofu have a specific role here: the declarative layer keeping a fleet's state in the same codebase and review process as everything else an organization runs.

Try Stategraph free to bring resource-level locking, blast radius analysis, and an audited history to that layer.

Bare metal provisioning FAQs

Is bare metal provisioning the same as bare metal server provisioning?

Yes. "Bare metal provisioning" and "bare metal server provisioning" describe the same automated process of taking a physical server from unformatted hardware to production-ready state; the longer phrase makes it explicit that a server, specifically, is what's being provisioned, as opposed to a broader resource like network hardware.

Can bare metal provisioning run with no manual steps at all?

For a known, pre-racked hardware fleet with a working BMC connection, yes: discovery, PXE boot, OS installation, and post-install configuration can run end to end without a technician touching the machine.

The manual step that tends to survive the longest is physical racking and cabling itself, since that still requires someone in the data center, though even that is shrinking as providers increasingly deliver pre-racked capacity ready for remote provisioning.

Does Terraform replace tools like Ironic or MAAS for bare metal provisioning?

No. Terraform is a declarative orchestration layer that calls a bare metal provider's API, and that provider (built on Ironic, MAAS, or its own stack) is what actually performs discovery, PXE boot, and OS installation behind the scenes.

Terraform also doesn't handle post-install configuration on its own, which is why most Terraform-managed bare metal fleets still pair it with Ansible or cloud-init.

How long should automated bare metal provisioning take for one server?

For a pre-racked server with a working BMC connection, a well-built pipeline typically completes hardware discovery, PXE boot, OS installation, and post-install configuration in well under 30 minutes, often closer to 10. Legacy manual provisioning, by comparison, was commonly measured in hours or days once a technician's time was factored in.