Provisioning a Jenkins Server on AWS Using Terraform
In this tutorial, we will be using Terraform to provision a Jenkins server in AWS.

Background
Scenario
Your team has been using a Jenkins server locally for their CI/CD pipeline and now wants to move it into the cloud. You have been tasked with setting up a Jenkins server on AWS.
Requirements
- The Jenkins server must be deployed on an EC2 instance
- The EC2 instance should be accessible via the internet on port 8080
- Only you should be able to access the EC2 instance via SSH
- Use Terraform for Infrastructure as Code
How will we accomplish this task with Terraform?
- Create the VPC
- Create the Internet Gateway and attach it to the VPC using a Route Table
- Create a Public Subnet and associate it with the Route Table
- Create a Security Group for the EC2 Instance
- Create a script to automate the installation of Jenkins on the EC2 Instance
- Create the EC2 Instance and attach an Elastic IP and Key Pair to it
- Verify that everything works
Prerequisites

Setting Up The Project Directory
First, we’re going to need to set up our directory. This is what it is going to look like when all said and done.
terraform-jenkins/
├─ main.tf
├─ outputs.tf
├─ secrets.tfvars
├─ modules/
│ ├─ compute/
│ │ ├─ main.tf
│ │ ├─ outputs.tf
│ │ ├─ install_jenkins.sh
│ ├─ security_group/
│ │ ├─ main.tf
│ │ ├─ outputs.tf
│ ├─ vpc/
│ │ ├─ main.tf
│ │ ├─ outputs.tf
You can run the following command to create the directory structure from above:
mkdir -p terraform-jenkins/modules/{compute,security_group,vpc} && cd terraform-jenkins && touch main.tf outputs.tf secrets.tfvars && cd modules/compute && touch main.tf outputs.tf install_jenkins.sh && cd ../security_group && touch main.tf outputs.tf && cd ../vpc && touch main.tf outputs.tf
Go ahead and open the terraform-jenkins folder in your favorite IDE. Now let’s start by filling out our variables and secrets file.
Variables and Secrets
Open variables.tf and fill it out with the following code:
Now open secrets.tfvars
and fill it in with the following:
my_ip="0.0.0.0" // replace 0.0.0.0 with your IP address
Configuring Terraform
Now that the variables and secrets have been created, we can start working on our modules.
Step One — Create the VPC
Open the file ./modules/vpc/main.tf
and fill it out with the following code:
Step Two — Create the Internet Gateway and attach it to the VPC using a Route Table
Now that the VPC has been created, we need to give it access to the internet. We’ll be creating an Internet Gateway and a Route Table. Inside the file ./modules/vpc/main.tf
, add the following:
Step Three — Create a Public Subnet and associate it with the Route Table
Now that we have the Route Table and Internet Gateway created, the VPC has access to the internet. Now, all we need to do is create our public subnet and associate it with our public route table so that it can have access to the internet. Inside the file ./modules/vpc/main.tf
, add the following code:
That’s about it with setting up our VPC. We just have one last thing to do, and that is to create a few outputs. Open up the file ./modules/vpc/outputs.tf
and add the following code:
Step Four — Create a Security Group for the EC2 Instance
Our VPC has been set up and configured. Now let’s move on to the security group for our EC2 instance. Open the file ./modules/security_group/main.tf
and add the following code:
That is it for creating our security group, now let’s add an output to our ./modules/security_group/outputs.tf
file:
Step Five — Create a Script to Automate the Installation of Jenkins on the EC2 Instance
Before we start working on the EC2 instance, let’s create the bash script we are going to use to automate the installation of Jenkins. We are going to be attaching this to the EC2 instance as user data, which will run at the time of the creation of the EC2 instance. Open up ./modules/compute/install_jenkins.sh
and add the following code:
Step Six— Create the EC2 Instance and Attach an Elastic IP and Key Pair To It
Before we dive into creating the EC2 instance and Elastic IP, let’s create our key pair real quick. Run the following command to create a key pair:
ssh-keygen -t rsa -b 4096 -m pem -f tutorial_kp && mv tutorial_kp.pub modules/compute/tutorial_kp.pub && mv tutorial_kp tutorial_kp.pem && chmod 400 tutorial_kp.pem
Sweet. Now that the key pair has been created let's create the EC2 instance and Elastic IP. Open up ./modules/compute/main.tf
and add the following code:
We are almost done! Let’s create an output in our ./modules/compute/outputs.tf
file. This output is going to output the public IP address of our EC2 instance.
Step 7 —Verify That Everything Works
Let’s initialize our terraform project.
terraform init
Now let’s run our terraform project.
terraform apply -var-file="secrets.tfvars"
When prompted, enter: Yes
If successful, you should see something like this:

Sweet! That IP address labeled “jenkins_public_ip” is the IP address of our Jenkins server. Let’s see if we can SSH into our EC2 instance.
ssh -i tutorial_kp.pem ubuntu@$(terraform output -raw jenkins_public_ip)
And we’re in! Let’s check and see if our user data script was running.
curl http://169.254.169.254/latest/user-data

And sure enough, it was! Now let's see if we can access the Jenkins server from our web browser. Enter the IP address in your address bar followed by :8080

And voilà, there it is! If you want to grab the administrator password from the EC2 instance, head back over to the terminal and run the following:
sudo cat /var/lib/jenkins/secrets/initialAdminPassword
That will give you the administrator password for the Jenkins server and allow you to continue with the setup process.
Tear Down
To make sure you don’t incur any unnecessary charges from AWS, go ahead and run the following command:
terraform destroy -var-file="secrets.tfvars"
When prompted, enter: Yes
If you had any issues throughout this tutorial, you can compare your code to the GitHub repo here: https://github.com/dispact/terraform-jenkins
Congratulations!
Woohoo, you did it! Throughout this tutorial, you learned how to use Terraform and leveraged infrastructure as code to create a Jenkins Server on an EC2 instance inside a custom VPC on AWS.