A Follow-up to Launching a Jenkins with Terraform

An Advanced Beginner’s Guide to Launching a Jenkins Server with Terraform

Melissa (Mel) Foster
Women in Technology
7 min readJul 5, 2023

--

Edited Logos

Welcome to an advanced, yet still beginner’s walk-through of deploying a Jenkins server with Terraform. As with my previous article, our scenario and objectives remain the same. Our approach is going to be the difference!

Scenario //

Your team would like to start using Jenkins as their CI/CD tool to create pipelines for DevOps projects. You are assigned to create the Jenkins server using Terraform, allowing it to be used in other environments and for changes to be tracked.

Objective //

  • Deploy 1 EC2 Instances in your Default VPC
  • Bootstrap the EC2 instance with a script that will install and start Jenkins
  • Create and assign a Security Group to the Jenkins Security Group that allows traffic on port 22 from your IP and allows traffic from port 8080
  • Create a S3 bucket for your Jenkins Artifacts (Private by Default)
  • Verify that you can reach your Jenkins install via port 8080 in your browser. Be sure to include a screenshot of the Jenkins login screen in your documentation.

To follow along with this project you will need //

  • Access to AWS
  • An Configured AWS Cloud9 with AWS CLI
  • An Optional GitHub Account
  • Attention to Details

Building our Deployment //

To begin, we will once again be utilizing our AWS Cloud9 Environment. Again, I just want to mention that you can use an IDE of your choice, but Cloud9 has the benefit of having Terraform pre-installed. I have attached Documentation for easy referral under the section Helpful Resources.

  • Change into your directory with previously created main.tf
    If you are just joining and not building off of the previous project, you will need to create a new file and save as main.tf.
cd /Terraform/wk20Terraform

Next, we will be creating a view new files, pulling information from our main.tf.

  • Create a new file
    File New File Save As → providers.tf
    (A provider is a plugin which enables interaction with an API.)
#providers for wk20jenkins

terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 3.0"
}
}
}

provider "aws" {
region = var.region
}
  • Create a new file
    File New File Save As → variables.tf
  • Locate your Default VPC off of your AWS Console
    Search bar VPC → Select → Your VPC (off left-hand menu)
#variables for wk20jenkins

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

variable "security_group_name" {
description = "Name of the security group"
default = "wk20sg_jenkins"
}

variable "vpc_id" {
description = "ID of the VPC"
default = "[ENTER YOUR DEFAULT VPC HERE]"
}

variable "instance_ami" {
description = "AMI ID for the EC2 instance"
default = "ami-053b0d53c279acc90"
}

variable "instance_type" {
description = "Instance type for the EC2 instance"
default = "t2.micro"
}
  • Create a new file
    File New File Save As → script.sh
    Note:
    updated since previous article written
#!/bin/bash
sudo apt-get update -y
sudo apt-get install openjdk-11-jre -y
sudo curl -fsSL https://pkg.jenkins.io/debian-stable/jenkins.io-2023.key | sudo tee /usr/share/keyrings/jenkins-keyring.asc > /dev/null
sudo 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 -y
sudo apt-get install fontconfig openjdk-11-jre
sudo apt-get install jenkins -y
sudo apt-getsystemctl start jenkins
sudo apt-get systemctl enable jenkins

Next, we will work on updating our main.tf file to be able to call and pull the necessary data to deploy our Jenkins CI/CD pipeline.

  • Update main.tf
    We now have a resource block for our aws_instance, that now references our variables.tf to build the ami, and set instance type. As well as noted that we will be using a script for our user defined data when we launch our instance.
  • Update our Security Group resource block to now reference name and vpc_id from our variables.tf.
#Simplified main.tf

resource "aws_instance" "ubuntu" {
ami = var.instance_ami
instance_type = var.instance_type
vpc_security_group_ids = [aws_security_group.wk20sg_jenkins.id]
tags = {
Name = "wk20jenkins_instance"
}

#User Data in AWS EC2
user_data = file("script.sh")
}

