In this article, we will learn how to setup the Jenkins Server using the power of Terraform.
There are number of ways to setup the Jenkins Server but that took some efforts and time to setup that. We can use Terraform to setup the infrastructure and configure the Jenkins Server without knowing any code complexity
Pre-requisite:
- Basic knowledge of Terraform
- Terraform should be installed on your machine
- An Active AWS account to be used in this lab
Terraform Configuration
Provider
In the provider block, specify the name of provider (in our case its AWS) and region where you want to configure the infrastructure
Optional - you can provide the Access_KEY & SECRET_KEY inside the block code but it's not recommended to provide the keys in the code
provider "aws" {
region = "us-east-1"
}
Networking
In this lab we will be setting up our own VPC, Subnets, NAT Gateway, Route Table etc
# Internet gateway to reach the internet
resource "aws_vpc" "web_vpc" {
cidr_block = var.network_cidr
}
resource "aws_internet_gateway" "web_igw" {
vpc_id = aws_vpc.web_vpc.id
}
# Route table with a route to the internet
resource "aws_route_table" "public_rt" {
vpc_id = aws_vpc.web_vpc.id
route {
cidr_block = "0.0.0.0/0"
gateway_id = aws_internet_gateway.web_igw.id
}
# tags {
# Name = "Public Subnet Route Table"
# }
}
# Subnets with routes to the internet
resource "aws_subnet" "public_subnet" {
# Use the count meta-parameter to create multiple copies
count = 2
vpc_id = aws_vpc.web_vpc.id
cidr_block = cidrsubnet(var.network_cidr, 2, count.index + 2)
availability_zone = element(var.availability_zones, count.index)
# tags = {
# Name = "Public Subnet ${count.index + 1}"
# }
}
# Associate public route table with the public subnets
resource "aws_route_table_association" "public_subnet_rta" {
count = 2
subnet_id = aws_subnet.public_subnet.*.id[count.index]
route_table_id = aws_route_table.public_rt.id
}
We will be using Amazon Linux-2 AMI, instead of hardcoding the code with the AMI id, we will take help of DataSource block to retrieve the value of AMI from AWS
data "aws_ami" "AmazonLinux2" {
most_recent = true
filter {
name = "name"
values = ["amzn2-ami-kernel-5.10-hvm-2.0.20220805.0-x86_64-gp2"]
}
filter {
name = "virtualization-type"
values = ["hvm"]
}
owners = ["137112412989"] # Canonical
}
Now it's time to create the EC2 and configure the Jenkins Sever, however one last piece of the puzzle here. I want to expose my Jenkins Server on port 8080 and expose the InitialAdminPassword to configure Jenkins Server on port 80 so we can retrieve that information without login into the EC2 instance. For this we will have to create the Security Group and allow both of these ports
resource "aws_security_group" "jenkins-sg" {
name = "jenkins-sg-12345678"
description = "Allow incoming HTTP traffic from the internet"
vpc_id = aws_vpc.web_vpc.id
ingress {
from_port = 8080
to_port = 8080
protocol = "tcp"
#cidr_blocks = ["0.0.0.0/0"]
}
ingress {
from_port = 80
to_port = 80
protocol = "tcp"
#cidr_blocks = ["0.0.0.0/0"]
}
# Allow all outbound traffic
egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
}
So now we are ready to create the EC2 instance and configure the Jenkins Server. I will be using the bash script and pass that in user data using the file("path") function
#!/bin/bash
yum install update -y
sudo wget -O /etc/yum.repos.d/jenkins.repo https://pkg.jenkins.io/redhat-stable/jenkins.repo
sudo rpm --import https://pkg.jenkins.io/redhat-stable/jenkins.io.key
sudo yum install fontconfig java-11-openjdk
sudo yum install jenkins
sudo systemctl start jenkins
sudo amazon-linux-extras install nginx1 -y
sudo systemctl start nginx
cp /var/lib/jenkins/secrets/initialAdminPassword /var/www/html/index.html
sudo amazon-linux-extras install java-openjdk11
chown -R root:root /var/lib/jenkins
chown -R root:root /var/cache/jenkins
chown -R root:root /var/log/jenkins
sudo systemctl restart docker.service
sed -i 's/JENKINS_USER="jenkins"/JENKINS_USER="root"/' /etc/sysconfig/jenkins
sudo systemctl restart jenkins
Save this Bash script file as install_jenkins.sh
Configure Jenkins Server
resource "aws_instance" "jenkins" {
ami = data.aws_ami.AmazonLinux2.id
instance_type = var.ec2_instance_type
vpc_security_group_ids = [aws_security_group.jenkins-sg.id]
subnet_id = aws_subnet.public_subnet[0].id
associate_public_ip_address = true
user_data = file("install_jenkins.sh")
root_block_device {
delete_on_termination = true
volume_size = "20"
}
tags = {
Name = "Jenkins_Server"
Environment = "Dev"
}
}
Variables Block
To make our code more dynamic, we use couple of variables above so you will have to define the variable.tf file and declare those variable
variable "ec2_instance_type" {
type = string
default = "t2.micro"
description = "Please enter the instance type, if you want to provision different than T2 Micro"
}
variable "service_ports" {
type = list(number)
description = "list of ingress ports"
default = [8080, 80]
}
variable "network_cidr" {
default = "192.168.0.0/24"
description = "Please enter the CIDR"
}
variable "availability_zones" {
type = list(any)
default = ["us-east-1a", "us-east-1d"]
description = "Please enter the AZs"
}
Ola, we have successfully configured the Jenkins Server without going to the AWS Console.
In order to retrieve the IP address of newly created instance, we will use the output { } block.
Output
To make the output more menaningful I'm using a temp file and will display output in more customize way. Save the following code as outputtemp.tpl
%{for ports in port ~}
backend = ${ip_addr}:${ports}
%{endfor ~}
Now save the following to output.tf. The output will get the value form Port list and using for loop, will print Jenkins Sever IP and nginx IP on separate line
output "IPAddress" {
value = templatefile("outputtemp.tpl", { port = ["8080", "80"], ip_addr = aws_instance.jenkins.public_ip })
}
We have successfully setup the Jenkins Sever. To destroy the above created infrastructure
terraform destroy --auto-approve
Thank you for reading my article, if you like this article then don't forget to share it with others. In case you have any question or suggestion please left the comments below, I would love to answer your queries
Top comments (0)