DEV Community

Cover image for Packer Workflows with Jenkins - Setup
lykins
lykins

Posted on • Updated on

Packer Workflows with Jenkins - Setup

Introduction

Probably most folks know both of these products by now, but I've ripped a short intro for both.

And also for a bit of a disclosure. I am by no means an expert in any of this. I run though these out of general curiosity, training, and experience. This should not be followed as a production or development environment guide. This is primarily persona lab setup.

This is going to most likely be a two-parter. This first part will be setting up the require infrastructure. Next will be setting up a Packer template and running a couple of builds.

What I liked about this setup is only Multipass needs setup to launch the instances, but nothing else will need installed or configured on your local system.

HashiCorp Packer

Packer lets you create identical machine images for multiple platforms from a single source configuration. A common use case is creating golden images for organizations to use in cloud infrastructure.

Packer Documentation

Jenkins

Jenkins is a self-contained, open source automation server which can be used to automate all sorts of tasks related to building, testing, and delivering or deploying software.

Jenkins can be installed through native system packages, Docker, or even run standalone by any machine with a Java Runtime Environment (JRE) installed.

What is Jenkins?

Objectives

I have honestly not used Jenkins that much, but it is a heavily used CI/CD solution. There are many more options out there - some much more modern solutions - Jenkins still is very prevalent and will most likely be here to stay for some time.

For this the objects are:

  1. Use Multipass to create two instances.
    1. Jenkins
    2. Packer
  2. Set up Jenkins.
  3. Set up Packer instance as a worker node. Agent will only run for Packer jobs.

Prerequisites

  • Knowledge of Jenkins and Packer.
  • Multipass
    • I love Multipass for quick Ubuntu instances spun up for testing or as a playground. Wish I would have known and used of it sooner.

Instance Setup

Following sections will walk through the necessary setup.

Using Multipass create two virtual machines.

╰─ multipass version                               
multipass   1.13.1+mac
multipassd  1.13.1+mac
Enter fullscreen mode Exit fullscreen mode

Launch Jenkins-Server

multipass launch -n jenkins-server

Launch Jenkins-Packer Server

multipass launch -n jenkins-packer

Run multipass list to see instances.

multipass list                                     
Name                    State             IPv4
jenkins-packer          Running      192.168.64.9
jenkins-server          Running      192.168.64.8
Enter fullscreen mode Exit fullscreen mode

And there we go, we have two instances set up for testing. Multipass is great for this since it can easily spin up and down instances for testing.

These were set up with the default Ubuntu image and configuration settings, there is much more which can be done with Multipass, so check out their documentation.

Jenkins

First step will be to connect to the instance you will run Jenkins on.

multipass shell jenkins-server

Ubuntu version

Once on the server, I will run through the setup necessary for Jenkins.

Note: I will be using root permissions to simplify steps.

Install Jenkins

For full install instructions, please see the following documentation:

Installing Jenkins - Ubuntu

sudo wget -O /usr/share/keyrings/jenkins-keyring.asc \
  https://pkg.jenkins.io/debian-stable/jenkins.io-2023.key
echo deb [signed-by=/usr/share/keyrings/jenkins-keyring.asc] \
  https://pkg.jenkins.io/debian-stable binary/ | sudo tee \
  /etc/apt/sources.list.d/jenkins.list > /dev/null
sudo apt-get update
sudo apt-get install jenkins
Enter fullscreen mode Exit fullscreen mode

Error due to not having Java on the instance, this will get corrected:

Job for jenkins.service failed because the control process exited with error code.
Enter fullscreen mode Exit fullscreen mode

Run the following to setup openjdk:

snap install openjdk

openjdk 21.0.3+3 from John Neffenger (jgneff) installed
Enter fullscreen mode Exit fullscreen mode

Run the following three commands to start up Jenkins :

sudo systemctl enable jenkins
Enter fullscreen mode Exit fullscreen mode
sudo systemctl start jenkins
Enter fullscreen mode Exit fullscreen mode
sudo systemctl status jenkins
Enter fullscreen mode Exit fullscreen mode

Should get a confirmation when running status command.

root@jenkins-server:~# sudo systemctl status jenkins
● jenkins.service - Jenkins Continuous Integration Server
     Loaded: loaded (/lib/systemd/system/jenkins.service; enabled; vendor preset: enabled)
     Active: active (running) since Wed 2024-02-21 12:31:36 EST; 1s ago
   Main PID: 7306 (java)
      Tasks: 40 (limit: 1069)
     Memory: 367.2M
        CPU: 9.747s
     CGroup: /system.slice/jenkins.service
             └─7306 /usr/bin/java -Djava.awt.headless=true -jar /usr/share/java/jenkins.war --webroot=/var/cache/jenkins/war --httpPort=8080
Enter fullscreen mode Exit fullscreen mode

Jenkins - Firewall

Needing to open up the firewall on this host to ensure communication from my personal laptop and the packer instance.

