How to set up Jenkins to Run on AWS EC2 Instance Using Terraform

Abiola Majek
7 min readSep 18, 2023

--

Hello today I will be doing some projects using Terraform and I will also be doing a simple project on

1. How to create an AWS EC2 instance and also use Terraform to set up and start Jenkins.

2. 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.

3. Create a S3 bucket for your Jenkins Artifacts that is not open to the public.

4. Verify that you can reach your Jenkins install via port 8080 in your browser

For simplicity, I will be using AWS Cloud9 for this project because Cloud9 already has Terraform installed on it, so once I set up Cloud9 Terraform is automatically installed on my IDE

I will push all this code to my GitHub once this project is complete.

Let me give a simple explanation of Terraform and why Terraform is effective in terms of infrastructure as a code tool.

Terraform is infrastructure as a code that will help automate software-defining deployment networks
Terraform supports a vast range of public/private networks.
Terraform is used to deploy an environment across multiple clouds. With the help of Terraform, you deploy in AWS, Azure, and GCP. This makes your job environment AGONSTICS.
With Terraform you can track the state of each resource deployed

Terraform workflow

Here is the complete workflow of Terraform
1) Write down IAC and that infrastructure and the infrastructure must be written in Hashicorp Configuration Language (HCL)
2) Terraform Init. Then you will execute the terraform in the directory to initialize the terraform. Then it will download the plugins and necessary modules.
3)Terraform Plan: It will show you all the resources you have written down in your configuration files and it will display what will deploy once you execute the terraform apply so here if you want any changes in any resource you can make it and update your code file and execute the terraform plan
4)Terraform apply: `It will execute or deploy all the resources you have mentioned on the code file.
5) Terraform destroy is used to destroy the deployment. It will look at the state file and start destroying the resources in our state file.

For this project, I will be using Amazon Linux OS. Another essential resource that I will be using is the Terraform Registry. You can go on your Google and search terraform registry, then you register an account to have access to the terraform registry.

For this project, I used cloud9 IDE because it has Terraform automatically installed on it.

After i set up cloud9 IDE i will clone my git repository and next is create a main.tf file and bash file which I called blackteam_jenkins.sh.

Firstly I will create my AWS provider which i copied from harshicorp registry by navigating to the AWS and click the documentation

Please note that for this project I will be using only main.tf so all my code will be hardcoded on main.tf

Let’s create an AWS instance for Jenkins and I will be using the user data to install Jenkins.I created a bash script from above for Jenkins that will run as user data when the EC2 instance is up. I call it “blackteam_jenkins.sh” then I save it

#!/bin/bash
sudo yum 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-2023.key
sudo yum upgrade -y # Add required dependencies for the jenkins package
sudo dnf install java-11-amazon-corretto -y
sudo yum install jenkins -y
sudo systemctl enable jenkins
sudo systemctl start jenkins

I will be using a default vpc so I will not be including vpc in my main.tf code. Terraform adds the default vpc itself

I will create a resource for the security group this will be done by using the Terraform registry

#Jenkins Security Group Resource
resource "aws_security_group" "jenkins-sg" {
name = "jenkins-sg"
description = "Allow Port 22 and 8080"

ingress {
description = "Allow SSH Traffic"
from_port = 22
to_port = 22
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}

ingress {
description = "Allow HTTPS Traffic"
from_port = 443
to_port = 443
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}

ingress {
description = "Allow 8080 Traffic"
from_port = 8080
to_port = 8080
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}

egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
}

Next is to create an S3 bucket

Now i will create the EC2 instance which will include

  1. ami which i got from aws launch instance console
  2. Instance type: Which is the t2.micro
  3. Key_name : This is the keypair
  4. vpc_security_group_ids: These are the ports where the ec2 instance will be connected. I created this identity file
  5. user data is the bash script created to run jenkins

This is how your main.tf file will look like

terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "5.16.2"
}
}
}

# Configure the AWS Provider
provider "aws" {
region = "us-west-1"
}


resource "aws_instance" "black_jenkins" {
ami = "ami-073e64e4c237c08ad" # use free tier AMI other than Amazon Linux 2023 AMI as it has some issue insatlling Jenkins
instance_type = "t2.micro"
key_name = "danny"
associate_public_ip_address = true
vpc_security_group_ids = [aws_security_group.jenkins-sg.id]
user_data = file("blackteam_jenkins.sh")
#iam_instance_profile = aws_iam_instance_profile.s3-jenkins-profile.name

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


#Jenkins Security Group Resource
resource "aws_security_group" "jenkins-sg" {
name = "jenkins-sg"
description = "Allow Port 22 and 8080"

ingress {
description = "Allow SSH Traffic"
from_port = 22
to_port = 22
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}

ingress {
description = "Allow HTTPS Traffic"
from_port = 443
to_port = 443
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}

ingress {
description = "Allow 8080 Traffic"
from_port = 8080
to_port = 8080
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}

egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
}

resource "aws_s3_bucket" "black_bucket_team23" {
bucket = "jenkins-s3-bucket-black-bucket-team2323"

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


resource "aws_s3_bucket_acl" "s3_bucket_acl" {
bucket = aws_s3_bucket.black_bucket_team23.id
acl = "private"
depends_on = [aws_s3_bucket_ownership_controls.s3_bucket_acl_ownership]
}

# Resource to avoid error "AccessControlListNotSupported: The bucket does not allow ACLs"
resource "aws_s3_bucket_ownership_controls" "s3_bucket_acl_ownership" {
bucket = aws_s3_bucket.black_bucket_team23.id
rule {
object_ownership = "ObjectWriter"
}
}

Please make sure you save all these file before you run

terraform init

run terraform validate and next is run

terraform plan

Then run

terraform apply 

We will check if the ec2 instance, security group, and s3 is running

Now we will be using EC2 to ssh into the created Jenkins_server after connecting we will check the Jenkins which is input in the user data

Next is we run

systemctl status jenkins

we will see the status active running. Also important is the password to log in to Jenkins that is generated from checking the Jenkins status. Now I will copy the password and use it to log in to Jenkins.

Now I will copy the public IP address and paste it on the browser using port 8080 set in the security group

I will paste the password generated to access Jenkins. I will complete the registration and we have Jenkins running

Lastly, run

terraform destroy

To delete the created EC2 instance and and s3 bucket.Now we have completed this project and i am going to push my terraform code to GitHub.

Thank you and i hope you like it . please like this if you find interesting.

Kindly follow me www.linkedin.com/in/abiola-majekodunmi-

--

--

Abiola Majek

Business Systems Analyst || Cloud Expert || Devops Engineer || AWS Solutions Architect