Setting Up a Private CI/CD Pipeline in Azure—Part 4

Listen to this article:
0:00
0:00

Note: This article was adapted from content originally written on October 19th, 2017, titled “Setting up a Private CI/CD Solution in Azure.” It has been simplified and split into four parts for easier reading.

Part 4: Jenkins Configuration and Complete Workflow

Key Takeaways

  • This article concludes the series on setting up a private CI/CD solution in Azure, focusing on Jenkins configuration and workflow.
  • Readers learn to configure Jenkins with Blue Ocean, integrate with GitLab, and set up ephemeral build agents for dynamic builds.
  • The complete development workflow includes feature branch creation, merge requests, automated CI pipelines, and deployment processes.
  • Best practices emphasize complete privacy, high availability, scalability, modern workflows, and full control over the CI/CD infrastructure.
  • The article encourages enhancements such as SonarQube for code quality, security tools, artifact management, and advanced container orchestration with Kubernetes.

In this final part, we’ll configure Jenkins with Blue Ocean for modern CI/CD pipelines, set up ephemeral build agents, and walk through the complete development workflow from code commit to deployment.

Jenkins Configuration

Deploy Jenkins Master

First, create the Jenkins stack with Blue Ocean and essential plugins:

Initial Jenkins Setup

  1. Get the initial admin password:
  2. Access Jenkins at http://jenkins.example.com
  3. Enter the initial admin password
  4. Install suggested plugins plus:
    • GitLab Plugin
    • Docker Pipeline
    • Blue Ocean
    • Pipeline Stage View
    • Yet Another Docker Plugin (YADP)
  5. Create an admin user account
  6. Configure Jenkins URL: http://jenkins.example.com

Configure GitLab Integration

Set up the connection between Jenkins and GitLab:

  1. In GitLab:
    • Navigate to Admin Area → Applications
    • Create new application:
      • Name: Jenkins
      • Redirect URI: http://jenkins.example.com/securityRealm/finishLogin
      • Scopes: api, read_user, read_repository
    • Save the Application ID and Secret
  2. In Jenkins:
    • Navigate to Manage Jenkins → Configure Global Security
    • Under Security Realm, select “GitLab”
    • Configure:
      • GitLab Web URI: http://gitlab.example.com
      • Application ID: [from GitLab]
      • Application Secret: [from GitLab]
  3. Create GitLab API Token:
    • In GitLab, go to User Settings → Access Tokens
    • Create token with API scope
    • In Jenkins, go to Credentials → System → Global credentials
    • Add credentials → GitLab API token

Configure Ephemeral Build Agents

Set up the Yet Another Docker Plugin (YADP) for dynamic build agents:

  1. Navigate to Manage Jenkins → Configure System
  2. Under the Cloud section, add new cloud → Docker
  3. Configure Docker cloud for each worker node:

For each Docker cloud, add a Docker Agent Template:

Pipeline Configuration

Create Sample Pipeline Project

Let’s create a sample Spring Boot project to demonstrate the complete workflow:

  1. In GitLab, create a new project:
    • Name: spring-boot-demo
    • Visibility: Private
    • Initialize with README
  2. Add project files:

Create Jenkins Pipeline Job

  1. In Jenkins, click “New Item”
  2. Name: spring-boot-demo
  3. Type: Multibranch Pipeline
  4. Configure:
    • Branch Sources → Add source → Git
    • Project Repository: http://gitlab.example.com/your-group/spring-boot-demo.git
    • Credentials: [GitLab credentials]
    • Build Configuration → Script Path: Jenkinsfile
  5. Save and scan repository

Complete Development Workflow

Now let’s walk through the complete development workflow that brings everything together:

Step 1: Developer Creates Feature Branch

Step 2: Create Merge Request

  1. Navigate to your fork in GitLab
  2. Click “Create Merge Request”
  3. Configure:
    • Source branch: feature/add-new-endpoint
    • Target branch: develop (upstream)
    • Title: “Add new feature endpoint”
    • Description: Describe the changes
    • Assign reviewers
  4. Submit merge request

