Setup SonarQube in OpenShift for scanning projects via Jenkins
When you have software development projects that you are building and running on Red Hat OpenShift you are probably testing them out locally with Minishift, getting the deployment correct, testing source-to-image or running your Dockerfile builds with environment variables to ensure your CI/CD pipeline is ready to roll. Or maybe you are testing out platforms or containers and kubernetes and you want to get a good developer experience when doing it. You also could be testing out this DevOps thing people have been talking about for years and years. One other thing to remember is the “Sec” part of DevSecOps: Sec = security. In my case, I use SonarQube locally and on my platform as part of my “Sec” steps to scan my projects and look for errors, vulnerabilities, bad coding practices, and the like. This post is to show how to setup SonarQube via a template within OpenShift (and Minishift) and call it from your Jenkins pipeline. I will link to a deployment template as well as a GH Readme on how to use SonarQube from Jenkins and get rolling quickly.
First things first, you need Minishift on your machine. I use a Mac for all my development so I used brew to install the latest Minishift executable. You can see other ways to setup Minishift here. I also use VirtualBox for my virtual machine driver for Minishift. I have a script that runs this for doing all my local Minishift development work that adds the vm-driver for VirtualBox, memory of 10GB, and disk-size of 40GB. I also run with the profile flag and save off the VM under a specific name so I can keep track of it. All personal preferences of course and you can run minishift -h to see the options. Figure out the options you wish to use and run minishift start with those options. It will pull down images, start the system, and give you information on how to log in. When that is up and running we are ready to setup SonarQube.
Optional: Enable the Admin-User AddOn
This is optional but I like doing this locally. I enable the admin-user addon for Minishift. This lets you log in with ‘god’ rights. You can run minishift addon enable admin-user and then run minishift addon apply admin-user to do this. Once enabled and then applied you can login with admin/admin and see all the inner workings of Minishift and get a glimpse of what OpenShift has under the covers. There are other addons you can see by running the command minishift addons list as well. (Che is the other one I am testing out.)
Setup the SonarQube Project
Now that we have Minishift setup, you can go to the URL that was listed when you started it in the terminal window and login with admin/admin. Click the Create Project button on the top right and enter sonarqube (all lower case) for the Name field and SonarQube for the Display Name field. You can enter a description if you like to ensure you know what it is later when you look at the project listings.
Click the Create button and then click the SonarQube link that is created for you in the project listings. You will get to the blank screen for a Minishift project. From here you can deploy images, import deployment settings (we are doing this one), import other definitions in YAML format as well as select from templates in the catalog. I encourage you to see how you can import other templates, create your own templates for faster deployments, and get more familiar with this interface if you are going the OpenShift way. I was inspired by the OpenShift Demos GH repo on SonarQube however I needed to update my image and persist data differently. So I went a different route. Not better or worse just different.
Now that you are in the SonarQube project click the “Import YAML / JSON” button and copy and paste this deployment from my GitHub repo. Click the Create button on the bottom right and ensure “Process the Template” is checked. Click Continue to get a listing of parameters. I will go into more detail later on these settings of saving data for the extensions (plugins), logs, temp space as well as the PostgreSQL database space. You can adjust the space if you wish or just leave the defaults. I usually leave the database password field blank and it generates its own when I am doing local development. When all is ready click the Create button and then the Close button and you will see a BUNCH of things were created. (Note the default SonarQube login is also admin/admin. If you keep this up you will want to change it OR link in oAuth, GitHub login, or Keycloak.)
What did we just do? Well we create a pod with a PostgreSQL image that when run exposes port 5432 internally to the project. We created a pod with a SonarQube 7.4-community image that when run exposes port 9000 through the https://sonarqube-sonarqube.x.x.x.x route. We have a database connection from SonarQube to PostgreSQL. And we have 5 areas of storage setup to persist data for these containers that are run: database data, SonarQube data, SonarQube extensions/plugins, SonarQube logs, and SonarQube temp space. Do we need all of these? Maybe not if you want to write into the container and not keep it if it restarts. I do not like doing that. So I do it this way. Feel free to use and adjust to your will.
Let’s Dive In!
To get more familiar with what our YAML file actually did we need to explore a little. We setup 2 deployments inside our project, one for each application. One application is SonarQube itself and we are using the image from DockerHub for that. The other application is PostgreSQL and OpenShift comes with that image already. So we just used it. If you click the Applications menu on the left and then Deployments you can see the 2 deployments we have. Click further on the links to see what each one has setup. For each deployment OpenShift will list #1, #2, #3 for the number of the deployment you have running. We just did this so you should see the #1 hyperlinked. Click on it to get something like the below image.
What you can see from the highlighted region are those storage listings, persistent volumes and persistent volume claims in Minishift language. This is telling OpenShift that for those areas of my container running (i.e. /opt/sonarqube/extensions) I want you to save that data in OpenShift to persist it. And as the container comes up or is redeployed mount this path inside the container for reuse. I am simplifying it however that is the gist of what this is doing. You also can see these Mounts going against the Storage listing under the Storage menu on the left. I tried to match the names to have them make sense for you.
Log into SonarQube
Go back to the Overview section of your project and you will see the https://sonarqube-sonarqube.x.x.x listing. This is the Route exposing a URL to the internal SonarQube container running. We only have a route for SonarQube. We do not need an external route for PostgreSQL as only SonarQube has to talk to it. Click that link and log in with admin/admin to ensure you can get to SonarQube. If it starts a tutorial click Skip this tutorial. You should get into SonarQube and see a screen like below. Now get to work!
Use Jenkins in projects to scan code with SonarQube
Having SonarQube is great and all only if you use it. I have an example microservice API project in dotnet core 2.1 that you could put into a brand new project and then use its deployment file to deploy 3 pods: Jenkins, the database, and the API. Then log into Jenkins, approve the OpenShift login, and see how Jenkins works within OpenShift. For SonarQube to work you need to add the SonarQube plugin on the Manage Jenkins → Manage Plugins page and restart. Then go into the Manage Jenkins → Configure System and setup the SonarQube plugin with the name if the server (i.e. SonarQube-Server), the internal-to-Openshift URL (i.e. http://sonarqube.sonarqube.svc), and a generated token from your account page so you can push scan results from the Jenkins process. You also could fork this project linked above and play around to get more familiar. The best way to learn is to do!
The steps on how to use SonarQube with Jenkins are here and are also all over Google.com and StackOverflow.com as well. To use that project linked above you have to load up some Jenkins slave images and update your Jenkinsfile to use them.
Advanced: .NET Core Sonar Scanner Jenkins Slave
There is a .Net Core SonarQube Scanner Jenkins slave image on my other repo that you can import by using the YAML files and importing into the ‘openshift’ project in OpenShift. You can use this project here to create in OpenShift to test it out. The Jenkins slave setup in the Jenkins Configure System screen will need to match the name of the labels in the Jenkinsfile. If you have NO IDEA what I am talking about do not worry. I go into that in a third post that is related to this. For now get used to SonarQube and see what you can do! And look at the other blog post.