How to Build Docker Image with Helm Chart Or VM Image Using Maven and Packer. Part 2 Packer

Eugene Paniot
3 min readSep 6, 2021

--

Part 2. Packer

Packer

Builders are components of Packer that are able to create a machine image for a single platform. Builders read in some configuration and use that to run and generate a machine image. A builder is invoked as part of a build in order to create the actual resulting images. Example builders include GCP, DO, Docker image.

The copy/paste madness

Because we and other teams have bunch of packer.json attributes that are the same cross all build types (Docker or VM Image). Those attributes must be maintained using copy/paste across all projects. This is wrong!

I believe that those attributes should be easily distributed and updated across projects using Maven parent inheritance and Maven dependencies management. See Builds Portability.

That you need it’s just specify:

  1. What Docker Image (Docker from)to use;
  2. How to provision you component.

Example of packer.json for Docker Based component:

{
"builders": [
{
"type": "docker",
"image": "zookeeper:3.6",
"commit": "true",
"pull": "true",
"message": "{{user `description`}}",
"changes": []
}
],
"provisioners": [
{
"type": "ansible",
"playbook_file": "./playbook.yml"
}
]
}

Example packer.json for VM Based component. It doesn’t matter what kind of cloud used — cloud agnostic! (it depends on parent artifactId):

{
"provisioners": [
{
"type": "shell",
"script": "provision.sh"
}
]
}

Maven will automatically add all necessary options.

For Docker based:

{
"builders": [
{
"type": "docker",
"image": "zookeeper:3.6",
"commit": "true",
"pull": "true",
"message": "{{user `description`}}",
"changes": []
}
],
"provisioners": [
{
"type": "ansible",
"playbook_file": "./playbook.yml"
}
],
"variables": {
"group_id": "",
"artifactId": "",
"version": "",
"repository": "",
"gcp_staging_key": ""
},
"sensitive-variables": [
"gcp_staging_key"
],
"post-processors": [
{
"type": "manifest",
"output": "manifest.json",
"strip_path": true,
"custom_data": {
"group_id": "{{user `group_id`}}",
"artifactId": "{{user `artifactId`}}",
"version": "{{user `version`}}",
"tags": "{{user `version`}},unvalidated-{{user `version`}},spinnaker-{{user `version`}}",
"repository": "{{user `repository`}}"
}
},
[
{
"type": "docker-tag",
"repository": "{{user `repository`}}/{{user `artifactId`}}",
"tags": [
"{{user `version`}}",
"unvalidated-{{user `version`}}",
"spinnaker-{{user `version`}}"
]
},
{
"name": "docker-push",
"type": "docker-push"
}
]
]
}

For VM based (GCP for example):

{
"provisioners": [
{
"type": "shell",
"script": "provision.sh"
}
],
"variables": {
"group_id": "",
"artifactId": "",
"version": "",
"description": "",
"gcp_staging_key": "",
"gcp_project_id": "",
"gcp_zone": "",
"gcp_network": "",
"gcp_subnetwork": "",
"gcp_image_name": "",
"gcp_source_image": "",
"gcp_source_image_project_id": ""
},
"sensitive-variables": [
"do_api_token",
"gcp_staging_key"
],
"post-processors": [
{
"type": "manifest",
"output": "manifest.json",
"strip_path": true,
"custom_data": {
"type": "googlecompute",
"group_id": "{{user `group_id`}}",
"artifactId": "{{user `artifactId`}}",
"finalName": "{{user `finalName`}}",
"version": "{{user `version`}}",
"packer_version": "{{user `packer_version`}}",
"project_id": "{{user `gcp_project_id`}}",
"zone": "{{user `gcp_zone`}}",
"network": "{{user `gcp_network`}}",
"subnetwork": "{{user `gcp_subnetwork`}}",
"image_name": "{{user `gcp_image_name`}}",
"image_description": "{{user `description`}}"
}
}
],
"builders": [
{
"type": "googlecompute",
"project_id": "{{user `gcp_project_id`}}",
"zone": "{{user `gcp_zone`}}",
"machine_type": "n1-highcpu-16",
"network": "{{user `gcp_network`}}",
"subnetwork": "{{user `gcp_subnetwork`}}",
"disk_size": "20",
"source_image": "{{user `gcp_source_image`}}",
"source_image_project_id": "{{user `gcp_source_image_project_id`}}",
"image_name": "{{user `gcp_image_name`}}",
"image_description": "{{user `description`}}",
"image_labels": {
"creator": "packer",
"artifactid": "{{user `artifactId`}}",
"version": "{{user `packer_version`}}"
},
"metadata": {
"block-project-ssh-keys": "true"
},
"labels": {
"creator": "packer",
"artifactid": "{{user `artifactId`}}",
"version": "{{user `packer_version`}}"
},
"use_internal_ip": "false",
"ssh_username": "packer",
"scopes": [
"https://www.googleapis.com/auth/monitoring",
"https://www.googleapis.com/auth/cloud-platform.read-only",
"https://www.googleapis.com/auth/logging.write",
"https://www.googleapis.com/auth/userinfo.email",
"https://www.googleapis.com/auth/compute",
"https://www.googleapis.com/auth/devstorage.full_control"
]
}
]
}

Part 3 — https://medium.com/@e.paniot/how-to-build-docker-image-with-helm-chart-or-vm-image-using-maven-and-packer-part-3-helm-chart-1a546178435e

--

--

Eugene Paniot

Engineer with 15 years of experience in SRE and DevOPS, networking, databases, managing cloud and developing automation solutions.