#Create security group
resource "aws_security_group" "wk20sg_jenkins" {
name = "wk20sg_jenkins"
description = "Open ports 22, 8080, and 443"
vpc_id = var.vpc_id

#Allow incoming TCP requests on port 22 from any IP
ingress {
description = "Incoming SSH"
from_port = 22
to_port = 22
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}

#Allow incoming TCP requests on port 8080 from any IP
ingress {
description = "Incoming 8080"
from_port = 8080
to_port = 8080
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}

#Allow incoming TCP requests on port 443 from any IP
ingress {
description = "Incoming 443"
from_port = 443
to_port = 443
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}

#Allow all outbound requests
egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}

tags = {
Name = "wk20sg_jenkins"
}
}

#Create S3 bucket for Jenkins artifacts; PRIVATE BY DEFAULT
resource "aws_s3_bucket" "wk20jenkins-artifacts" {
bucket = "wk20jenkins-artifacts-${random_id.randomness.hex}"

tags = {
Name = "wk20jenkins_artifacts"
}
}

#Create random number for S3 bucket name
resource "random_id" "randomness" {
byte_length = 8
}
Example of Cloud9 Environment

Deploy our Infrastructure //

Following the Terraform Workflow: write planapply, we will complete the next steps continuing in our Cloud9 environment.

  • Ensure you are in the CWD with all of our new scripts
  • Run terraform init
  • Run terraform fmt -recursive, to verify correct spacing and formatting through all files in CWD
  • Run terraform validate, to verify syntax once again
  • Run terraform plan
  • Run terraform approve -auto-approve

Verify on AWS Console //

  • Navigate to EC2
Successful created EC2
  • Navigate to Security Groups
Successful created Security Group
  • Navigate to S3
Successful created S3 Bucket

Verify Jenkins //

  • Navigate to EC2 Dashboard
  • Open Jenkins EC2
  • Select Connect

Note: We did not set up a .pem file key and will not be able to ssh into. However, if you choose the first tab EC2 Instance Connect we will be able to connect through AWS.

  • Select EC2 Instance Connect
  • Select Connect
    A new window tab should open and you will be connected to your Jenkins EC2.
  • Verify Jenkins
sudo systemctl status jenkins
Jenkins is Active!
  • Validate on web browser
http://<instance_publicip>:8080
Success!

Optional GitHub //

If you are working on building your coding repos, don’t forget to push to your GitHub account. Need a quick review on basic’s of GitHub? Check out one of my previous articles. A quick reference to this project can be found here: https://github.com/mel-foster/Terraform/tree/main/wk20Terraform

Clean Up Time //

It’s time to clean up! Remember it’s not so hard to clean up what we no longer need.

terraform destroy -auto-approve

Tip //

Only use the -auto-approve tag when you are absolutely confident in what you are approving. You never want to destroy something you might still need or will continue using.

Adobe Free Stock Image

Congratulations on completing a little more of an advanced way to streamline a Jenkins server deployment with Terraform. Keep challenging yourself; growth comes from practice and researching. Thank you for reading and following along. I do hope you join me on my next project! See you soon!

Note from the author: This article has an updated title to reflect setting up a Jenkin server for use of a CI/CD pipeline in the future.

Join me on https://www.linkedin.com/in/melissafoster08/ or follow me at https://github.com/mel-foster

All Screen Capture Images ©Melissa (Mel) Foster

--

--

Melissa (Mel) Foster
Women in Technology

𝔻𝕖𝕧𝕆𝕡𝕤 𝗘𝗻𝗴𝗶𝗻𝗲𝗲𝗿 |𝒲𝑜𝓂𝑒𝓃 𝐼𝓃 𝒯𝑒𝒸𝒽 𝒜𝒹𝓋𝑜𝒸𝒶𝓉𝑒 | 𝚂𝚘𝚌𝚒𝚊𝚕 𝙼𝚎𝚍𝚒𝚊 𝙲𝚛𝚎𝚊𝚝𝚘𝚛 | Photographer