Skip to main content

BYOI (Bring Your Own Image)

Create custom VM images with your tools pre-installed for faster CI builds on Harness Cloud.

Prerequisites

  • Harness CI Enterprise license
  • CI_ENABLE_BYOI_HOSTED feature flag enabled (contact Harness support)
  • Harness Cloud infrastructure (not self-hosted runners)

Quick Start

1. Create a Packer File

Add a .pkr.hcl file to your repository with your customizations:

# packer/my-image.pkr.hcl

# Optional: Define variables for reusability
variable "node_version" {
type = string
default = "20"
}

# Install your tools
provisioner "shell" {
inline = [
"sudo apt-get update",
"sudo apt-get install -y nodejs npm python3",
"sudo npm install -g typescript yarn"
]
}

# Copy config files (optional)
provisioner "file" {
source = "configs/settings.json"
destination = "/tmp/settings.json"
}

provisioner "shell" {
inline = ["sudo mv /tmp/settings.json /etc/myapp/"]
}

2. Build the Image

Add this step to your pipeline:

- step:
type: Plugin
name: Build Image
spec:
connectorRef: account.dockerhub
image: harness/byoi-builder:1.0.0
settings:
mode: build
packerFilePath: packer/my-image.pkr.hcl
targetOs: linux
targetArch: amd64
imageName: my-dev-image
imageVersion: v1
baseImage: ubuntu/22.04

3. Use the Image

Reference it in your stage configuration:

- stage:
type: CI
spec:
platform:
os: Linux
arch: Amd64
runtime:
type: Cloud
spec:
imageSpec:
imageName: my-dev-image:v1
execution:
steps:
- step:
type: Run
spec:
command: node --version # Pre-installed!

Plugin Settings

Build Mode

SettingRequiredDefaultDescription
modeNobuildOperation mode: build or delete
packerFilePathYes-Path to your Packer file (relative to repo root)
imageNameYes-Image name (3-30 chars, lowercase letters, numbers, hyphens)
imageVersionYes-Version tag (1-20 chars, alphanumeric and hyphens)
targetOsNolinuxTarget operating system: linux
targetArchNoamd64Target architecture: amd64 or arm64
baseImageNoubuntu/22.04Base image to build from (see Supported Base Images)
dockerVersionNo28Docker version to pre-install (e.g., 28, 27)
debugNofalseEnable verbose Packer logging

Delete Mode

To rebuild with the same version, delete the existing image first:

- step:
type: Plugin
name: Delete Image
spec:
connectorRef: account.dockerhub
image: harness/byoi-builder:1.0.0
settings:
mode: delete
imageName: my-dev-image
imageVersion: v1

Supported Base Images

Linux

Base ImageArchitectures
ubuntu/24.04amd64, arm64
ubuntu/22.04amd64, arm64

Advanced options:

TypeFormatExample
Harness pre-configured{name}ubuntu-v1-hosted-amd64
Your previous BYOI imagebyoi-{sanitizedAccountId}-{imageName}-{version}byoi-abc123-my-base-v1

To use a previous BYOI image, specify the full image name (as shown in build output), not imageName:version.

Note: Account IDs are sanitized in image names: lowercase, _ becomes -, and special characters are removed. For example, if your account ID is My_Account_123, your images are stored as byoi-my-account-123-....


Writing Your Packer File

You provide variables and provisioners. Harness handles source configuration, authentication, and cleanup automatically.

Example with Variables

# Define reusable variables
variable "java_version" {
type = string
default = "17"
}

variable "maven_version" {
type = string
default = "3.9.6"
}

# Install Java
provisioner "shell" {
inline = [
"sudo apt-get update",
"sudo apt-get install -y openjdk-${var.java_version}-jdk"
]
}

# Install Maven
provisioner "shell" {
inline = [
"wget -q https://archive.apache.org/dist/maven/maven-3/${var.maven_version}/binaries/apache-maven-${var.maven_version}-bin.tar.gz",
"sudo tar -xzf apache-maven-${var.maven_version}-bin.tar.gz -C /opt",
"sudo ln -s /opt/apache-maven-${var.maven_version} /opt/maven",
"rm apache-maven-${var.maven_version}-bin.tar.gz"
]
}

Copying Files

# Copy files from your repo into the image
provisioner "file" {
source = "configs/app.conf"
destination = "/tmp/app.conf"
}

provisioner "shell" {
inline = ["sudo mv /tmp/app.conf /etc/myapp/app.conf"]
}

What Harness Adds Automatically

Linux:

  • Git, Git LFS, wget, curl, CA certificates
  • Docker (configurable version)
  • git safe.directory * configuration
  • HOME environment variable
  • Cleanup (apt cache, logs) to reduce image size

What Gets Ignored

If your Packer file contains source or build blocks, they will be ignored. Harness uses its own secure configuration. Only your variable and provisioner blocks are used.


Limitations

Image Naming

  • imageName: 3-30 characters, must start with lowercase letter
  • imageVersion: 1-20 characters, must start/end with alphanumeric
  • Combined length of imageName + imageVersion should not exceed ~35 characters (the full name includes your account ID)

Platform

  • Linux: Ubuntu (amd64 and arm64)
  • Windows: Coming soon
  • macOS: Coming soon
  • Harness Cloud only. Self-hosted runners are not supported.

Build Process

  • Maximum build time: 3 hours (bounded by authentication token lifetime)
  • Automatic retries: 3 attempts on transient failures
  • Disk size: 100GB
  • Cannot build same image name/version concurrently

Security

Do not include credentials in your Packer file. The following patterns will cause the build to fail:

  • credentials = "..."
  • account_file = "..."
  • access_token = "..."

Harness injects credentials securely.


Troubleshooting

IssueSolution
Build failsSet debug: "true" to see detailed Packer output
"Image name too long" errorShorten imageName or imageVersion
"Image already exists" errorUse mode: delete first, or use a different version
Packer file not foundCheck packerFilePath is relative to repo root
Authentication errorContact Harness support
Build times outThe maximum build time is 3 hours.

FAQ

Can I use my image across all projects? Yes, BYOI images are available to all projects in your account.

Can I build on ARM64? Yes, set targetArch: arm64 in your plugin settings (Linux only).

Can I build on top of a previous BYOI image? Yes. Use the full image name from your previous build output as baseImage. For example: baseImage: byoi-abc123-my-base-v1 (not my-base:v1). Note that the account ID in the image name is sanitized (lowercase, _-, special chars removed). You can only use your own account's BYOI images.

Do I need to set mode to build? No, build is the default mode. You only need to explicitly set mode: delete when deleting an image.

What is the maximum build time? 3 hours, bounded by the GCP authentication token lifetime. If your build needs more time, optimize your Packer provisioners.


Support

If you encounter issues:

  1. Enable debug: "true" for verbose logs
  2. Check the error message against the troubleshooting table above
  3. Contact Harness support