Announcing the Packer Plugin for Artifactory
Today marks the v0.1.0 release of the Packer Plugin for Artifactory, my first standalone Packer plugin. This one's been on the list for a while.
The plugin adds an artifactory post-processor. After a Packer build produces an OVA or OVF, the post-processor uploads it straight to JFrog Artifactory. Build, export, upload, done. No handoff step, no separate script, no copy-pasting artifact paths into another job.
Primary targets are the vmware/vsphere and vmware/vmware Packer plugins, covering vSphere, Fusion, and Workstation. Any other builder that emits OVA or OVF should work too. Authentication supports username and password, API key, and access token. Custom properties let teams attach version, OS, and build metadata right from the post-processor block.
Install¶
Add the plugin to your Packer block, then initialize:
packer {
required_plugins {
artifactory = {
source = "github.com/tenthirtyam/artifactory"
version = ">= 0.1.0"
}
}
}
Or install a specific version directly:
packer plugins install github.com/tenthirtyam/[email protected]
Supported Platforms and Artifacts¶
The plugin is tested against the VMware by Broadcom ecosystem. Other builders that emit OVA or OVF may work, though support outside the list below is best-effort:
| Platform | Type | Support |
|---|---|---|
| VMware vSphere | Bare Metal Hypervisor | Supported |
| VMware Fusion | Desktop Hypervisor (macOS) | Supported |
| VMware Workstation | Desktop Hypervisor (Windows/Linux) | Supported |
| Other | Various | Best Effort |
Both OVA and OVF are supported:
| Format | What It Is |
|---|---|
.ova | Single archive with the OVF descriptor and disk files packaged together |
.ovf | OVF descriptor plus companion files such as .mf, .vmdk, and related |
For OVF uploads, the plugin includes the default companion extensions (.ovf, .mf, .vmdk, .cert, .vdi). Use additional_ovf_extensions when you need extras such as .nvram.
Configuration¶
The post-processor needs to know where to send the artifact and how to authenticate. Beyond that, everything is optional. Pick one authentication method and leave the others out.
| Option | Required | Purpose |
|---|---|---|
url | Yes | Base URL of the Artifactory instance |
repository | Yes | Repository to upload into |
artifact_name | Yes | Name of the artifact being uploaded |
username / password | No | Basic authentication credentials |
api_key | No | API key authentication |
access_token | No | Access token authentication |
artifact_path | No | Path inside the repository |
properties | No | Custom properties attached to uploaded artifacts |
artifact_path_properties | No | Also apply properties to the artifact path when supported |
overwrite | No | Replace an existing artifact (false by default) |
max_retries | No | Retry failed uploads (default 3) |
timeout_seconds | No | Request timeout in seconds (default 30) |
additional_ovf_extensions | No | Extra companion extensions for OVF uploads |
Credentials can come from HCL variables or environment variables. For environment variables, use ARTIFACTORY_URL, ARTIFACTORY_USERNAME, ARTIFACTORY_PASSWORD, ARTIFACTORY_REPOSITORY, ARTIFACTORY_API_KEY, or ARTIFACTORY_TOKEN.
Example Usage¶
Each example below wires both vmware-iso and vsphere-iso sources, then uploads with artifactory. Full end-to-end templates with variables and source definitions are in the examples/ directory.
build {
sources = [
"source.vmware-iso.example",
"source.vsphere-iso.example",
]
provisioner "shell" {
inline = [
"sudo apt-get update",
"sudo apt-get install -y open-vm-tools"
]
}
post-processor "artifactory" {
url = var.artifactory_url
username = var.artifactory_username
password = var.artifactory_password
repository = var.artifactory_repository
artifact_name = local.artifact_name
artifact_path = local.artifact_path
}
}
build {
sources = [
"source.vmware-iso.example",
"source.vsphere-iso.example",
]
provisioner "shell" {
inline = [
"sudo apt-get update",
"sudo apt-get install -y open-vm-tools"
]
}
post-processor "artifactory" {
url = var.artifactory_url
username = var.artifactory_username
password = var.artifactory_password
repository = var.artifactory_repository
artifact_name = local.artifact_name
artifact_path = local.artifact_path
artifact_path_properties = true
properties = {
"version.number" = "1.0.0"
"build.number" = "12345678"
"release.channel" = "stable"
"os.family" = "linux"
"os.vendor" = "debian"
"os.version" = local.guest_version
"os.arch" = local.guest_arch
}
}
}
build {
sources = [
"source.vmware-iso.example",
"source.vsphere-iso.example",
]
provisioner "shell" {
inline = [
"sudo apt-get update",
"sudo apt-get install -y open-vm-tools"
]
}
post-processor "artifactory" {
url = var.artifactory_url
api_key = var.artifactory_api_key
repository = var.artifactory_repository
artifact_name = local.artifact_name
artifact_path = local.artifact_path
overwrite = true
max_retries = 5
timeout_seconds = 60
}
}
build {
sources = [
"source.vmware-iso.example",
"source.vsphere-iso.example",
]
provisioner "shell" {
inline = [
"sudo apt-get update",
"sudo apt-get install -y open-vm-tools"
]
}
post-processor "artifactory" {
url = var.artifactory_url
access_token = var.artifactory_token
repository = var.artifactory_repository
artifact_name = local.artifact_name
artifact_path = local.artifact_path
overwrite = true
max_retries = 5
timeout_seconds = 60
}
}
If something doesn't work the way you expect, open a discussion or file an issue in the repository.