Installing

apt install firewalld
Enter fullscreen mode Exit fullscreen mode

Once installed, run the following commands:

Note: For testing I'm going to have port 50000 open for the agent to connect back to the Jenkins controller

YOURPORT=8080
PERM="--permanent"
SERV="$PERM --service=jenkins"

firewall-cmd $PERM --new-service=jenkins
firewall-cmd $SERV --set-short="Jenkins ports"
firewall-cmd $SERV --set-description="Jenkins port exceptions"
firewall-cmd $SERV --add-port=$YOURPORT/tcp
firewall-cmd $SERV --add-port=50000/tcp
firewall-cmd $PERM --add-service=jenkins
firewall-cmd --zone=public --add-service=http --permanent
firewall-cmd --reload
Enter fullscreen mode Exit fullscreen mode

Most likely will get some warnings, but to verify, I will connect from my laptop to the host. If done correctly, you should see the following:

Jenkins Initial Setup

For Jenkins configuration, I will run through the defaults, without any major changes.

Once set up is complete, you have a clean slate to work with.

Jenkins dashboard


Packer Node

Before jumping onto the instance we set up for Packer, I we need to stay on the Jenkins console for a little bit more.

Node Setup

For more detailed instructions and terminology on distributed nodes, see the documentation.

I'll keep this relatively light for prep.

  1. Install java.
  2. Create the following directory /home/packer/agent.

Agent Setup - Jenkins Side

Back in the Jenkins UI, go to manage Jenkins and select nodes:

manage jenkins

Create a new node:

Packer Node

Configure node:

Configuration-1

continued...

Configuration continued

Once configured, select status for the node.

Node Status

Grab the commands and we will use them when we are back on the node.

CLI command

One last stop, go back to manage Jenkins and go to security.

In security, make the following updates to enable agent connectivity. Using port 50000, as it is the static port I opened up on the firewall.

Agent networking

Agent Setup - Packer Instance

Make sure you still have the command you copied earlier, we will use it here.

Change directory to - /home/packer/agent

Run the first command to download the agent. Port 8080 should be open to connect to the Jenkins instance.

root@jenkins-packer:/home/packer/agent# curl -sO http://192.168.64.8:8080/jnlpJars/agent.jar
root@jenkins-packer:/home/packer/agent# ls
agent.jar  remoting
Enter fullscreen mode Exit fullscreen mode

Run the second command to start the Jenkins agent. In the info, you should see that port 50000 is in use for the connection. I cleared out most of the message and focusing on the connection information.

root@jenkins-packer:/home/packer/agent# java -jar agent.jar -url http://192.168.64.8:8080/ -secret 322747aa59050708e4af27206812443a9556c25ca45b0456ea70799e20f7db23 -name packer -workDir "/home/packer/agent"
...
INFO: Agent discovery successful
  Agent address: 192.168.64.8
  Agent port:    50000
  Identity:      1f:dc:34:23:1b:e1:84:6f:9c:34:72:c7:d1:5f:c2:74
...
Enter fullscreen mode Exit fullscreen mode

If going back to the UI, you can see the Packer agent is now connected. This agent will drop out when no communication is occurring and will come back up when a job is started.

Image description

Note: Agent can be run as a service or in a Docker container. For this setup I'm keeping it simple, but both of those are options.


First Job

Now that we have both a Jenkins node and a Packer node with an agent, we will set up our first job.

Dashboard-create job

Select create a job and select pipeline as the type.

selecting job type

After hitting OK, I am going to do a quick hello world to confirm connectivity with the node. Here is a sample that Jenkins provides. I do update to use the packer agent and node:

pipeline {
    agent {
  label 'packer'
}
    stages {
        stage('Hello') {
            steps {
                echo 'Hello World'
            }
        }
    }
}
Enter fullscreen mode Exit fullscreen mode

From the console output :

Started by user [lykins](http://192.168.64.8:8080/user/lykins)
[Pipeline] Start of Pipeline[](http://192.168.64.8:8080/job/packer/2/console#)
[Pipeline] node[](http://192.168.64.8:8080/job/packer/2/console#)
Running on [packer](http://192.168.64.8:8080/computer/packer/) in /home/packer/agent/workspace/packer
[Pipeline] {[](http://192.168.64.8:8080/job/packer/2/console#)
[Pipeline] stage[](http://192.168.64.8:8080/job/packer/2/console#)
[Pipeline] { (Hello)[](http://192.168.64.8:8080/job/packer/2/console#)
[Pipeline] echo[](http://192.168.64.8:8080/job/packer/2/console#)
Hello World
[Pipeline] }
[Pipeline] // stage
[Pipeline] }
[Pipeline] // node
[Pipeline] End of Pipeline
Finished: SUCCESS
Enter fullscreen mode Exit fullscreen mode

At this point, we are done with setting up the worker node with the agent. Other options would be running it in docker or as a service, but doing a simple setup for now.

Top comments (0)