Create Jenkins AMI using Packer and Ansible Playbook.

Tafari BeckfordTafari Beckford
3 min read

In this article, you will learn how to create a Jenkins AMI using Hashicorp Packer and Ansible Playbook.

What is Packer?

Packer is an open-source tool for creating identical machine images for multiple platforms from a single source configuration. Packer is lightweight, runs on every major operating system, and is highly performant, creating machine images for multiple platforms in parallel.

What is Ansible?

Ansible is an open-source automation tool designed for IT infrastructure provisioning, configuration management, and application deployment. It allows you to automate repetitive tasks, orchestrate complex workflows, and manage infrastructure as code.

At its core, Ansible uses a simple and human-readable language called YAML (Yet Another Markup Language) to define automation tasks and configuration files. These files, called "playbooks," describe the desired state of a system and the steps needed to achieve that state.

Prerequisites:

  • AWS Account

  • Packer

Ansible

Notes:

  • I will be using the default VPC in my AWS Account. If you're using a custom VPC configure it accordingly to ensure your network is correct.

  • Red Hat Enterprise Linux (RHEL) will be used as the source AMI for Packer.

  • The code for the project can be found on my Github.

AWS

Create Security Group

Create the Jenkins Security Group with the following inbound rules:

  • Type: HTTP
    Port range: 8080
    Source: My IP

  • Type: SSH
    Port range: 22
    Source: My IP

Ansible

Create playbook in a folder named "ansible"

This playbook sets up the Jenkins repository, installs OpenJDK 11 JRE, and installs Jenkins on the specified hosts using the yum package manager

  1. jenkins-playbook.yaml
---
- name: Install Jenkins
  hosts: all
  become: true

  tasks:
    - name: Add Jenkins repository
      yum_repository:
        name: jenkins
        description: Jenkins Repository
        baseurl: https://pkg.jenkins.io/redhat-stable
        gpgcheck: yes
        gpgkey: https://pkg.jenkins.io/redhat-stable/jenkins.io-2023.key
        enabled: yes

    - name: Download Jenkins repository key
      get_url:
        url: https://pkg.jenkins.io/redhat-stable/jenkins.io-2023.key
        dest: /etc/pki/rpm-gpg/jenkins.io-2023.key


    - name: Install OpenJDK 11 JRE
      ansible.builtin.yum:
        name: 
         - fontconfig 
         - java-11-openjdk-devel
        state: present
        update_cache: yes

    - name: Install Jenkins
      ansible.builtin.yum:
        name: jenkins
        state: latest
        update_cache: yes

Bash Script

Create a scripts directory with the following jenkins-start.sh script:

#!/bin/bash
sudo systemctl enable jenkins
sudo systemctl start jenkins

Packer

Create packer files in a packer directory

  1. variables.pkr.hcl
variable "ami_name" {
  default = "Jenkins-AMI"
}

variable "source_ami" {
  default = "ami-026ebd4cfe2c043b2"
}

variable "instance_type" {
  default = "t3.medium"
}

variable "region" {
  default = "us-east-1"
}

variable "ssh_username" {
  default = "ec2-user"
}

variable "security_group_id" {
  default = "sg-0022ddab3a95e94fc"
}
  1. jenkins.pkr.hcl
source "amazon-ebs" "jenkins" {
  ami_name          = var.ami_name
  instance_type     = var.instance_type
  region            = var.region
  source_ami        = var.source_ami
  ssh_username      = var.ssh_username
  security_group_id = var.security_group_id

  tags = {
    "Name" = "Jenkins-Ansible"
  }
}

build {

  sources = ["source.amazon-ebs.jenkins"]

  provisioner "ansible" {

    playbook_file = "../playbook/jenkins-playbook.yaml"

  }

  provisioner "file" {
    source = "../scripts/jenkins-start.sh"

    destination = "/tmp/jenkins-start.sh"

  }

  provisioner "shell" {

    inline = [
      "sudo chmod +x /tmp/jenkins-start.sh",
      "sudo mv /tmp/jenkins-start.sh   /var/lib/cloud/scripts/per-instance/",
    ]

  }

  post-processor "manifest" {}

}

The file provisioner uploads files to machines built by Packer. The recommended usage of the file provisioner is to use it to upload files, and then use the shell provisioner to move them to the proper place, set permissions, etc.

The script is then made executable followed by placing them in the directories under /var/lib/cloud/scripts/per-instance. Scripts within this directory are run when a new instance is first booted.

  1. Validate Packer files using the command packer validate . with validates both files simultaneously.

  2. Create AMI using the command packer build .

The image below shows the ongoing build process:

Completion

Upon completion of the build process, your AMI will be stored in your AWS account along with a snapshot.

Congrats you have created a Jenkins AMI !!!!!!!!

0
Subscribe to my newsletter

Read articles from Tafari Beckford directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Tafari Beckford
Tafari Beckford