Skip to content

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"
    }
  }
}
packer init -upgrade .

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.

References