Setting Up a CI/CD Pipeline with Jenkins, Maven, and Tomcat on AWS EC2 Instances running Ubuntu

Setting Up a CI/CD Pipeline with Jenkins, Maven, and Tomcat on AWS EC2 Instances running Ubuntu

In the fast-paced world of software development, having a reliable and efficient Continuous Integration and Continuous Deployment (CI/CD) pipeline is essential. A well-structured CI/CD pipeline can streamline the development process, improve code quality, and accelerate the delivery of new features and bug fixes to production. In this article, we will guide you through the process of setting up a robust CI/CD pipeline using Jenkins, Maven, and Tomcat.

Why CI/CD?

Before we dive into the technical details, let's briefly discuss why CI/CD is crucial for modern software development.

1. Faster Development: CI/CD automates the build and deployment process, reducing manual interventions and accelerating development cycles.

2. Improved Code Quality: Automated testing and code analysis tools can catch issues early in the development process, leading to higher code quality.

3. Reliable Releases: CI/CD ensures that each code change is thoroughly tested before deployment, minimizing the risk of introducing bugs or breaking existing functionality.

4. Collaboration: Teams can work more collaboratively, as CI/CD provides a central platform for code integration and deployment.

Now, let's get started with setting up our CI/CD pipeline.

Prerequisites

Before you begin, make sure you have the following:

  1. Two AWS EC2 instances running Ubuntu (one for Jenkins and one for Tomcat).

  2. SSH access to both instances.

  3. A GitHub repository with your application code.

  4. Basic knowledge of Linux commands.

Step 1: Set Up Jenkins Server

On Jenkins Server:

  1. SSH into your Jenkins server.

  2. Update the package list and install Jenkins:

     sudo apt update
     sudo apt install openjdk-11-jdk -y
     wget -q -O - https://pkg.jenkins.io/debian/jenkins.io.key | sudo apt-key add -
     sudo sh -c 'echo deb http://pkg.jenkins.io/debian-stable binary/ > /etc/apt/sources.list.d/jenkins.list'
     sudo apt update
     sudo apt install jenkins -y
    
  3. Start and enable Jenkins:

     sudo systemctl start jenkins
     sudo systemctl enable jenkins
    
  4. Retrieve the Jenkins initial admin password:

     sudo cat /var/lib/jenkins/secrets/initialAdminPassword
    
  5. Visit http://<Your_Jenkins_Server_IP>:8080 in your web browser and enter the initial admin password to complete the Jenkins setup.

  6. Install recommended plugins when prompted.

  7. Create an admin user and set up Jenkins according to your preferences.

Step 2: Set Up Tomcat Server

