Thursday, 27 May 2021

Jenkins Nexus Integration - How to integrate Nexus with Jenkins

 


You need to install Nexus Artifact Uploader plug-in to integrate Nexus with Jenkins. Let us see how to integrate Jenkins with Nexus and able to upload War/Ear/Jar/Exe/DLLs.


Pre-requistes:

Install Nexus Artifact Uploader plugin in Jenkins.


Steps:

1. Once you installed the above plug-ins, click existing FreeStyle job configuration or create a new job.

2. Under source code management. enter bitbucket repo url and git credentials.

3. Go to build section, add Maven targets. with goals clean install. Also click advance, give path of POM.xml



4. click on Add build step, choose Nexus artifact uploader.



5. Enter information per below screen shot.
Make sure you enter version as 1.0-SNAPSHOT and repository as maven-snapshots. You can take the information from your WebApp/pom.xml from Bitbucket Repo


6. Click on Apply, Save.



7. Now login to Nexus repo, Click on Components, Click on maven-snapshots


8. you shall see the WAR being uploaded here.
Note:

Click here for Jenkins pipeline code for Nexus Upload.

How to Install Nexus on RedHat Linux

Nexus is binary repository manager, used for storing build artifacts. We will eventually integrate Nexus with Jenkins for uploading WAR/EAR/JAR files there.

Here are the steps for installing Sonatype Nexus 3 in RHEL in EC2 on AWS. Please create a new Redhat EC2 instance with small type. Choose Redhat Enterprise 8.



Pre-requisites:
Make sure you open port 8081 in AWS security group

Installation Steps:

sudo yum install wget -y






Download Open JDK
sudo yum install java-1.8.0-openjdk.x86_64 -y

Execute the below command to navigate to /opt directory by changing directory:
cd /opt

Download Nexus
sudo wget http://download.sonatype.com/nexus/3/nexus-3.23.0-03-unix.tar.gz

Extract Nexus
sudo tar -xvf nexus-3.23.0-03-unix.tar.gz
sudo mv nexus-3.23.0-03 nexus

Create a user called Nexus
sudo adduser nexus

Change the ownership of nexus files and nexus data directory to nexus user.
sudo chown -R nexus:nexus /opt/nexus
sudo chown -R nexus:nexus /opt/sonatype-work

Configure to run as Nexus user
change as below screenshot by removing # and adding nexus
 sudo vi /opt/nexus/bin/nexus.rc

Modify memory settings in Nexus configuration file
sudo vi /opt/nexus/bin/nexus.vmoptions

Modify the above file as shown in red highlighted section:










-Xms512m
-Xmx512m
-XX:MaxDirectMemorySize=512m
after making changes, press wq! to come out of the file.

Configure Nexus to run as a service

sudo vi /etc/systemd/system/nexus.service
Copy the below content highlighted in green color.

[Unit]
Description=nexus service
After=network.target
[Service]
Type=forking
LimitNOFILE=65536
User=nexus
Group=nexus
ExecStart=/opt/nexus/bin/nexus start
ExecStop=/opt/nexus/bin/nexus stop
User=nexus
Restart=on-abort
[Install]
WantedBy=multi-user.target

Create a link to Nexus
sudo ln -s /opt/nexus/bin/nexus /etc/init.d/nexus

Execute the following command to add nexus service to boot.

sudo chkconfig --add nexus
sudo chkconfig --levels 345 nexus on

Start Nexus
sudo service nexus start







Check whether Nexus service is running
sudo service nexus status

Check the logs to see if Nexus is running
tail -f /opt/sonatype-work/nexus3/log/nexus.log

You will see Nexus started..
If you Nexus stopped, review the steps above.

Now press Ctrl C to come out of this windows.

Once Nexus is successfully installed, you can access it in the browser by URL - http://public_dns_name:8081

Click on Sign in link
user name is admin and password can be found by executing below command:

sudo cat /opt/sonatype-work/nexus3/admin.password



Copy the password and click sign in.
Now setup admin password as admin123

you should see the home page of Nexus:


Please follow steps for integrating Nexus with Jenkins

Wednesday, 26 May 2021

Deploy Tomcat with Terraform

 Overview

The goal is to implement Devops best practices to run Terraform in Jenkins Pipelines to deploy a tomcat. We will go over the main concepts that need to be considered and a Jenkinsfile that runs Terraform. The Jenkinsfile will consists of parameters that allows us to pass data as variables in our pipeline job. 


  • Install Terraform on Jenkins Server
  • Install Terraform Plugin on Jenkins
  • Configure Terraform
  • Store and Encrypt Credentials in Jenkins
  • Setting up CD Pipeline with Terraform
  • Bash Script to Deploy Tomcat
  • Run Pipeline Job


