Let’s Build an image pipeline! (part 2)

Share on:

Sorry for the delay in getting part two published, life had been busy the past week or so.  Today we are going to build upon what we covered in part one, namely the pieces of the code and/or things you need to adapt about the packer template file for it to be functional for your environment.

This is the second post of a planned 4 part series:

In case you missed it in part one, I have created a working packer build for use as a template.  You can find the template project in GitHub.  As we did in part 1, you’ll want to reference the BlogSample1 tag.  I’ll be walking through this customization in the order things are processed by packer during the build process.


This json file is the main file that packer parses to build this specific template, since we are saving the deep dive for part three, let’s head straight to the edits.  Scroll down to line 130, and you will find the block of code listed below.

      "type": "ansible-local",
      "playbook_file": "ansible/configure_template.yml",
      "role_paths": [

This block of code instructs packer to use ansible, installed inside of the template machine, to run a playbook containing a number of roles.  You’ll want to rename the add_sentania_certs to something that describes your RootCA.  If you don’t have PKI, simply delete the call to that role.  We will deal with update or deletion of that role later.  Remember, one file at a time.

The install-labansiblekey role, installs a public key to the labansible user account for password less login post image deploy.  Rename the call to this role as you see fit.

If you will be using public repositories and will not be referencing RHSM/Katello, delete line 103 – which is a call to scripts/satellite_reg.sh.  It is a simple bash script that will register the template image to a RHSM/Katello instance for installation of patches from a local repo.


This file is a variable definition file for packer, pretty much the whole file needs editing!

    "os_version": "7.4",
    "image_build_version": "0.2",
    "satellite_activation_key_centos":"CentOS 7",
    "centos_nexus_url": "https://nexus.int.sentania.net/repository/labRepo/lab/isos/Linux/CentOS/7/CentOS-7-x86_64-Everything-1708.iso"

In no particular order you need to:

  • change the references to labansible
  • If you are using RHSM/Katello, update the four lines that begin with satellite to what is appropriate for your environment
  • The two lines containing nexus_url should be updated to reflect a web location that will be accessible to packer to download installer isos
  • Verify the checksum values (sha256)


This file will likely need a lot of editing.  This is the kickstart file that performs the install.  While there are a lot of things you could tweak in this, you will want to make the following changes at minimum:

  • Line 5: Update the hostname to meed your needs
  • Jump to line 59 and make the changes to the bootstrap account that reflect your previous choices
# Add a user so packer can connect to the image
/usr/sbin/groupadd labansible
/usr/sbin/useradd labansible -g labansible -G wheel
echo "labansible"|passwd --stdin labansible
echo "labansible        ALL=(ALL)       NOPASSWD: ALL" >> /etc/sudoers.d/packer
chmod 0440 /etc/sudoers.d/labansible
sed -i "s/^.*requiretty/#Defaults requiretty/" /etc/sudoers


This file needs updates to reflect the changes you made to enterprise_linux.json, related to your PKI environment and what you want to local bootstrap user to be named.


Delete this role, or update it for your environment.  If you update it you need to make these changes:

  • Edit tasks/main.yml and replace sentaniaRoot.crt with the name of your RootCA cert
  • Delete files/sentaniaRoot.crt and replace it with your own


Edit the files/chrony.conf file to reflect your NTP needs


Delete or rename the role based on your previous choices for the bootstrap account.  If you are keeping the role, you will need to edit the tasks/main.yml file, place your public key, and edit the user name.

- name: Install the packer ssh public key
    user: labansible
    state: present
    exclusive: yes
    key: "ssh-rsa AAAAB3NzaC1yc2EAAAABJQAAAQEAwRaRdO3iR9aMFA99uFV7r55lwZoaceL8eZx+V1Gm/GsLTSx6Cse/ZSiiQ7jHIAGQ6q/p4jXuHGcqliHjCkCmL4c2lx01Hl3GSQPrhUpMsKKMbNatBMr74e1XLzCIKv4H4lTvrGNe6hdXQUsk0gmb6Odx8j3qssX2xllWoLZ71SApZe6usCsI7ydgrb2oLbgDxjdyH1TZ2PDqipJiwg4Gvo7ztZ/Xjr7tgsuGIhmDLaOM4MZJzocshbzXvPp5FwJ6Jd+/BQ2HvaOzWtHxqkwgqyysxRTJpc3cufM2UM1J7Rw34VnfqZzJC+9AMIs5DnyaXPA8w3wMMBk6Uo4srRdKcQ== rsa-key-20180309"


#Upload to Lab vCenter
$vCenterServerList = "vcenter.int.sentania.net"
$datastore = "ntx-iso"
$targetCluster = "ntnxlab"

You’ll want to update these lines to reflect the vSphere environment you want to upload this too.

$ovfConfig = Get-OvfConfiguration $image.fullname
$vdPortGroup = Get-VDPortgroup -Server $viConnection "VM Network"
$ovfConfig.NetworkMapping.nat.Value = $vdPortGroup

You need to update line 65 to reference a portgroup that exists in your vSphere environment.  It’s important that this portgroup exist in all clusters, as this script will deploy a copy of this template to every cluster in the vCenter you connect to.


if (env.BRANCH_NAME == 'master' || env.BRANCH_NAME == 'Development') {
      withCredentials([usernamePassword(credentialsId: 'c574ec56-5665-4bb6-84f1-98d8316ba488',
        usernameVariable: 'nexusUSERNAME', passwordVariable: 'nexusPASSWORD'),
        usernamePassword(credentialsId: '75124b79-b775-4189-9025-0f37b756e83d',
        usernameVariable: 'vSphereUSERNAME', passwordVariable: 'vSpherePASSWORD')
 stage ('Upload Image(s) to Nexus')
 //sh 'curl -k -v -u $nexusUSERNAME:$nexusPASSWORD --upload-file $IMAGE_OUTPUT_DIR/output-vmware-iso-rhel/RHEL-7-4.ova https://nexus.int.sentania.net/repository/labRepo/lab/enterpriseLinux/RHEL-7-4-$BUILD_TAG.ova'
 sh 'curl -k -v -u $nexusUSERNAME:$nexusPASSWORD --upload-file $IMAGE_OUTPUT_DIR/output-vmware-iso-centos/CentOS-7-4.ova https://nexus.int.sentania.net/repository/labRepo/lab/images/enterpriseLinux/CentOS-7-4-$BUILD_TAG.ova'

The Jenkinsfile will need updates based on the Jenkins Credentials created in part 1.5.

Update the references to nexus.int.sentania.net to whatever web postable repository you want the images uploaded to, or remove that upload all together.

There are also a number of references to building a RHEL image, but they are commented out.  If you want to build a RHEL image, simply uncomment those, and delete -only=CentOS from line 14.

Please note, that this pipeline will only deploy the image if it is building the master branch, or a branch named development.

Other changes

While not required, you may want to edit or update the install_packages or cleanup roles if you have needs that I’m not accounting for.

One thing that you may notice is that we aren’t doing a lot at this point to harden the image.  The reference kickstart file installs to a STIG compliant partitioning scheme, assuming I have read the docs correctly, but nothing else.  Don’t worry about that for now, we will be covering that in part 4 of this guide.

Thanks for reading and please feel free to comment or provide feedback.