Operations 10 min read

Deploying Jenkins on AWS with Terraform for CI/CD

This tutorial explains how to automate CI/CD by installing Jenkins on an AWS EC2 instance using Terraform, covering prerequisites, Bash installation scripts, plugin setup, a sample pipeline job, Terraform variable definitions, resource provisioning, and accessing the Jenkins web interface.

DevOps Cloud Academy
DevOps Cloud Academy
DevOps Cloud Academy
Deploying Jenkins on AWS with Terraform for CI/CD

Continuous integration, delivery and deployment (CI/CD) can be automated using Jenkins; this article demonstrates how to deploy Jenkins on AWS as IaaS using Terraform.

Prerequisites : an AWS EC2 instance for testing and Terraform installed as an infrastructure‑as‑code tool.

Installing Jenkins and its jobs : The article provides a Bash script to install Jenkins on CentOS, register a default user, install essential plugins, and create a sample HelloWorld pipeline job.

jenkins_user=$1
jenkins_password=$2
jenkins_address=http://localhost:8080

set -x

function installing()
{
    # Installing some necessary dependencies 
    sudo yum -y update
    sudo yum -y install wget java-1.8.0 nano nc
    
    # Installing jenkins, instructions located in http://pkg.jenkins-ci.org/redhat/
    sudo wget -O /etc/yum.repos.d/jenkins.repo http://pkg.jenkins-ci.org/redhat/jenkins.repo
    sudo rpm --import https://pkg.jenkins.io/redhat/jenkins.io.key
    sudo yum install -y jenkins
    
    sleep 1
    echo "[INFO]  Jenkins was installed"
}

The script also defines a plugins function that installs required Jenkins plugins via the Jenkins CLI and restarts the service, looping until Jenkins is reachable.

function plugins()
{
    # Installing jenkins plugins 
    java -jar jenkins-cli.jar -s "$jenkins_address" -auth $jenkins_user:$jenkins_password  install-plugin trilead-api
    java -jar jenkins-cli.jar -s "$jenkins_address" -auth $jenkins_user:$jenkins_password  install-plugin cloudbees-folder
    
    ... many more plugins ...
    
    java -jar jenkins-cli.jar -s "$jenkins_address" -auth $jenkins_user:$jenkins_password  install-plugin pam-auth 
    java -jar jenkins-cli.jar -s "$jenkins_address" -auth $jenkins_user:$jenkins_password  install-plugin ldap
    java -jar jenkins-cli.jar -s "$jenkins_address" -auth $jenkins_user:$jenkins_password  install-plugin email-ext 
    
    # Restart
    sudo systemctl restart jenkins &
    while (( 1 )); do
      echo "[INFO]   waiting for restart Jenkins on port [8080] ..."
      
      java -jar jenkins-cli.jar -s "$jenkins_address" -auth $jenkins_user:$jenkins_password  list-jobs
      if (( $? == 0 )); then
        break
      fi
      
      sleep 20
    done
    
    echo "[INFO]   Jenkins was restarted"
}

A simple pipeline job XML is shown, illustrating a parameterized job that prints "Hello World!".

<?xml version='1.1' encoding='UTF-8'?>
<flow-definition plugin="[email protected]">
  <description></description>
  <keepDependencies>false</keepDependencies>
  <properties>
    <hudson.model.ParametersDefinitionProperty>
      <parameterDefinitions>
        <hudson.model.StringParameterDefinition>
          <name>par_name</name>
          <description></description>
          <defaultValue>HelloWorld</defaultValue>
          <trim>false</trim>
        </hudson.model.StringParameterDefinition>
      </parameterDefinitions>
    </hudson.model.ParametersDefinitionProperty>
  </properties>
  <definition class="org.jenkinsci.plugins.workflow.cps.CpsFlowDefinition" plugin="[email protected]">
    <script>pipeline {
    agent { label 'master' }
    stages {
        stage('build') {
            steps {
                echo "Hello World!"
            }
        }
    }
}</script>
    <sandbox>true</sandbox>
  </definition>
  <triggers/>
  <disabled>false</disabled>
</flow-definition>

Deploying Jenkins as a server : Terraform variables are defined for AWS region, credentials, instance type, key name, and AMI. The aws_instance resource provisions the EC2 instance, copies startup scripts and job definitions, and runs remote commands to configure Jenkins.

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

variable "access_key" {
  default  = "HEREYOURACCESSKEY"
  description = "AWS credentials file path"
}

variable "secret_key" {
  default  = "HEREYOURSECRETKEY"
  description = "AWS credentials file path"
}

variable "jenkins_user_name" {
  description = "jenkins"
  default = "jenkins"
}

variable "jenkins_user_password" {
  description = "jenkins"
  default = "jenkins"
}

variable "jenkins_name" {
  description = "Jenkins name"
  default = "jenkins"
}

variable "jenkins_instance_type" {
  default = "t2.micro"
}

variable "jenkins_key_name" {
  default = "key-pair"
  description = "SSH key located in your AWS account."
}

variable "amis" {
  description = "ami to spawn."
  default = {
    us-east-1 = "ami-0c94855ba95c71c99"
  }
}

resource "aws_instance" "jenkins" {
  instance_type = "${var.jenkins_instance_type}"
  security_groups = ["${aws_security_group.security_group_jenkins.name}"]
  ami = "${lookup(var.amis, var.region)}"
  key_name = "${var.jenkins_key_name}"

  # Add jenkins server startup
  provisioner "file" {
    connection {
      user = "ec2-user"
      host = "${aws_instance.jenkins.public_ip}"
      timeout = "1m"
      private_key = "${file("templates/${var.jenkins_key_name}.pem")}"
    }
    source = "templates/jenkins_startup.sh"
    destination = "/home/ec2-user/jenkins_startup.sh"
  }

  # Add jenkins job
  provisioner "file" {
    connection {
      user = "ec2-user"
      host = "${aws_instance.jenkins.public_ip}"
      timeout = "1m"
      private_key = "${file("templates/${var.jenkins_key_name}.pem")}"
    }
    source = "templates/jobmaster.xml"
    destination = "/home/ec2-user/jobmaster.xml"
  }

  provisioner "remote-exec" {
    connection {
      user = "ec2-user"
      host = "${aws_instance.jenkins.public_ip}"
      timeout = "1m"
      private_key = "${file("templates/${var.jenkins_key_name}.pem")}"
    }
    inline = [
      "chmod +x /home/ec2-user/jenkins*.sh",
      "/home/ec2-user/jenkins_startup.sh ${var.jenkins_user_name} ${var.jenkins_user_password}"
    ]
  }
}

After configuring all variables, run terraform init to initialize the working directory, terraform plan to review the deployment plan, and terraform apply to provision the infrastructure.

Accessing Jenkins : Once the instance is running, copy its public DNS, open http://<public-dns>:8080 in a browser; the default credentials are set via the variables (user: Jenkins, password: Jenkins).

Conclusion : The guide offers a practical, reproducible method to set up Jenkins on AWS using Bash and Terraform, covering user registration, plugin installation, and job creation, with source code available on GitHub.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

ci/cdautomationDevOpsAWSTerraformJenkins
DevOps Cloud Academy
Written by

DevOps Cloud Academy

Exploring industry DevOps practices and technical expertise.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.