Install Terraform on Jenkins Server


Use the following commands to install Terraform on Jenkins server and move the binaries to the correct path as shown below.


  • wget https://releases.hashicorp.com/terraform/0.12.24/terraform_0.12.24_linux_amd64.zip
  • unzip terraform_0.12.24_linux_amd64.zip
  • sudo mv terraform /usr/bin/

Install Terraform plugin on Jenkins

Go to Manage Jenkins > Manage Plugins >Available > search Terraform as shown below:

As you can see, Terraform Plugin is already installed on my Jenkins hence why it's displayed in the Installed section.

Store and Encrypt Credentials in Jenkins (Access and Secret Key) 

In this step, we will be storing and encrypting the access and secret key in Jenkins to maximize security and minimize the chances of exposing our credentials.

    • Go to Manage Jenkins > Manage Credentials > Click on Jenkins the highlighted link as shown below


    • Select Add Credentials
    • Choose Secret text in the Kind field
    •  Enter the following below:
    Note: Modify the yellow highlighted text with the right value.
      • Secret = EnterYourSecretKeyHere
      • ID = AWS_SECRET_ACCESS_KEY
      • Description = AWS_SECRET_ACCESS_KEY
    Click OK

    Add another credential and enter the following:

      • Secret = EnterYourAccessIDHere
      • ID = AWS_ACCESS_KEY_ID
      • Description = AWS_ACCESS_KEY_ID

    Click OK





    Configure Terraform

    Go to Manage Jenkins > Global Tool Configuration > It will display Terraform on the list.

    • Enter terraform in the Name field
    • Provide the path /usr/bin/ as shown below




    Setting up CD Pipeline for Terraform

    • Go to Jenkins > New Items. Enter tomcat-pipeline in name field > Choose Pipeline > Click OK


    • Select Configure after creation.
    • Go to Build Triggers and enable Trigger builds remotely.
    • Enter tf_token as Authentication Token

     

    Bitbucket Changes
      • Create a new Bitbucket Repo and call it tomcat-pipeline
      • Go to Repository Settings after creation and select Webhooks
      • Click Add Webhooks
      • Enter tf_token as the Title
      • Copy and paste the url as shown below
                  http://JENKINS_URL:8080/job/terraform-pipeline//buildWithParameters?token=tf_token
      • Status should be active
      • Click on skip certificate verification
      • triggers --> repository push
    • Go back to Jenkins, select Pipeline Script From SCM
    • Enter credentials for Bitbucket, Leave the Branch master as the default, Make sure script path is Jenkinsfile
    • Right click on Pipeline Syntax and open in a new tab. 
    • Choose Checkout from Version Control in the Sample Step field
    • Enter Bitbucket Repository URL and Credentials, leave the branches blank
    • Click GENERATE PIPELINE SCRIPT, copy credentialsId and url (This is required for Jenkinsfile script)



    Open VSCode
    • Open Visual Code Studio and click on

      Terminal













    • Navigate to tomcat-pipeline repo in Bitbucket
    • Run the command before cloning repo: git init
    • Clone the repo with SSH or HTTPS
    • Create a new file main.tf and copy the below code in yellow color



















    provider "aws" {
    region = var.region
    version = "~> 2.0"
    }
    resource "aws_instance" "ec2" {
    user_data = base64encode(templatefile("deploy.sh", {JAVA_HOME = var.java_home}))
    ami = "ami-0782e9ee97725263d"   ##Change AMI to meet OS requirement as needed.
    root_block_device {
        volume_type           = "gp2"
        volume_size           = 200
        delete_on_termination = true
        encrypted             = true
      }
    tags = {
    Name = "u2-${var.environment}-${var.application}"
    CreatedBy = var.launched_by
    Application = var.application
    OS = var.os
    Environment = var.environment
    }
    instance_type = var.instance_type
    key_name = "Enter_KEYPAIR_Name_Here"
    vpc_security_group_ids = [aws_security_group.ec2_SecurityGroups.id]
    }
    output "ec2_ip" {
    value = [aws_instance.ec2.*.private_ip]
    }
    output "ec2_ip_public" {
    value = [aws_instance.ec2.*.public_ip]
    }
    output "ec2_name" {
    value = [aws_instance.ec2.*.tags.Name]
    }
    output "ec2_instance_id" {
    value = aws_instance.ec2.*.id


    • Create a new file security.tf and copy the below code in yellow color.
    (Note: Change the tomcat port highlighted in red as needed if default is not 3000)

    resource "aws_security_group" "ec2_SecurityGroups" {
    name = "u2-${var.environment}-sg-${var.application}"
    description = "EC2 SG"
    ingress {
    from_port = 22
    to_port = 22
    protocol = "tcp"
    cidr_blocks = ["0.0.0.0/0"]
    }

    ## TOMCAT PORT
    ingress {
         from_port   = 4000
    to_port     =
     4000
    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
    egress {
    from_port = 0
    to_port = 0
    protocol = "-1"
    cidr_blocks = ["0.0.0.0/0"]
    }
    }

    • Create a new file variable.tf and copy the below code in yellow color. 

    variable region {
      type        = string
      default = "us-east-2"
    }
    variable "instance_type" {}
    variable "application" {}
    variable "environment" {}
    variable "java_home" {
    type = string
    default = "/opt/java/jdk1.8.0_251"
    }
    ############## tags
    variable os {
      type        = string
      default = "Ubuntu"
    }
    variable launched_by {
      type        = string
      default = "USER"
    }
    ############## end tags


    Bash Script to Deploy Tomcat and Java application

    • Create a new file deploy.sh and copy the below code in yellow color. 
    #!/bin/bash
    set -x

    exec > >(tee /var/log/user-data.log|logger -t user-data -s 2>/dev/console) 2>&1

    echo ""
    echo "........................................"
    echo "Installation of application"
    echo "........................................"
    echo "Today's date: `date`"
    echo "........................................"
    echo ""
    sudo apt-get install -y unzip
    sudo apt update
    curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
    unzip awscliv2.zip
    sudo ./aws/install
    aws --version
    sudo apt-get install wget
    echo 'Installing Java...'
    wget https://deploy-app-servers.s3.us-east-2.amazonaws.com/java/jdk-8u251-linux-x64.tar.gz -P /opt/java/
    echo untar JAVA
    sudo tar -xf /opt/java/jdk-8u251-linux-x64.tar.gz -C /opt/java/
    sudo touch environment
    echo "export JAVA_HOME=/opt/java/jdk1.8.0_251" >> environment
    sudo mv -f environment /etc/
    source /etc/environment
    echo Set JAVA HOME
    echo Completed installing java
    echo Set JAVA HOME
    function check_java_home {
        if [ -z ${JAVA_HOME} ]
        then
            echo 'Could not find JAVA_HOME. Please install Java and set JAVA_HOME'
    exit
        else
    echo 'JAVA_HOME found: '$JAVA_HOME
            if [ ! -e ${JAVA_HOME} ]
            then
        echo 'Invalid JAVA_HOME. Make sure your JAVA_HOME path exists'
        exit
            fi
        fi
    }

    echo 'Installing tomcat server...'
    echo 'Checking for JAVA_HOME...'
    check_java_home

    echo 'Downloading tomcat-9.0...'
    if [ ! -f /etc/apache-tomcat-9*tar.gz ]
    then
        curl -O https://downloads.apache.org/tomcat/tomcat-9/v9.0.54/bin/apache-tomcat-9.0.54.tar.gz
    fi
    echo 'Finished downloading...'

    echo 'Creating install directories...'
    sudo mkdir -p '/opt/tomcat/9_0'

    if [ -d "/opt/tomcat/9_0" ]
    then
        echo 'Extracting binaries to install directory...'
        sudo tar -xzf apache-tomcat-9*.tar.gz -C "/opt/tomcat/9_0" --strip-components=1
        echo 'Creating tomcat user group...'
        sudo groupadd tomcat
        sudo useradd -s /bin/false -g tomcat -d /opt/tomcat tomcat

        echo 'Setting file permissions...'
        cd "/opt/tomcat/9_0"
        sudo chgrp -R tomcat "/opt/tomcat/9_0"
        sudo chmod -R g+r conf
        sudo chmod -R g+x conf

        # This should be commented out on a production server
        sudo chmod -R g+w conf

        sudo chown -R tomcat webapps/ work/ temp/ logs/

        echo 'Setting up tomcat service...'
        sudo touch tomcat.service
        sudo chmod 777 tomcat.service
        echo "[Unit]" > tomcat.service
        echo "Description=Apache Tomcat Web Application Container" >> tomcat.service
        echo "After=network.target" >> tomcat.service

        echo "[Service]" >> tomcat.service
        echo "Type=forking" >> tomcat.service

        echo "Environment=JAVA_HOME=$JAVA_HOME" >> tomcat.service
        echo "Environment=CATALINA_PID=/opt/tomcat/9_0/temp/tomcat.pid" >> tomcat.service
        echo "Environment=CATALINA_HOME=/opt/tomcat/9_0" >> tomcat.service
        echo "Environment=CATALINA_BASE=/opt/tomcat/9_0" >> tomcat.service
        echo "Environment='CATALINA_OPTS=-Xms512M -Xmx1024M -server -XX:+UseParallelGC'" >> tomcat.service
        echo "Environment=JAVA_OPTS=-Djava.awt.headless=true-Djava.security.egd=file:/dev/./urandom" >> tomcat.service

        echo "ExecStart=/opt/tomcat/9_0/bin/startup.sh" >> tomcat.service
        echo "ExecStop=/opt/tomcat/9_0/bin/shutdown.sh" >> tomcat.service

        echo "User=tomcat" >> tomcat.service
        echo "Group=tomcat" >> tomcat.service
        echo "UMask=0007" >> tomcat.service
        echo "RestartSec=10" >> tomcat.service
        echo "Restart=always" >> tomcat.service

        echo "[Install]" >> tomcat.service
        echo "WantedBy=multi-user.target" >> tomcat.service

        sudo mv tomcat.service /etc/systemd/system/tomcat.service
        sudo chmod 755 /etc/systemd/system/tomcat.service
        sudo systemctl daemon-reload
        sleep 3
        sudo sed -i 's/8080/4000/g' /opt/tomcat/9_0/conf/server.xml

        echo 'Starting tomcat server....'
        sudo systemctl start tomcat
        exit
    else
        echo 'Could not locate installation directory..exciting..'
        exit
    fi

        sudo systemctl start tomcat

    echo ""
    echo "........................................"
    echo "Installation of application"
    echo "........................................"
    echo "Today's date: `date`"
    echo "........................................"
    echo ""




    • Create a new file Jenkinsfile and copy the below code in yellow color. 



    pipeline {
        agent {
          node {
            label "master"
          } 
        }

        parameters {
            string(name: 'AppName', defaultValue: 'Enter App Name', description: 'Name of application', )
            choice(choices: ['master', 'dev', 'qa', 'uat', 'prod'], description: 'Select lifecycle to Deploy', name: 'Branch')
            choice(choices: ['t2.micro', 't2.small', 't2.large', 't2.xlarge'], description: 'Select Instance Size', name: 'InstanceSize')
            booleanParam(name: 'autoApprove', defaultValue: false, description: 'Automatically run apply after generating plan?')
        }


         environment {
            AWS_ACCESS_KEY_ID     = credentials('AWS_ACCESS_KEY_ID')
            AWS_SECRET_ACCESS_KEY = credentials('AWS_SECRET_ACCESS_KEY')
            TF_VAR_instance_type = "${params.InstanceSize}"
            TF_VAR_environment = "${params.Branch}"
            TF_VAR_application = "${params.AppName}"
        }
    // 

        stages {
          stage('checkout') {
            steps {
                echo "Pulling changes from the branch ${params.Branch}"
                git credentialsId: 'paste-credentialsId-here', url: 'paste-url-here' , branch: "${params.Branch}"
            }
          }

            stage('terraform plan') {
                steps {
                    sh "pwd ; terraform init -input=true"
                    sh "terraform plan -input=true -out tfplan"
                    sh 'terraform show -no-color tfplan > tfplan.txt'
    }
                }
            
            stage('terraform apply approval') {
               when {
                   not {
                       equals expected: true, actual: params.autoApprove
                   }
               }

               steps {
                   script {
                        def plan = readFile 'tfplan.txt'
                        input message: "Do you want to apply the plan?",
                        parameters: [text(name: 'Plan', description: 'Please review the plan', defaultValue: plan)]
                   }
               }
           }

            stage('terraform apply') {
                steps {
                    sh "terraform apply -input=true tfplan"
                }
            }
            
            stage('terraform destroy approval') {
                steps {
                    input 'Run terraform destroy?'
                }
            }
            stage('terraform destroy') {
                steps {
                    sh 'terraform destroy -force'
                }
            }
        }

      }

    • Commit and push code changes to Repo with the following:
      • In Vscode, navigate to Source Code Icon on the right tabs on the side
      • Enter commit message
      • Click the + icon to stage changes 

      • Push changes by clicking on the ðŸ”„0 ⬇️ 1 ⬆️ as shown below

    Run Pipeline Job

    • Go to tomcat-pipeline on Jenkins and run build 
    Note: The pipeline job will fail the first time to capture the parameters in Jenkinsfile

    • The next time you run a build you should see as shown below





    • Enter AppName
    • Select a Branch/Lifecycle to deploy server
    • Choose instance size for the server.
    • Go to Console Output to track progress
    Note: You can abort the destroy step and rerun the step by installing Blue Ocean Plugin on Jenkins to delete the resources created.

    How to upgrade Maven

      java.lang.IllegalStateException I had installed maven in my ubuntu using command  apt install maven This installed maven in path /usr/shar...