Image Building¶
As an Operator, you will want to build images for your image deploy process. DRP's image-deploy workflow boots a machine, streams a pre-built OS image onto the disk, and brings the machine up without running a traditional installer. This requires a pre-built image. DRP supports two paths for building these images: Packer-based image building and the DRP image-builder tooling.
Packer-Based Image Building¶
Packer is the recommended approach for building DRP-compatible OS images. Packer automates the process of booting a temporary VM, running a traditional OS installer inside it, applying configuration (packages, services, hardening), and exporting the resulting disk image.
The typical Packer workflow for DRP images:
- Packer boots a VM in a hypervisor (KVM/QEMU, VMware, AWS, etc.) using a vendor ISO
- Packer uses a kickstart/preseed/cloud-init file to automate the OS install
- Post-install provisioners (shell scripts, Ansible) configure the OS to DRP standards:
- Install and configure the DRP runner agent
- Set up cloud-init or equivalent for first-boot customization
- Remove machine-specific state (SSH host keys, hostname, machine-id)
- Packer exports the disk as a compressed image file (typically
.img.gzor.tar.gz) - The image is uploaded to the DRP provisioner file store or an S3 bucket
# Upload a built image to DRP
drpcli files upload ubuntu-22.04-drp.img.gz as files/images/ubuntu-22.04-drp.img.gz
The image-deploy bootenv and workflow then reference this image by URL, stream it to the target machine's disk during provisioning, and perform first-boot configuration via parameters and templates. See CentOS Image Build & Deployment Guide for the image-deploy workflow configuration.
DRP Image-Builder Tooling¶
RackN provides an image-builder content pack that automates the image build pipeline within DRP
itself. Rather than requiring an external Packer setup, image-builder uses DRP workflows to:
- Provision a temporary build machine using a standard DRP OS install workflow
- Apply post-install configuration tasks to produce the desired image content
- Export the disk state as a compressed image using DRP tasks
- Upload the resulting image back to the DRP file store
- Decommission the temporary build machine
This approach integrates image building into the standard DRP operational model, using the same parameters and profiles that configure production machines to configure the image. Changes to the base configuration are made in DRP profiles, and the next image build automatically picks them up.
What a Built Image Contains¶
A DRP-compatible image is a raw disk image (or partition image) that contains:
- A fully installed and configured OS
- A top-level
/curtindirectory with appropriate permissions (see The /curtin Directory) - First-boot configuration hooks (cloud-init, systemd units, or DRP-specific scripts) that apply machine-specific settings from DRP parameters (hostname, network configuration, SSH keys)
- No machine-specific state: SSH host keys,
/etc/machine-id, and similar per-machine files are absent or reset so they regenerate on first boot
The image is consumed by the image-deploy workflow, which streams the image to the machine's disk
using dd or a similar tool during a Sledgehammer-based deployment stage.
The /curtin Directory¶
Every image that image-deploy consumes must contain a top-level /curtin directory. It has to be baked
into the raw disk image or included in the rootfs tarball — the deploy does not create it for you.
image-deploy uses /curtin as scratch space during deployment. It writes the curtin hooks, the join-up
bootstrap script (drpcli-install.sh or drpcli-install.bat), and — when
image-deploy/cloud-init-base-url is left at its file:///curtin/ default — the cloud-init meta-data
and user-data files into it. meta-data carries the values of image-deploy/admin-username,
image-deploy/admin-password, and access-keys, so its contents are sensitive on every OS. That makes
the permissions on /curtin part of the image's security posture.
Permissions Are the Image Builder's Responsibility¶
image-deploy writes /curtin from the Linux deployment OS, so the permissions it can apply are limited
to what the target filesystem understands.
Linux and ESXi images: the deploy sets /curtin to mode 0700 owned by root. Nothing further is
required of the image.
Windows images: the deploy writes to NTFS from Linux. POSIX mode bits do not become NTFS ACLs there,
so the chmod is a no-op and image-deploy cannot restrict C:\curtin. A C:\curtin that the image did
not create inherits the ACL of the volume root, which grants BUILTIN\Users read access.
Warning
If you build Windows images for image-deploy, you must create C:\curtin and set its ACL as part of
the image build. image-deploy cannot do it for you.
Create the directory in your Packer build (or whatever tooling produces the image), break inheritance,
and grant only SYSTEM and Administrators:
New-Item -ItemType Directory -Path C:\curtin -Force | Out-Null
icacls C:\curtin /inheritance:r
icacls C:\curtin /grant 'NT AUTHORITY\SYSTEM:(OI)(CI)F' 'BUILTIN\Administrators:(OI)(CI)F'
Confirm the result before capturing the image:
What the ACL Does and Does Not Protect¶
A restrictive ACL on C:\curtin stops ordinary users from listing the directory. On its own it does not
protect the contents:
- Windows grants the Bypass traverse checking user right to
Everyoneby default, so a user who already knows a file name can open that file directly if the file's own ACL allows it. - Files written to NTFS from the Linux deployment OS do not pick up the parent directory's ACL.
Treat the directory ACL as defense in depth. The control that removes the exposure is that /curtin does
not survive: no machine token is written into it, and once the DRP agent has joined, the
image-deploy-cleanup task deletes C:\curtin entirely.
If you set image-deploy/cleanup-curtin to false — or point custom cloud-init/user-data or unattend
content at /curtin for later boots — you are choosing to keep the directory on the deployed system. Then
re-apply the ACL from inside Windows on first boot, where NTFS permissions actually take effect. A
SetupComplete.cmd, an unattend FirstLogonCommands entry, or a cloud-init runcmd running the icacls
lines above all work.
See Image Deploy for the full image-deploy content pack reference.