Connecting Jenkins CI to VM-Based Application

Published Sep 09, 2017
Connecting Jenkins CI to VM-Based Application

Original from

At HotelQuickly, we embrace micro-services architecture. Many applications are small, light-weight and container-based. Let’s call it a Modern-System. These applications are currently running on Google Container Engine ( Kubernetes Cluster).

Kubernetes console UI for monitoring kube-nodes and applications

Unfortunately, there are some of old applications that are not container-based yet. These are monolithic application, written by Nette PHP Framework. It was designed to run on virtual machines autoscale group behind load balance. Let’s call it Legacy-System.

VM-Based Applications are running on autoscale instance group behind GCP Load Balance.

This article will mainly focus on the development flow & deployment flow of Legacy-System.

Previous Development Flow

Earlier, when developer finish their coding part, like any other organization, developer then push their commit to remote branch. In our case, we use GitHub as our remote code repository. This commit push then trigger Jenkins CI to build a job. We use Jenkins Pipeline (Jenkinsfile) for telling Jenkins what to do next. Mainly, it will run the test and send build status back to GitHub so developer can notice whether the test is pass or not. This was our flow during development phase.

Earlier flow during DEVELOPMENT PHASE.

Previous Deployment Flow

When everything goes well, developer then go to #deployment channel in Slack which has hubot integrated named @wall-e. And developer can send the command to @wall-e, so he can deploy the code to production via ansible-playbook to production nodes. This was our flow during deployment phase.

Earlier flow during DEPLOYMENT PHASE

So what’s the problem ?

With previous flow, it create couple of problems like following…

  • Not standard, in HQ we embrace standard.
  • Developer can push test failed to production.
  • Cannot rollback easily.
  • Spin-up time of scaling up node took quite long (because it require provisioning from the based image)

We addressed these problem and we decide to fix it by unified the flow of deployment with Jenkins CI

Proposed Deployment Flow

As in above diagram, we make Jenkins itself to do the deployment on behalf of developer. Jenkins Pipeline will then check the test case whether it’s pass or not. Only commit that pass the test case then will continue the deployment flow. Which then will run Packer to build the image that provisioning by ansible-playbook.

After successful building image, it will tell GCP Instance Group by rolling update to latest image via gcloud SDK cli. (This is beta feature, see also here)

Put it all together, here is the full flow start from development phase until successful deployment.

Problem solved

These flow did fix all the problem we tell earlier. It’s more standard. Developer cannot deploy test failed commit to production. Rollback can be done easily because we have last application version image. And spin-up time is really fast because no provisioning is required when autoscale do scaling up node, just pull the image.

Instead of wall-e, we introduced BB-8 to inform developer that the deployment is waiting for their interaction.

Feed Forward

Right after I finished this blog, there is some comment and ask me to check out. It’s a google product and it’s opensource! How cool is that! I took a quick look and understand that this is a tool that focusing the CD Part (Continuous Deployment). They offer Blue/Green Deployment and Rollback feature, out-of-the-box!… Check this podcast from the maintainers of this cool product here.

Personally, I have never test this yet. But I believe it’s really cool one. If anybody have test it out, please don’t forget to share it. I would love to hear from you. Also, for the CI part, please check Container Registry out. I’ve heard that some company use this as a replacement of Jenkins. 😃

Discover and read more posts from Chainarong Tangsurakit (Por)
get started