Skip to main content

2 posts tagged with "OOP"

View All Tags

Exploring an Object-Oriented Jenkins Pipeline for Terraform:A novel architecture design in Jenkin's multi-stage Terraform CD pipeline to improve CI/CD granularity

· 3 min read

Usually, when we perform terraform plan, terraform destroy, or terraform apply, we apply these actions to all the resources in our target files, often main.tf (you can use any name for the file, but this name is just used as a convention).

In the age of CI/CD, when we have everything as pipelines right from data, and application code to infrastructure code, it is usually difficult to this granularity. Usually, at least in Terraform, to achieve these three different actions, we have three different pipelines to perform terraform plan: terraform apply and terraform destroy. And when we select a certain action (let's say terraform plan), this action is performed on all the stages and on all resources within the pipeline.

But when we observe all these pipelines, there is a commonality that can be abstracted out to create a generality, on which the dynamic nature can be inherited. Just as we create a class, using different objects with different attribute values can be built, is it possible to create a similar base class (read pipelines) which when instantiated can create different pipeline objects?

###One Pipeline to create them all###

##The Modular Infrastructure

In order to build this class-based pipeline, we first need to create a terraform script. This script developed should be loosely coupled and should be modular in nature. For this, we have created this modular script, which has three modules named “Networking,” “Compute,” and “Notifications.” The components that each of these modules create is as follows:

  1. Networking: 1 VPC and 1 subnet
  2. Compute : 1 IAM role, 1 Lambda, 1 EC2 t2.micro instance
  3. Notifications: 1 SNS topic and 1 email subscription

And the file structure is as follows:

Once we have this ready, let’s create a groovy script in declarative style in a Jenkins file.

Class-Based Jenkins Pipeline

To create this class-based architecture style to flexibly create pipeline objects at the action and resource level, we are going to utilize a feature called “parameters” in Jenkins. This feature helps us create multiple objects using a single base class Jenkins pipeline. In this example, let’s create three actions namely:

  • terraform plan: This creates and prints out a plan of the resources that we are going to create in the respective provider ( can be AWS, Kubernetes, GCP, Azure, etc.)
  • terraform apply: This command creates the resources in the respective provider and creates a state-file that saves the current state of resources in it.
  • terraform destroy: This removes all the resources that are listed within the state-file.

These actions are performed on three modules/resources namely “Networking,” “Compute,” and “Notifications.”

The above parameters create a UI for the end user, as shown below, which would help the end user to create objects of the base pipeline on the fly.

Based on the actions selected and the resources on which these actions have to be done, Jenkins will create a dynamic pipeline according to your requirement. In the picture below, we see that we have applied terraform for the networking and compute resources in #24, and run terraform apply on networking and notification in run #25. To clean the infrastructure, we ran terraform destroy on run #26.

The present approach implemented is more in line with Continuous delivery principles than continuous deployment.

For the Jenkins file and Terraform code, refer to this link.

**Want to Connect?**Feel free to reach out to my [LinkedIn](https://www.linkedin.com/in/krishnadutt/) for interesting content and productive discussions.

From Scratch to Brew: Creating Personalized Formulae using tfblueprintgen in Homebrew

· 4 min read

Homebrew has become defacto way to get and install the open source apps in the apple ecosystem. While homebrew has a vast repository of the appplications that it supports, it is sometimes required to create and publish our own packages to be installed be consumed by other people. In this blog, we are going to discuss how we can create the custom brew package for an app named tfblueprintgen, how do we test it and how can we install it as a homebrew package. The blog will be divided into following sections:

  • Understanding tfblueprintgen
  • Setting up the development environment
  • Creating and Testing Homebrew formula
  • Testing it locally
  • Pushing it to up stream and installing it from the upstream repos.

Understanding tfblueprintgen

Tfblueprintgen is an open-source command-line tool developed using the Charmbracelet CLI assets. It generates a modular file structure with code for your Terraform projects, speeding up the development process. By automating the creation of boilerplate files and directory structures, Tfblueprintgen streamlines setting new Terraform projects. To learn more about the project , refer this.

Setting up the development environment

Once you have your application up in the github environment, package your application for release by pushing it .

Once the release is complete we can see our application is avaliable in compressed format such as .tar.gz or .zip.

First lets setup our dev environment:

  • Set HOMEBREW_NO_INSTALL_FROM_API=1 in your shell environment,
  • Run brew tap homebrew/core and wait for the clone to complete. If clone fails run the following commands before running the brew tap homebrew/core again.
git config --global core.compression 0
git clone --depth 1 <https://github.com/Homebrew/homebrew-core.git>
git fetch --depth=2147483647
git pull --all

One this is done we are good to create the homebrew formula

Creating and Testing Homebrew formula

To create the boilerplate homebrew formula run “brew create <url of .tar.gz>” in my case it is

brew create <https://github.com/krishnaduttPanchagnula/tfblueprintgen/archive/refs/tags/0.3.tar.gz>

Running the above command opens a file to edit in vim. This formula file contains following:

  • desc provides a brief description of the package.
  • homepage is left blank in this case.
  • url specifies the download URL for the package source code.
  • sha256 is the SHA-256 checksum of the package, which Home-brew uses to verify the integrity of the downloaded zip.
  • license declares the software license for the package.
  • depends_on specifies the dependencies that current formula depends on.
  • install contains the instructions for building and installing the package.
  • test defines a test to ensure that the package was installed correctly by checking the version output.

Make changes to the install and test function so it reflects the installation and testing for your application. In my case i have made changes as follows:

class Tfblueprintgen < Formula
desc "This contains the formula for installing tfblueprintgen. tfblueprintgen cli utility developed using charmbracelet CLI assets, which generates the Modular file structure with the code for your Terraform code to speed up the development."
homepage ""
url "<https://github.com/krishnaduttPanchagnula/tfblueprintgen/archive/refs/tags/0.3.tar.gz>"
sha256 "0ef05a67fa416691c849bd61d312bfd2e2194aadb14d9ac39ea2716ce6a834a6"
license "MIT"
depends\_on "go" => :build
def install
puts \`ls\`
# system ("cd tfblueprintgen-0.2")
system ("go build -o tfblueprintgen main.go ")
bin.install "tfblueprintgen"
end
test do
system "#{bin}/tfblueprintgen --version"
expected\_version = "Tfblueprintgen version: 0.3"
actual\_version = shell\_output("#{bin}/tfblueprintgen --version").strip
assert\_match expected\_version, actual\_version
end
end

Once the formula is defined, install the formula using following command

brew install tfblueprintgen.rb

This command installs the package source, build it according to the formula instructions ( defined in the install function), and install the resulting binary. To test the binary installed run “brew test ”. In my case the command will be

brew test tfblueprintgen

If he tests goes well, you should be seeing the test process running without any errors

Pushing it to up stream and installing it from the upstream repo

Once the formula has been written and tested, now it is time to publish the formula. Create a repository with prefix homebrew like “homebrew-”, which in my case is “homebrew-tfblueprintgen”. Clone this repo locally and move your formula to that folder and push it to github.

To install your tap locally from the formula stored in github

  • Run brew tap /homebrew-
  • Then run brew install

In my case this is

brew tap krishnaduttPanchagnula/homebrew-tfblueprintgen

brew install tfblueprintgen

Voila, your package can now be installed via homebrew.