On Tomcat Server:

  1. SSH into your Tomcat server.

  2. Install Java and Tomcat:

     sudo apt update
     sudo apt install openjdk-11-jdk -y
     wget https://downloads.apache.org/tomcat/tomcat-9/v9.0.54/bin/apache-tomcat-9.0.54.tar.gz
     sudo tar -xzvf apache-tomcat-9.0.54.tar.gz -C /opt
     sudo mv /opt/apache-tomcat-9.0.54 /opt/tomcat
    
  3. Start Tomcat:

     sudo /opt/tomcat/bin/startup.sh
    
  4. Open port 8080 in your security group settings on AWS to allow external access to Tomcat.

  5. Configure Tomcat for your application. (See the application's documentation for specific configuration details.)

Step 3: Configure Jenkins and GitHub Integration

On Jenkins Server:

  1. Install Maven:

     sudo apt install maven -y
    

Step 4: Setting Up SSH Authentication

On Jenkins Server:

  1. Generate SSH Key Pair:

    • Log in to your Jenkins server.

    • Open a terminal window.

    • Generate an SSH key pair using the following command:

        ssh-keygen -t rsa -b 2048
      
    • Follow the prompts to generate the SSH key. You can leave the passphrase empty for automated authentication.

  2. Copy the Public Key:

    • After generating the key pair, the public key is stored in the ~/.ssh/id_rsa.pub file.

    • Display the public key using the following command:

        cat ~/.ssh/id_rsa.pub
      
    • Copy the entire content of the public key, including the "ssh-rsa" prefix.

      On Tomcat Server:

  3. Add SSH Public Key to Tomcat Server:

    • SSH into your Tomcat server.

    • Navigate to the user's home directory (e.g., /home/ubuntu).

    • Create a .ssh directory if it doesn't already exist:

        mkdir -p ~/.ssh
      
    • Inside the .ssh directory, create a file named authorized_keys if it doesn't exist:

        touch ~/.ssh/authorized_keys
      
    • Edit the authorized_keys file:

        nano ~/.ssh/authorized_keys
      
    • Paste the public key you copied from the Jenkins server into this file.

    • Save and close the file.

  4. Set Permissions:

    • Ensure that the .ssh directory and the authorized_keys file have the correct permissions:

        chmod 700 ~/.ssh
        chmod 600 ~/.ssh/authorized_keys
      
  5. SSH Configuration:

    • If not already configured, open the SSH configuration file for editing:

        nano /etc/ssh/sshd_config
      
    • Set the following options:

        PasswordAuthentication no
        PermitRootLogin no
      
    • Save and close the file.

  6. Restart SSH Service:

    • Restart the SSH service to apply the changes:

        sudo systemctl restart ssh
      

On Jenkins Server:

  1. Test SSH Connection:

    • Test the SSH connection from your Jenkins server to the Tomcat server to ensure that key-based authentication works:

        ssh ubuntu@your-tomcat-ip
      
    • Replace your-tomcat-ip with the actual IP address of your Tomcat server.

    • You should be able to connect without being prompted for a password.

In Jenkins Pipeline Script:

  1. Modify your Jenkins pipeline script to include the SSH commands for deploying to Tomcat. Below is an example Jenkins pipeline script:
pipeline {
    agent any
    tools {
        maven 'Maven-Tool'
    }
    environment {

        your_tomcat_ip = '<your-tomcat-public-ip>' 
        WAR_FILE = '<your app name>'

    }
    stages {
        stage("Git Checkout") {
            steps {
                git branch: 'master', credentialsId: 'git', url: 'https://github.com/<user-name>/<sample-code>.git'
            }
        }
        stage("Maven Build") {
            steps {
                sh "mvn clean package"
            }
        }
        stage("Archive Artifact") {
            steps {
                archiveArtifacts 'target/*.war'
            }
        }

        stage ('Deploying Artifact') {
            steps {
                script {
                    sshagent(credentials: ['tomcat-server']) {

                        sh "scp -o StrictHostKeyChecking=no $WORKSPACE/*/*.war ubuntu@${env.your_tomcat_ip}:/tmp/"
                        sh "ssh ubuntu@${env.your_tomcat_ip} 'sudo mv /tmp/*.war /opt/tomcat/webapps/${env.WAR_FILE}.war'"
                        sh "ssh ubuntu@${env.your_tomcat_ip} 'sudo systemctl restart tomcat.service'"

                    }
                }
            }
        }
    }
}

Make sure to replace <your-tomcat-public-ip>, <your app name >,https://github.com/<user-name>/<sample-code>.git with the actual IP address of your Tomcat server and adjust the paths and settings as needed for your project.

you can clone my git repo as well for codes and files https://github.com/Shahid199578/java-Sample-code.git

Step 5: Configure the Jenkins Job

On Jenkins Server:

  1. Go to your Jenkins Dashboard.

  2. Create a new Jenkins job:

    • Click on "New Item" in the Jenkins dashboard.

    • Enter a name for your job and select "Pipeline" as the job type.

  3. Configure your pipeline job:

    • In the "Pipeline" section, select "Pipeline script from SCM."

    • Choose Git as your SCM (Source Code Management) system.

    • Enter the URL of your Git repository.

    • Optionally, specify the credentials for accessing your Git repository.

    • Choose "Jenkinsfile" as the Script Path. This should point to the Jenkins file you created in your repository.

  4. Save your Jenkins job configuration.

Step 6: Trigger Automatic Builds with Poll SCM

On Jenkins Server:

  1. Go to your Jenkins Dashboard.

  2. Create a new Jenkins job:

    • Click on "New Item" in the Jenkins dashboard.

    • Enter a name for your job and select "Pipeline" as the job type.

  3. Configure your pipeline job:

    • In the "Pipeline" section, select "Pipeline script from SCM."

    • Choose Git as your SCM system.

    • Enter the URL of your Git repository.

    • Optionally, specify the credentials for accessing your Git repository.

    • Choose "Jenkinsfile" as the Script Path. This should point to the Jenkins file you created in your repository.

  4. Scroll down to the "Build Triggers" section.

  5. Check the option "Poll SCM."

  6. In the "Schedule" field, specify how often Jenkins should check for changes using a cron-like syntax. For example, you can use * * * * * to check every minute. Adjust the schedule as needed.

  7. Save your Jenkins job configuration.

On your development machine:

Make code changes in your GitHub repository.

  1. Push the changes to your GitHub repository.

Now, Jenkins will automatically check your source code repository for changes based on the specified schedule. When changes are detected, it will trigger a build of your pipeline.

Keep in mind that enabling frequent polling can put some load on your source code repository and Jenkins server. Adjust the polling schedule according to the needs of your project and infrastructure.

Step 7: Testing the CI/CD Pipeline


With this Jenkins pipeline script, you can automate the build and deployment process of your web application to the Tomcat server. The pipeline will trigger builds automatically whenever changes are pushed to your Git repository, streamlining your development workflow.

Verification:

  • Observe that code changes trigger automatic builds in Jenkins.

  • Verify that the changes are correctly reflected in the Tomcat Server.

Congratulations! You've successfully set up a robust CI/CD pipeline using Jenkins, Maven, and Tomcat. This pipeline will ensure that your software development process is efficient, reliable, and ready to adapt to the ever-evolving demands of modern application development. Happy coding!

Did you find this article valuable?

Support Mohd Shahid by becoming a sponsor. Any amount is appreciated!