Step 3: Automated CI Pipeline Triggers

When the merge request is created, Jenkins automatically:

  1. Detects the merge request via GitLab webhook
  2. Spins up an ephemeral build agent
  3. Checks out the code
  4. Builds the Docker image
  5. Runs tests
  6. Reports status back to GitLab
Pipeline Status in GitLab
GitLab will show the pipeline status directly in the merge request:
  • ✅ Pipeline passed – Ready to merge
  • ❌ Pipeline failed – Review logs and fix issues
  • 🔄 Pipeline running – Wait for completion

Step 4: Code Review and Merge

Once the pipeline passes and code review is complete:

  1. The reviewer approves the merge request
  2. Click the “Merge” button in GitLab
  3. Code is merged into the develop branch
  4. Jenkins automatically:
    • Builds the updated develop branch
    • Pushes image to Docker Registry
    • Deploys to staging environment

Step 5: Promote to Production

Advanced Pipeline Features

Load Balancing Build Servers

The pipeline intelligently distributes builds across available workers:

Blue Ocean Interface

Access the modern Blue Ocean interface for better pipeline visualization:

  1. Navigate to http://jenkins.example.com/blue
  2. Features include:
    • Visual pipeline editor
    • Real-time log streaming
    • Branch and pull request visualization
    • Pipeline analytics and trends

Monitoring and Alerting

Set up notifications for pipeline events:

Troubleshooting Common Issues

IssueSolution
Jenkins can’t connect to GitLabVerify network connectivity and DNS resolution. Check GitLab API token permissions.
Docker commands fail in the pipelineEnsure Docker socket is mounted and the agent has proper permissions.
Registry push failsVerify registry certificates are installed on all nodes. Check credentials.
Build agents not startingCheck the Docker daemon on worker nodes. Verify YADP configuration.
Services unreachableVerify load balancer health probes. Check network security groups.

Best Practices

  1. Security:
    • Regularly update all components
    • Use secrets management for credentials
    • Implement RBAC in Jenkins and GitLab
    • Enable audit logging
  2. Performance:
    • Use Docker layer caching
    • Implement parallel stages in pipelines
    • Clean up old images and containers regularly
    • Monitor resource usage
  3. Reliability:
    • Implement health checks for all services
    • Set up automated backups
    • Use version tags for production deployments
    • Maintain staging environment parity with production
  4. Development Workflow:
    • Enforce branch protection rules
    • Require code reviews for merges
    • Automate as much testing as possible
    • Keep pipelines fast (< 10 minutes ideally)

Conclusion

Congratulations! You’ve successfully built a comprehensive, private CI/CD solution in Azure. This infrastructure provides your team with:

  • Complete Privacy: All components run within your private network, accessible only via VPN
  • High Availability: Clustered services ensure continuous operation
  • Scalability: Easy to add more build capacity by adding worker nodes
  • Modern Workflow: Git-based development with automated testing and deployment
  • Full Control: Complete ownership of your CI/CD infrastructure

This solution serves as a solid foundation that can be adapted to meet your specific needs. Consider these potential enhancements:

  • Add SonarQube for code quality analysis
  • Integrate security scanning tools
  • Implement artifact management with Nexus or Artifactory
  • Add Kubernetes for more advanced container orchestration
  • Integrate monitoring with Prometheus and Grafana

The beauty of this setup is that once you see its benefits firsthand, you’ll never look back. The investment in setting up a proper CI/CD pipeline pays dividends in improved code quality, faster delivery times, and happier development teams.

Additional Resources


This is Part 4 of a 4-part series on setting up a private CI/CD solution in Azure.

Thank you for following along with this series. You are welcome to adapt this solution to meet your needs, and don’t hesitate to provide feedback or share your improvements!

Table of Contents
Scroll to Top