Important
- Initial Generation: Originally generated by Gemini 3.7 Flash with Antigravity.
- Review & Production Hardening: Audited, remediated, and verified for enterprise readiness using Gemini 3.8 Flash with Antigravity.
- Testing Status: This repository serves as an architectural reference blueprint, educational design pattern, and foundational boilerplate. Platform engineers must review and validate all cluster endpoints, secrets, and TLS certificates prior to live production deployment.
Important
This platform operates in a tightly integrated multi-repository GitOps ecosystem:
- π Centralized Governance & Configuration SSOT:
nubenetes/jenkins-git-parameter-global-varsβ Master repository containing cluster topologies, environment overlays, application inventory, and dynamicgitParameterdropdown targets. - π CI/CD Platform Orchestrator (This Repository):
nubenetes/jenkins-git-parameterβ Infrastructure-as-Code, JCasC, Job DSL, Jenkinsfiles, OpenTelemetry, Grafana 13.2.0, and ArgoCD 3.5 manifests. - β Workload Reference Microservice:
nubenetes/jhipster-microserviceβ Java 21 / Spring Boot 3 cloud-native microservice with OpenTelemetry and Prometheus integration.
- Executive Summary & Architecture Overview
- In-Depth Architectural Analysis & Design Decisions
- 1. Multi-Repository Git Parameter Investigation: Two Architectural Patterns
- The Core Problem: Why Standard Pipelines Fail with Multiple Git Repositories
- Master Seed Job & JCasC Automation Architecture
- Pattern 1: Dual Git Parameter Dropdowns in a Single Pipeline (Multi-Remote SCM)
- Pattern 2: Decoupled Two-Pipeline Architecture (CI -> CD Hand-off) [RECOMMENDED]
- When to Use Each Pattern: Environment & Persona Decision Matrix
- Coexistence Strategy: Combining Pattern 1 (Inner-Loop) & Pattern 2 (Outer-Loop) in Development
- 2. Job DSL + Declarative Pipelines vs. Monolithic Shared Libraries
- 3. OpenShift 4.20+ Security & Ephemeral Kubernetes Agents
- 4. ArgoCD 3.5 Integration & Multi-Cluster Promotion
- 5. Full-Stack Observability: OpenTelemetry, Prometheus & Grafana 13.2.0 (ArgoCD GitOps Managed)
- 6. Centralized Configuration Architecture: config/environments.env vs jenkins-git-parameter-global-vars
- 1. Multi-Repository Git Parameter Investigation: Two Architectural Patterns
- Repository Structure
- Quick Start: 1-Click Automated Deployment
- Enterprise Production Hardening & Advanced Best Practices
- 1. Supply Chain Security: Cosign Image Signing & SBOM Attestation (SLSA 3)
- 2. Zero-Trust Secret Management: External Secrets Operator (ESO) + HashiCorp Vault
- 3. Dynamic Ephemeral PR Preview Environments with ArgoCD ApplicationSet
- 4. Progressive Delivery with Argo Rollouts (Metric-Driven Canary)
- 5. Automated Credential Rotation: GitHub App Authentication via JCasC
- Strategic Roadmap: Impact vs. Implementation Effort
- Decommissioning & Reinstallation
- Video Walkthroughs & Architecture References (YouTube)
- References & Evidence Links
This repository provides an enterprise-grade, end-to-end Infrastructure as Code (IaC) blueprint and GitOps orchestration engine hosted on Red Hat OpenShift Container Platform (OCP) 4.20+.
The solution addresses a core enterprise challenge: how to build, govern, promote, and release multi-repository cloud-native microservices across 3 distinct OpenShift clusters (DEV, STAGING, PROD) while leveraging dynamic Git Parameter selection, Declarative Pipelines as Code, ArgoCD 3.5 GitOps synchronization, and unified OpenTelemetry observability.
πΊοΈ Click to expand: End-to-End Multi-Cluster Platform Topology Diagram
flowchart TB
subgraph DeveloperWorkspace["1. Developer & External Systems"]
Dev["π©βπ» Developer / Ops"]
Backstage["ποΈ Backstage IDP<br/>(Software Catalog)"]
ITSM["π« Jira Service Mgmt<br/>& ServiceNow CMDB"]
end
subgraph OCP_DEV["OpenShift Cluster 1: DEV (Control Plane & Workloads)"]
direction TB
subgraph JenkinsPlatform["Jenkins Controller (JCasC & Job DSL)"]
Master["Jenkins Controller<br/>(2.492.2 LTS)"]
Seed["00-Seed-Job<br/>Orchestrator"]
CIJob["01-CI-Build-Pipeline<br/>(Git Param: App Repo)"]
CDJob["02-CD-Release-Orchestrator<br/>(Git Param: Global Vars)"]
end
subgraph Agents["Ephemeral Kubernetes Agent Pods"]
MavenAgent["maven-jdk21 Agent<br/>(Build & Test)"]
GitOpsAgent["argocd-gitops Agent<br/>(Skopeo & Argo CLI)"]
end
subgraph OCPDevRegistry["OCP DEV Internal Registry"]
DevReg["image-registry:5000<br/>nubenetes-dev-apps"]
end
subgraph ArgoCDMaster["ArgoCD 3.5 Control Plane"]
ArgoServer["ArgoCD Server &<br/>ApplicationSets"]
end
subgraph ObservabilityStack["Full-Stack Observability"]
OTel["OpenTelemetry<br/>Collector (OTLP)"]
Prom["Prometheus<br/>Server"]
Grafana["Grafana<br/>Dashboards"]
end
DevApps["DEV Workloads<br/>(nubenetes-dev-apps)"]
end
subgraph OCP_STG["OpenShift Cluster 2: STAGING (UAT)"]
StgReg["OCP Staging Registry"]
StgApps["Staging Workloads<br/>(nubenetes-staging-apps)"]
end
subgraph OCP_PRD["OpenShift Cluster 3: PROD (High Availability)"]
PrdReg["OCP Prod Registry"]
PrdApps["Production Workloads<br/>(nubenetes-prod-apps)"]
end
Dev -->|Selects Branch or Tag| CIJob
Dev -->|Selects Config Version| CDJob
Backstage -->|REST API Trigger| CDJob
ITSM -->|Webhook Dispatch| CDJob
CIJob -->|Launches| MavenAgent
MavenAgent -->|Pushes Image| DevReg
CIJob -->|Triggers Downstream| CDJob
CDJob -->|Launches| GitOpsAgent
GitOpsAgent -->|Skopeo Copy| StgReg
GitOpsAgent -->|Skopeo Copy| PrdReg
GitOpsAgent -->|Sync & Health Check| ArgoServer
ArgoServer -->|GitOps Deploy| DevApps
ArgoServer -->|GitOps Deploy| StgApps
ArgoServer -->|Sync Waves Deploy| PrdApps
Master -.->|OTLP Traces| OTel
OTel -.->|Forward Spans| Grafana
Master -.->|Metrics Export| Prom
Prom -.->|Metrics Scrape| Grafana
- Developer & External Ingestion: Developers, Backstage IDP, and Jira/ServiceNow trigger parameterized builds specifying application and global configuration revisions.
- Master Controller (OpenShift Cluster 1): Jenkins JCasC boots the master Seed Job and materializes isolated CI and CD pipelines via Job DSL.
- Pipeline 01 (CI Build): Ephemeral
maven-jdk21agents compile source code, execute tests, push container images to the internal DEV registry, and trigger downstream CD. - Pipeline 02 (CD Release Orchestration): Ephemeral
gitops-toolsagents promote images across registries using Skopeo and executeargoAppSyncto synchronize DEV, STAGING, and PROD clusters. - Observability & Tracing: OpenTelemetry collector exports build spans to Grafana, while Prometheus exports metrics for real-time monitoring.
π‘ Architectural Summary & Conclusion: This topology decouples build creation from release promotion while keeping release orchestration parameterized inside Jenkins. By isolating CI agents from CD promotion agents and automating ArgoCD synchronizations, engineering teams gain multi-cluster delivery with centralized auditing.
In cloud-native architectures, applications separate source code (app-repo) from centralized environmental configuration, cluster definitions, and Helm values (jenkins-git-parameter-global-vars).
When engineering teams attempt to introduce multiple gitParameter dropdowns into a single Jenkins Pipeline, they almost universally encounter a hard blocker where GitSCM appears to only support one repository, or secondary dropdowns fail with No GIT repository configured in SCM configuration.
β οΈ Click to expand: Jenkins SCM Lifecycle & Pre-Execution Blindspot Diagram
flowchart TB
subgraph UI_Phase["1. Pre-Execution Phase (Master)"]
direction TB
User["π€ User opens<br/>Build UI Form"]
Master["βοΈ Master reads<br/>Job XML SCM"]
GitParam["π git-parameter<br/>queries remote refs"]
Dropdown["π Renders Dropdown<br/>for Primary Repo"]
User --> Master --> GitParam --> Dropdown
end
subgraph Runtime_Phase["2. Runtime Execution Phase (Agent)"]
direction TB
AllocAgent["βΈοΈ Ephemeral Agent<br/>Pod Allocated"]
RunStage["π¦ Pipeline Stage:<br/>checkout(repo-2)"]
AllocAgent --> RunStage
end
Gap["β οΈ SCM Blindspot:<br/>Dynamic stage checkouts<br/>run during build and are<br/>invisible at UI render"]
Dropdown -.-> Gap
Gap -.-> RunStage
- Pre-Execution Master Phase: The Jenkins Master renders
gitParameterdropdowns by querying only repositories statically declared in the Jenkins Job XML. - Runtime Agent Execution: Secondary checkouts executed dynamically inside pipeline stages run on ephemeral agents long after the parameter form has been submitted.
- The Blindspot: The Master cannot discover secondary stage checkouts ahead of time, causing secondary dropdowns to fail or duplicate primary repository branches.
π‘ Architectural Summary & Conclusion: Understanding the pre-execution vs. runtime paradox is essential when designing multi-repository pipelines in Jenkins. Pattern 1 (Multi-Remote SCM) solves this statically in Job DSL, while Pattern 2 (Decoupled Hand-off) eliminates the conflict by separating pipelines completely.
- The Pre-Execution vs. Runtime Lifecycle Paradox:
Jenkins calculates and renders job parameters in the user's browser before allocating an agent, before checking out the source tree, and before executing any
Jenkinsfilestage. Whengit-parameterinspects the job, it only knows about Git repositories defined statically in the Jenkins Master Job XML configuration. - The SCM Binding Constraint (Dynamic Checkouts are Invisible):
If a
Jenkinsfileclones a secondary repository dynamically inside a stage (steps { checkout([$class: 'GitSCM', userRemoteConfigs: [[url: '...']]]) }), the Jenkins Master cannot discover or query this secondary repository at parameter render time. Consequently, the secondgitParameterdropdown fails or mistakenly duplicates the branches of the primary repository. - Pipeline (
cpsScm) GUI Limitations & Deprecation of Multiple SCMs Plugin: In legacy Jenkins Freestyle jobs, the community used the Multiple SCMs Plugin. However, this plugin was never ported or supported in Declarative Pipelines (cpsScm). The standard Jenkins Pipeline Web UI only allows configuring a single SCM Git block with one repository URL.
To solve this challenge, this repository implements and delivers BOTH architectural patterns as production-ready code:
The entire platform is self-bootstrapping and self-healing using Jenkins Configuration as Code (JCasC) combined with the Job DSL Plugin:
βοΈ Click to expand: Seed Job & Job DSL Pipeline Provisioning Flow Diagram
flowchart TB
subgraph JCasC_Phase ["1. Controller Bootstrap (JCasC)"]
direction TB
JCasC["jenkins-jcasc.yaml<br/>(Master Config)"] -->|"Registers"| SeedJob["00-Seed-Job<br/>(Platform Seed)"]
end
subgraph SCM_Phase ["2. SCM Synchronization"]
direction TB
GitRepo["Git Repository<br/>(Platform Code)"]
SeedJob -->|"Polls H/15 * * * *"| GitRepo
SeedJob -->|"Evaluates"| JobDSLFiles["Target Scripts<br/>(jobdsl/*.groovy)"]
end
subgraph Materialization ["3. Pipeline Materialization"]
direction TB
JobDSLFiles -->|"seed-job.groovy"| Folders["Creates Folders:<br/>β’ CI Pipelines<br/>β’ CD Orchestrators<br/>β’ Maintenance"]
JobDSLFiles -->|"pipelines-ci.groovy"| CIPipelines["Generates CI:<br/>β’ jhipster-ci<br/>β’ angular-ci"]
JobDSLFiles -->|"pipelines-cd.groovy"| CDPipelines["Generates CD:<br/>β’ release-orchestrator<br/>β’ hotfix-deploy"]
end
Folders -.->|"Parent"| CIPipelines
Folders -.->|"Parent"| CDPipelines
- JCasC Bootstrap: Master controller starts up and executes JCasC to register
00-Seed-Job-Platform-Orchestrator. - Dynamic SCM Polling: The Seed Job polls this repository every 15 minutes for changes in
jobdsl/*.groovy. - Separation of Concerns:
seed-job.groovycreates folder taxonomies,pipelines-ci.groovymaterializes CI jobs, andpipelines-cd.groovyprovisions release orchestrators. - Automated Lifecycle Pruning:
removedJobAction('DELETE')automatically purges decommissioned pipelines without touching master configuration.
π‘ Architectural Summary & Conclusion: Combining JCasC with Job DSL treats the entire Jenkins pipeline hierarchy as version-controlled code. Teams can onboard new microservices or modify pipeline definitions via Git commits without manual controller restarts or UI drift.
In enterprise Jenkins-as-Code implementations, we deliberately apply the Separation of Concerns (SoC) principle:
- Taxonomy & Hierarchy Initialization:
jobdsl/seed-job.groovyacts as the root taxonomy initializer. It creates and configures the top-level folder containers (01-CI-Build-Pipelines,02-CD-Release-Orchestrators, and03-Platform-Maintenance) along with their descriptions and metadata. - Decoupled Pipeline Generation Logic: The application CI pipelines (
jobdsl/pipelines-ci.groovy) and CD release orchestrators (jobdsl/pipelines-cd.groovy) contain iterative business logic (looping over theappsinventory, configuring multi-remote refspecs, Git Parameter dropdowns, log rotation, and OpenTelemetry spans). Keeping folder declarations separate prevents monolithic scripts and enables modular additions of new business domains.
While folders can technically be defined directly in jenkins-jcasc.yaml, managing them through Job DSL is the recommended SRE practice for multi-tenant platforms:
| Architectural Metric | Static JCasC Management (jenkins-jcasc.yaml) |
Dynamic Job DSL Management (jobdsl/seed-job.groovy) |
|---|---|---|
| Creation Lifecycle | Executed strictly upon Jenkins Controller startup or manual JCasC reload. | Evaluated continuously on every Seed Job execution (automated SCM polling or manual trigger). |
| Orphaned Item Pruning | Does not automatically purge folders or child jobs if deleted from configuration. | Automated Pruning: removedJobAction('DELETE') and removedViewAction('DELETE') cleanly destroy removed jobs/folders. |
| Configuration Ownership | Belongs to Controller System Configuration (Platform Admin scope). | Belongs to Version-Controlled GitOps Code (Developer / Application Domain scope). |
| Zero-Downtime Evolution | Renaming or restructuring folders requires reloading master JCasC. | Restructuring folders is applied dynamically via Git commit without touching master configuration. |
- JCasC Master Bootstrap:
When the Jenkins container starts,jcasc/jenkins-jcasc.yamlconfigures the master Seed Job:jobs: - script: | job('00-Seed-Job-Platform-Orchestrator') { description('Master Seed Job provisioning CI/CD Pipelines as Code.') scm { git { remote { url('https://github.com/nubenetes/jenkins-git-parameter.git') } branch('*/main') } } steps { jobDsl { targets('jobdsl/seed-job.groovy\njobdsl/pipelines-ci.groovy\njobdsl/pipelines-cd.groovy') removedJobAction('DELETE') removedViewAction('DELETE') lookupStrategy('JENKINS_ROOT') } } triggers { scm('H/15 * * * *') } }
lookupStrategy('JENKINS_ROOT')Context Resolution:
By settinglookupStrategy('JENKINS_ROOT'), Job DSL resolves all relative job paths from the root of Jenkins. This allowspipelines-ci.groovyto target"01-CI-Build-Pipelines/${app.name}-ci-build"and nest jobs into the folders previously created byseed-job.groovy.- Automated Drift Correction via SCM Polling:
The triggerscm('H/15 * * * *')polls this repository every 15 minutes. When an engineer adds a new microservice to thedef apps = [...]inventory inpipelines-ci.groovyand pushes tomain, the Seed Job automatically generates the new CI/CD pipelines in Jenkins with zero manual UI configuration.
Implemented in: jobdsl/pipelines-ci.groovy (*-ci-dual-dropdown) and jenkinsfiles/ci/Jenkinsfile.app-java-maven-dual-dropdown
Rather than attempting to define multiple scm blocks (which Jenkins rejects), Job DSL configures a single GitSCM definition containing multiple named Git remote blocks with dedicated refspecs. The Git Parameter plugin can then target each remote independently using useRepository matching on the remote identifier or URL regex:
// Job DSL Implementation: Multi-Remote SCM with 2 Dynamic Dropdowns
pipelineJob("01-CI-Build-Pipelines/jhipster-microservice-ci-dual-dropdown") {
parameters {
// Dropdown 1: Application Repository (Branches & Tags)
gitParameterDefinition {
name('APP_GIT_REVISION')
type('PT_BRANCH_TAG')
defaultValue('main')
useRepository('origin-app') // Targets Remote 1
sortMode('DESCENDING_SMART')
}
// Dropdown 2: Global Variables Repository (Branches & Tags)
gitParameterDefinition {
name('GLOBAL_VARS_REVISION')
type('PT_BRANCH_TAG')
defaultValue('main')
useRepository('origin-vars') // Targets Remote 2
sortMode('DESCENDING_SMART')
}
}
definition {
cpsScm {
scm {
git {
remote {
name('origin-app')
url('https://github.com/nubenetes/jhipster-microservice.git')
refspec('+refs/heads/*:refs/remotes/origin-app/* +refs/tags/*:refs/remotes/origin-app/tags/*')
}
remote {
name('origin-vars')
url('https://github.com/nubenetes/jenkins-git-parameter-global-vars.git')
refspec('+refs/heads/*:refs/remotes/origin-vars/* +refs/tags/*:refs/remotes/origin-vars/tags/*')
}
branch('origin-app/main')
}
}
scriptPath('jenkinsfiles/ci/Jenkinsfile.app-java-maven-dual-dropdown')
}
}
}Hidden Pitfalls, Failure Modes & Operational Drawbacks
While Pattern 1 successfully renders two dropdowns on a single screen, enterprise teams should be aware of several critical technical caveats:
| Pitfall / Caveat | Technical Root Cause | Operational Impact |
|---|---|---|
| Branch & Tag Namespace Collisions | Both repositories frequently have identical branch/tag names (e.g. main, release-1.0). |
Without strict custom refspecs (refs/remotes/origin-app/* vs refs/remotes/origin-vars/*), Git checkout becomes non-deterministic and can check out the wrong commit. |
| Misleading Workspace State | Jenkins' initial cpsScm checkout only materializes one branch into the workspace directory. |
Even if the user selected two branches, the files of the second repository are not present in the workspace. The Jenkinsfile must still execute an explicit secondary checkout into a subfolder. |
| Jenkins Master Performance Overhead | On every page load of "Build with Parameters", the Master executes synchronous git ls-remote network calls to both Git repositories. |
If either repository has high latency, rate limits, or network degradation, the Jenkins UI blocks, freezes, or times out. |
useRepository Regex Fragility |
useRepository relies on regular expression matching against UserRemoteConfig repository URLs. |
Known bugs (e.g. JENKINS-75780) can cause dropdowns to cross-contaminate or fail if repositories share common domains or credentials. |
Implemented in: jobdsl/pipelines-ci.groovy (*-ci-build), jenkinsfiles/ci/Jenkinsfile.app-java-maven, jobdsl/pipelines-cd.groovy (multi-cluster-release-orchestrator), and jenkinsfiles/cd/Jenkinsfile.release-orchestrator
Separates artifact creation from release promotion. Pipeline 01 focuses on building the application code with its own Git Parameter dropdown, while Pipeline 02 is bound to jenkins-git-parameter-global-vars with its own Git Parameter dropdown for multi-cluster release orchestration.
Decoupling CI from CD solves the limitations of Pattern 1 cleanly by aligning with core cloud-native architecture principles:
-
Single Responsibility Principle (SRP):
- Pipeline 01 (CI) is strictly responsible for code quality, unit testing, static analysis, and packaging container images.
- Pipeline 02 (CD) is strictly responsible for environment state, configuration management, deployment orchestration, and GitOps synchronization.
-
Artifact Immutability ("Build Once, Deploy Anywhere"):
- In Pattern 1, redeploying or promoting to another environment forces a recompilation of the application source code.
- In Pattern 2, the container image is built once in CI, tagged immutably (e.g.
2.1.0-42-a1b2c3d), and promoted across DEV$\rightarrow$ STAGING$\rightarrow$ PROD by updating GitOps manifests without rebuilding.
-
Zero SCM Hacks & Zero Namespace Collision Risk:
- Each pipeline uses standard, isolated SCM bindings. No multi-remote refspec gymnastics or fragile regex matching.
-
Universal REST API & ITSM Interoperability:
- Pipeline 02 can be triggered downstream by Pipeline 01, but can also be invoked directly by Jira Service Management Forms, ServiceNow Change Requests, or Backstage Developer Portals via standard parameterized REST API calls.
A. Job DSL Implementation (jobdsl/pipelines-ci.groovy):
Configures a dedicated gitParameterDefinition targeting the application repository, alongside parameters to configure the downstream release trigger:
// Job DSL Implementation: Decoupled CI Build Pipeline with Application Git Parameter
pipelineJob("01-CI-Build-Pipelines/jhipster-microservice-ci-build") {
description('''
<b>[PATTERN 2: Decoupled CI Build Pipeline - Recommended]</b><br/>
Cloud-Native Java 21 / Spring Boot Microservice<br/>
β’ <b>App Revision</b>: Dynamic Git Parameter Dropdown on https://github.com/nubenetes/jhipster-microservice.git<br/>
β’ <b>Global Vars</b>: Passed via parameter to downstream 02-CD-Release-Orchestrator.
'''.stripIndent())
parameters {
// Dropdown: Application Repository (Branches & Tags)
gitParameterDefinition {
name('APP_GIT_REVISION')
type('PT_BRANCH_TAG')
defaultValue('main')
description('Select Application Git Branch/Tag from https://github.com/nubenetes/jhipster-microservice.git')
branchFilter('.*')
tagFilter('*')
sortMode('DESCENDING_SMART')
selectedValue('DEFAULT')
useRepository('https://github.com/nubenetes/jhipster-microservice.git')
quickFilterEnabled(true)
}
booleanParam('TRIGGER_CD_RELEASE', true, 'Automatically trigger downstream CD Release Orchestrator.')
stringParam('GLOBAL_VARS_BRANCH', 'main', 'Global Variables branch to pass to downstream CD Release Orchestrator.')
choiceParam('TARGET_ENVIRONMENT', ['dev', 'staging', 'prod'], 'Initial deployment target environment for downstream CD release.')
}
definition {
cpsScm {
scm {
git {
remote {
url('https://github.com/nubenetes/jenkins-git-parameter.git')
}
branch('*/main')
}
}
scriptPath('jenkinsfiles/ci/Jenkinsfile.app-java-maven')
lightweight(true)
}
}
}B. Declarative Jenkinsfile CI Stage (jenkinsfiles/ci/Jenkinsfile.app-java-maven):
Builds the container image, tags it with an immutable build identifier, and triggers Pipeline 02 passing the configuration branch and artifact metadata:
// Jenkinsfile Stage: Compile, Package Image, and Trigger Downstream CD Orchestrator
stage('Checkout Application Code') {
steps {
script {
checkout([
$class: 'GitSCM',
branches: [[name: "${params.APP_GIT_REVISION}"]],
userRemoteConfigs: [[url: env.APP_REPO_URL]]
])
env.GIT_COMMIT_SHORT = sh(script: 'git rev-parse --short HEAD', returnStdout: true).trim()
env.CALCULATED_TAG = "2.1.0-${BUILD_NUMBER}-${env.GIT_COMMIT_SHORT}"
}
}
}
// ... Compile, Test, Package, and Push Image stages ...
stage('Trigger CD Release Orchestrator') {
when {
expression { return params.TRIGGER_CD_RELEASE == true }
}
steps {
echo "===> Triggering Downstream CD Release Orchestration Pipeline..."
build job: '02-CD-Release-Orchestrators/multi-cluster-release-orchestrator',
parameters: [
string(name: 'GLOBAL_VARS_REVISION', value: params.GLOBAL_VARS_BRANCH ?: 'main'),
string(name: 'APP_NAME', value: env.APP_NAME),
string(name: 'IMAGE_TAG', value: env.CALCULATED_TAG),
string(name: 'TARGET_ENVIRONMENT', value: params.TARGET_ENVIRONMENT ?: 'dev'),
booleanParam(name: 'AUTO_PROMOTE_TO_STAGING', value: true),
booleanParam(name: 'REQUIRE_PROD_APPROVAL', value: true),
string(name: 'TRIGGERED_BY', value: 'CI_PIPELINE'),
string(name: 'CHANGE_REQUEST_ID', value: "CI-AUTO-${BUILD_NUMBER}")
],
wait: false
}
}A. Job DSL Implementation (jobdsl/pipelines-cd.groovy):
Configures a dedicated gitParameterDefinition targeting the centralized jenkins-git-parameter-global-vars configuration repository, exposing promotion flags and token-based REST dispatching:
// Job DSL Implementation: Multi-Cluster CD Release Orchestrator with Global Vars Dropdown
pipelineJob("02-CD-Release-Orchestrators/multi-cluster-release-orchestrator") {
description('''
π <b>Enterprise Multi-Cluster Release & Promotion Orchestrator</b><br/>
Orchestrates promotion across 3 OpenShift clusters (DEV -> STAGING -> PROD) with ArgoCD 3.5.<br/>
β’ Parameterized with <b>Git Parameter</b> on the Global Variables repository.<br/>
β’ Can be triggered manually, by upstream CI build pipelines, or externally via REST API.
'''.stripIndent())
authenticationToken('RELEASE_DISPATCH_TOKEN_2026')
parameters {
// Dropdown: Global Variables & Multi-Cluster Environment Configuration Repo
gitParameterDefinition {
name('GLOBAL_VARS_REVISION')
type('PT_BRANCH_TAG')
defaultValue('main')
description('Select the Git Branch or Tag from Global Configuration (jenkins-git-parameter-global-vars)')
branchFilter('.*')
tagFilter('*')
sortMode('DESCENDING_SMART')
selectedValue('DEFAULT')
useRepository('https://github.com/nubenetes/jenkins-git-parameter-global-vars.git')
quickFilterEnabled(true)
}
choiceParam('APP_NAME', ['jhipster-microservice', 'angular-frontend', 'all-apps'], 'Application to release and promote.')
stringParam('IMAGE_TAG', 'latest', 'Container Image Tag to deploy and promote across OpenShift clusters.')
choiceParam('TARGET_ENVIRONMENT', ['dev', 'staging', 'prod', 'full-promotion-chain'], 'Target environment or full promotional chain.')
booleanParam('AUTO_PROMOTE_TO_STAGING', true, 'Automatically promote image and deploy to OCP STAGING cluster if DEV tests pass.')
booleanParam('REQUIRE_PROD_APPROVAL', true, 'Require interactive human gate approval before deploying to OCP PROD cluster.')
choiceParam('TRIGGERED_BY', ['MANUAL', 'CI_PIPELINE', 'BACKSTAGE_IDP', 'SERVICENOW_ITSM', 'JIRA_CMDB'], 'Caller identity for audit and trace metadata.')
stringParam('CHANGE_REQUEST_ID', 'CHG-DEFAULT-0000', 'ITSM / Jira Change Request ID for production compliance.')
}
definition {
cpsScm {
scm {
git {
remote {
url('https://github.com/nubenetes/jenkins-git-parameter.git')
}
branch('*/main')
}
}
scriptPath('jenkinsfiles/cd/Jenkinsfile.release-orchestrator')
lightweight(true)
}
}
}B. Declarative Jenkinsfile CD Stages (jenkinsfiles/cd/Jenkinsfile.release-orchestrator):
Checks out the selected global variables revision dynamically, updates GitOps environment manifests, triggers ArgoCD syncs, and promotes immutable images across OpenShift clusters:
// Jenkinsfile Stage: Dynamic Global Config Checkout & Multi-Cluster Promotion Flow
stage('Initialize & Resolve Global Configuration') {
steps {
script {
echo "===> Checking out Global Vars Repository at revision: ${params.GLOBAL_VARS_REVISION}"
dir('jenkins-git-parameter-global-vars') {
checkout([
$class: 'GitSCM',
branches: [[name: "${params.GLOBAL_VARS_REVISION}"]],
userRemoteConfigs: [[url: 'https://github.com/nubenetes/jenkins-git-parameter-global-vars.git']]
])
}
}
}
}
stage('Deploy to OCP DEV Cluster') {
when {
expression { return params.TARGET_ENVIRONMENT in ['dev', 'full-promotion-chain', 'staging', 'prod'] }
}
steps {
script {
// Update GitOps manifests in global vars repo & Sync ArgoCD DEV App
gitopsCommit(envName: 'dev', appName: params.APP_NAME, imageTag: params.IMAGE_TAG, configDir: 'jenkins-git-parameter-global-vars')
argoAppSync(appName: "${params.APP_NAME}-dev", targetRevision: params.GLOBAL_VARS_REVISION, server: env.ARGOCD_SERVER)
}
}
}
stage('Promote to OCP STAGING Cluster') {
when {
expression { return params.AUTO_PROMOTE_TO_STAGING == true && params.TARGET_ENVIRONMENT in ['staging', 'full-promotion-chain', 'prod'] }
}
steps {
script {
// Promote immutable image across cluster registries via Skopeo
skopeoPromote(
sourceImage: "${env.DEV_REGISTRY}/${env.DEV_NAMESPACE}/${params.APP_NAME}:${params.IMAGE_TAG}",
destImage: "${env.STAGING_REGISTRY}/${env.STAGING_NAMESPACE}/${params.APP_NAME}:${params.IMAGE_TAG}"
)
gitopsCommit(envName: 'staging', appName: params.APP_NAME, imageTag: params.IMAGE_TAG, configDir: 'jenkins-git-parameter-global-vars')
argoAppSync(appName: "${params.APP_NAME}-staging", targetRevision: params.GLOBAL_VARS_REVISION, server: env.ARGOCD_SERVER)
}
}
}
stage('Promote to OCP PROD Cluster') {
when {
expression { return params.TARGET_ENVIRONMENT in ['prod', 'full-promotion-chain'] }
}
steps {
script {
if (params.REQUIRE_PROD_APPROVAL) {
input message: "Approve deployment of ${params.APP_NAME}:${params.IMAGE_TAG} to OCP PRODUCTION?", submitter: 'release-managers,platform-admins'
}
skopeoPromote(
sourceImage: "${env.STAGING_REGISTRY}/${env.STAGING_NAMESPACE}/${params.APP_NAME}:${params.IMAGE_TAG}",
destImage: "${env.PROD_REGISTRY}/${env.PROD_NAMESPACE}/${params.APP_NAME}:${params.IMAGE_TAG}"
)
gitopsCommit(envName: 'prod', appName: params.APP_NAME, imageTag: params.IMAGE_TAG, configDir: 'jenkins-git-parameter-global-vars')
argoAppSync(appName: "${params.APP_NAME}-prod", targetRevision: params.GLOBAL_VARS_REVISION, server: env.ARGOCD_SERVER)
}
}
}π Click to expand: End-to-End CI/CD Hand-off Sequence Diagram
sequenceDiagram
autonumber
actor Dev as Developer / Operator
participant CI as "01-CI-Build-Pipeline (App Repo)"
participant DevReg as "OCP DEV Registry"
participant CD as "02-CD-Release-Orchestrator (Global Vars)"
participant Skopeo as "Skopeo Image Promotion"
participant StgReg as "OCP STAGING Registry"
participant Argo as "ArgoCD 3.5 GitOps Engine"
participant PrdReg as "OCP PROD Registry"
alt Trigger Path A: Developer CI Dispatch
Dev->>CI: Trigger Build with Git Parameter (Select App Tag/Branch)
CI->>CI: Compile Java 21 / Run Unit Tests / Sonar / Trivy
CI->>DevReg: Build & Push Container Image (e.g. 2.1.0-42-a1b2c3d)
CI->>CD: Trigger Downstream with (IMAGE_TAG, GLOBAL_VARS_REVISION='main')
else Trigger Path B: External API / Backstage / ServiceNow / Jira
Dev->>CD: Direct REST API / UI Trigger with (GLOBAL_VARS_REVISION, IMAGE_TAG)
end
CD->>CD: Checkout jenkins-git-parameter-global-vars @ GLOBAL_VARS_REVISION
CD->>Argo: Update DEV manifests & Sync ArgoCD DEV App
Argo->>Argo: Validate Health on OCP DEV Cluster
opt Auto Promote to STAGING
CD->>Skopeo: Copy Image: OCP DEV Registry -> OCP STAGING Registry
CD->>Argo: Update STAGING manifests & Sync ArgoCD STAGING App
Argo->>Argo: Validate Health & Run Integration Suite
end
opt Production Promotion Gate
CD->>Dev: Interactive Human Approval Gate (Submitter: release-managers)
Dev-->>CD: Approval Granted
CD->>Skopeo: Copy Image: OCP STAGING Registry -> OCP PROD Registry
CD->>Argo: Update PROD manifests & Sync with Sync Waves
Argo->>Argo: Verify Canary / Blue-Green Zero-Downtime Rollout
end
- 1. CI Pipeline Trigger: Developer launches Pipeline 01 (
jhipster-microservice-ci-build) withAPP_GIT_REVISION. - 2. Build & Immutability: Jenkins compiles Java 21 code, executes tests, and pushes image
jhipster-microservice:2.1.0-42. - 3. Downstream Hand-off: Pipeline 01 triggers Pipeline 02 (
multi-cluster-release-orchestrator), passingIMAGE_TAGand environment targets. - 4. Multi-Cluster Promotion: Pipeline 02 copies the image via Skopeo from DEV to STAGING/PROD registries and commits the new tag to
jenkins-git-parameter-global-vars. - 5. GitOps Synchronization: Pipeline 02 invokes
argoAppSync, verifying HTTP 200 health on target OpenShift clusters.
π‘ Architectural Summary & Conclusion: Pattern 2 achieves strict 'Build Once, Deploy Anywhere' artifact immutability. Re-deploying or promoting across environments never recompiles application code, eliminating environment-specific build drift.
A foundational capability of Pattern 2 is the automated downstream linkage between Pipeline 01 (CI Build) and Pipeline 02 (CD Release Orchestrator). When an engineer or external system launches Pipeline 01, they can choose whether and where the resulting immutable artifact should be deployed:
π Click to expand: Downstream Hand-off & Environment Targeting Flow Diagram
flowchart LR
subgraph CIStage["1. Pipeline 01: CI Build"]
direction TB
Dev1["π©βπ» User"] -->|"Selects Branch & Env"| CI["ποΈ 01-CI-Build<br/>β’ Compiles Artifact<br/>β’ Signs Image<br/>β’ Pushes to DEV"]
CI -->|"Trigger CD"| Dispatch["β‘ build job:<br/>02-CD-Orchestrator<br/>Passes: IMAGE_TAG"]
end
subgraph CDStage["2. Pipeline 02: CD Orchestrator"]
direction TB
Dispatch --> CD["π 02-CD-Orchestrator<br/>β’ Resolves vars<br/>β’ Routes by Env"]
CD -->|"env == 'dev'"| DevTarget["βΈοΈ OpenShift DEV<br/>β’ gitopsCommit(dev)<br/>β’ argoAppSync(dev)"]
CD -->|"env == 'staging'"| StgTarget["βΈοΈ OpenShift STAGING<br/>β’ skopeoPromote<br/>β’ argoAppSync(stg)"]
CD -->|"env == 'prod'"| PrdTarget["βΈοΈ OpenShift PROD<br/>β’ Approval Gate<br/>β’ skopeoPromote<br/>β’ argoAppSync(prd)"]
end
- Configured in Job DSL (
jobdsl/pipelines-ci.groovy):TRIGGER_CD_RELEASE(boolean, default:true): Automatically dispatches downstream release.GLOBAL_VARS_BRANCH(string, default:'main'): Global configuration branch passed to Pipeline 02.TARGET_ENVIRONMENT(choice:dev,staging,prod,full-promotion-chain): Initial target environment.
- Trigger Stage in Pipeline 01 (
Jenkinsfile.app-java-maven):stage('Trigger CD Release Orchestrator') { when { expression { return params.TRIGGER_CD_RELEASE == true } } steps { build job: '02-CD-Release-Orchestrators/multi-cluster-release-orchestrator', parameters: [ string(name: 'GLOBAL_VARS_REVISION', value: params.GLOBAL_VARS_BRANCH ?: 'main'), string(name: 'APP_NAME', value: env.APP_NAME), string(name: 'IMAGE_TAG', value: env.CALCULATED_TAG), string(name: 'TARGET_ENVIRONMENT', value: params.TARGET_ENVIRONMENT ?: 'dev'), booleanParam(name: 'AUTO_PROMOTE_TO_STAGING', value: true), booleanParam(name: 'REQUIRE_PROD_APPROVAL', value: true), string(name: 'TRIGGERED_BY', value: 'CI_PIPELINE'), string(name: 'CHANGE_REQUEST_ID', value: "CI-AUTO-${BUILD_NUMBER}") ], wait: false } }
- Environment-Specific Routing in Pipeline 02 (
Jenkinsfile.release-orchestrator):- Target
dev: Updatesdevoverlays and triggersargoAppSyncon OpenShift DEV. - Target
staging: Promotes container image via Skopeo from DEV to STAGING registry, updates manifests, and synchronizes OpenShift STAGING. - Target
prod: Promotes image to PROD registry, pauses at the interactiveProduction Approval Gate(inputstep), and deploys with ArgoCD sync waves on OpenShift PROD.
- Target
π‘ Architectural Summary & Conclusion: This automated linkage guarantees 'Build Once, Deploy Anywhere' artifact immutability. Pipeline 02 never recompiles source codeβit promotes the exact, cryptographically verified container image digest created by Pipeline 01.
| Dimension | Pattern 1: Dual Dropdown (Multi-Remote SCM) | Pattern 2: Decoupled CI |
|---|---|---|
| Primary Use Case | Developer Workspaces & Sandboxes | Enterprise Multi-Cluster Production |
| Target Environments |
dev, feature branches, ephemeral PR preview clusters |
dev staging (UAT) prod
|
| User Persona | Individual Software Engineers & Frontend Developers | Release Managers, QA Leads, Platform Teams, ITSM |
| UI Experience | Single "Build with Parameters" form with 2 live dropdowns | Dedicated CI form for code; Dedicated CD form for release |
| Jenkins Master Overhead | Fetches remote refs from both repos on every page render | SCM queries are isolated to the specific pipeline |
| Branch Collision Risk | Requires strict refspec prefixes (origin-app/* vs origin-vars/*) |
Zero risk; completely isolated Git repositories |
| External Integration | Complex; external callers must know build & compilation parameters |
Simple REST API: Callers only supply IMAGE_TAG & GLOBAL_VARS_REVISION
|
| Promotion & Rollbacks | Rebuilds application code on every run | Promotes existing immutable images without recompiling |
| Governance & SoD | Code committers deploy directly to target cluster | Enforces Segregation of Duties via Jira Forms / CAB |
Can Pattern 1 and Pattern 2 coexist? Yes! Coexistence is the recommended industry standard for separating Inner-Loop (rapid developer experimentation) from Outer-Loop (governed, automated CI/CD release lifecycle).
π§ͺ Click to expand: Inner-Loop (Pattern 1) vs Outer-Loop (Pattern 2) Coexistence Diagram
flowchart TD
subgraph InnerLoop["π§ͺ Inner-Loop (Pattern 1: Dual-Dropdown Pipeline)"]
Dev1["π¨βπ» Feature Developer"]
DualJob["01-CI-*-ci-dual-dropdown<br/>(Dropdown 1: App | Dropdown 2: Config)"]
DevSandbox["βΈοΈ Ephemeral Dev Sandbox / PR Preview<br/>(e.g. nubenetes-dev-apps / pr-42)"]
Dev1 -->|Ad-Hoc Experimentation| DualJob
DualJob -->|Direct 1-Click Deploy| DevSandbox
end
subgraph OuterLoop["π Outer-Loop (Pattern 2: Decoupled CI β CD Orchestration)"]
GitWebhook["β‘ Git Push / PR Merge Event"]
CIJob["01-CI-*-ci-build<br/>(Compiles & Tests App Code)"]
DevRegistry["π¦ OCP DEV Image Registry<br/>(Immutable Tag: 2.1.0-42-sha)"]
CDJob["02-CD-Release-Orchestrator<br/>(ArgoCD 3.5 Multi-Cluster Promotion)"]
SharedClusters["βΈοΈ Shared Environments<br/>(Shared DEV β STAGING β PROD)"]
GitWebhook -->|Automated Trigger| CIJob
CIJob -->|Publishes Image| DevRegistry
CIJob -->|Hands off to CD| CDJob
CDJob -->|GitOps Promotion| SharedClusters
end
- Inner-Loop (Pattern 1: Dual-Dropdown): Optimized for active feature development, sandbox testing, and rapid integration experimentation using a single unified pipeline.
- Outer-Loop (Pattern 2: Decoupled Hand-off): Standardized for official release promotions, UAT gates, and high-governance production rollouts.
- Shared Infrastructure: Both patterns share the same container registries, Helm charts, and ArgoCD application synchronizers.
π‘ Architectural Summary & Conclusion: Providing both patterns side-by-side offers enterprise platform teams maximum flexibility: rapid inner-loop velocity for developers during active feature testing, paired with rigorous, auditable release orchestration for production deployments.
- Scenario: An engineer is developing a feature requiring simultaneous code and environment configuration changes (e.g. a new microservice endpoint requiring a new database connection string or secret in
jenkins-git-parameter-global-vars). - Workflow:
- The developer pushes
feature/order-v2to the application repository. - The developer pushes
feature/order-config-v2tojenkins-git-parameter-global-vars. - The developer runs
jhipster-microservice-ci-dual-dropdown(Pattern 1), selecting both branches from the two live dropdowns. - The pipeline compiles and deploys the paired code and configuration directly into an isolated DEV preview namespace for instant verification.
- The developer pushes
- Benefit: Fast, self-contained iteration with zero impact on release promotion pipelines or shared environments.
- Scenario: The feature branch is merged into
main, or an automated scheduled CI build is triggered. - Workflow:
- A GitHub Webhook automatically triggers
jhipster-microservice-ci-build(Pattern 2). - It compiles, unit-tests, scans vulnerabilities (Trivy), builds an immutable container image (
2.1.0-42-a1b2c3d), and pushes it to the OCP DEV registry. - It triggers
02-CD-Release-Orchestrator, which syncs ArgoCD 3.5 in the shared DEV cluster, executes integration tests, and prepares the image for promotion to STAGING and PROD.
- A GitHub Webhook automatically triggers
- Benefit: 100% auditability, immutable artifact promotion via Skopeo, and strict GitOps compliance across shared environments.
| Pipeline in Jenkins UI | Pattern | Best Suited For | Target OpenShift Scope |
|---|---|---|---|
*-ci-dual-dropdown |
Pattern 1 (Dual Dropdowns) | Manual Ad-hoc Developer Testing & Feature Pairing | Developer Sandbox / Preview Namespaces |
*-ci-build |
Pattern 2 (CI Build) | Automated Git Webhooks, PR Scans & Trunk Integration | Pushes immutable image to OCP DEV Registry |
multi-cluster-release-orchestrator |
Pattern 2 (CD Release) | Release Promotions, Staging UAT & Production Releases | Deploys across DEV |
| Dimension | Monolithic Shared Library Antipattern (@Library('...') _) |
Modern Architecture: Job DSL + Declarative Templates + Granular Steps |
|---|---|---|
| Pipeline Visibility | Opaque black box; stages hidden inside Groovy scripts | Modern Stage View, Pipeline Graph View, and OpenTelemetry trace spans natively rendered |
| Jenkins Replay | β Broken: Replay cannot modify Shared Library code | β 100% Functional: Developers can replay and edit pipeline stages in UI |
| Job Provisioning | Manual UI creation or complex custom scripts | Automated Seed Job (seed-job.groovy) reconciles all jobs from Git |
| Syntax Validation | Runtime-only Groovy failures | Declarative linter validates syntax at definition time |
| Step Reusability | Tight coupling; copy-pasting scripted logic | Granular custom steps (argoAppSync, skopeoPromote, gitopsCommit) |
Note
Blue Ocean Deprecation & Modern UX Architecture: Blue Ocean has been officially deprecated by the Jenkins project due to maintenance overhead, heavy resource footprints, and limited compatibility with modern Declarative features. This platform adopts the modern recommended Jenkins UX stack:
- Pipeline Graph View Plugin (
pipeline-graph-view): Lightweight, responsive pipeline visualization directly embedded in the core Jenkins interface. - Pipeline Stage View (
pipeline-stage-view): Fast tabular build and stage matrix. - OpenTelemetry + Grafana: Deep distributed trace analysis with sub-millisecond stage breakdown and span correlations.
Decision: We use Job DSL to generate Declarative Pipeline jobs pointing to standard declarative Jenkinsfile definitions, complemented by a lightweight Jenkins Shared Library containing modular, reusable steps.
- Security Context Constraints (SCC):
- Jenkins Controller runs under
restricted-v2/nonrootSCC without requiring root privileges. - UID and GID are pinned to
1000:1000. - Dynamic ephemeral agents run inside dedicated non-privileged containers.
- Jenkins Controller runs under
- Zero Permanent Executors on Controller:
numExecutors: 0configured in JCasC. The master controller is exclusively a coordinator.- All builds run inside short-lived agent pods (
maven-jdk21,node-angular,skopeo-trivy,argocd-gitops) created on-demand and terminated immediately upon stage completion.
- OpenShift Route with Edge TLS:
- Secure external ingress via OpenShift HAProxy Route with automatic HTTP-to-HTTPS redirect and TLS termination.
-
Multi-Cluster Topology:
-
Cluster 1 (
ocp-dev): Hosts Jenkins Master, ArgoCD 3.5 Controller, OpenTelemetry Collector, and DEV workloads. -
Cluster 2 (
ocp-staging): External target cluster registered in ArgoCD via Kubernetes cluster secrets (cluster-ocp-staging). -
Cluster 3 (
ocp-prod): Production cluster managed remotely by ArgoCD (cluster-ocp-prod).
-
Cluster 1 (
-
ApplicationSets & Sync Waves:
-
ApplicationSetgenerators dynamically provision application targets per cluster. - ArgoCD sync waves enforce strict ordering: Database migrations (Wave 1)
$\rightarrow$ Backend Microservices (Wave 2)$\rightarrow$ Frontend SPA & Routes (Wave 3).
-
-
Skopeo Cross-Cluster Image Copy:
- Images are copied directly between cluster internal registries (
image-registry.openshift-image-registry.svc:5000) without spinning up a Docker daemon or intermediate worker storage.
- Images are copied directly between cluster internal registries (
This platform implements a unified, end-to-end observability mesh covering both Platform Operations (Jenkins Controller, Ephemeral Agent Pods, ArgoCD GitOps Engine, OpenShift Cluster Metrics) and Application Workloads (Java 21 / Spring Boot Microservices, Angular SPAs).
Grafana 13.2.0 is deployed and continuously reconciled via ArgoCD GitOps (argocd-apps/apps/dev/grafana-observability.yaml), with pinned image tags and automated drift management.
By leveraging the W3C Distributed Tracing standard, every CI build, container promotion, GitOps sync, and live HTTP user request is linked through a single correlated traceparent.
π Click to expand: Full-Stack Observability & Trace Correlation Architecture Diagram
flowchart TB
subgraph Layer1["1. CI/CD Platform & GitOps Engine"]
direction TB
Jenkins["βοΈ Jenkins Controller<br/>(OpenTelemetry Plugin)"]
Agents["βΈοΈ Ephemeral Agent Pods<br/>(Maven / Skopeo / Cosign)"]
ArgoCD["π ArgoCD 3.5 Controller<br/>(ApplicationSet Engine)"]
end
subgraph Layer2["2. Observability & Telemetry Processing"]
direction TB
Collector["π OpenTelemetry Collector<br/>(OTLP gRPC:4317 / HTTP:4318)"]
Prom["π₯ Prometheus Server<br/>(Metrics Scrape & Storage)"]
end
subgraph Layer3["3. Deployed Microservices & Web Apps"]
direction TB
Angular["π
°οΈ Angular 18 Web App<br/>(@opentelemetry/sdk-trace-web)"]
SpringBoot["β Spring Boot 3 Microservice<br/>(Micrometer Tracing + OTLP)"]
end
subgraph Layer4["4. Unified Grafana 13.2.0 Correlation"]
direction TB
Grafana["π Grafana 13.2.0 Dashboards<br/>(Trace-to-Log & Exemplars)"]
end
Jenkins -->|"OTLP Traces"| Collector
Agents -->|"Span Context (W3C)"| Collector
ArgoCD -->|"Prometheus Metrics"| Prom
Collector -->|"Export Metrics"| Prom
Angular -->|"HTTP + W3C Traceparent"| SpringBoot
SpringBoot -->|"OTLP Traces & Exemplars"| Collector
SpringBoot -->|"/actuator/prometheus"| Prom
Prom -->|"Metrics with Exemplars"| Grafana
Collector -->|"Correlated Traces"| Grafana
- Pipeline Telemetry: OpenTelemetry Jenkins Plugin traces pipeline stages (checkout, build, test, deploy) with W3C trace IDs.
- Metric Export: Prometheus plugin exports live controller queue metrics, build execution durations, and executor utilization.
- Unified Dashboards: Grafana 13.2.0 consolidates OTLP distributed traces, Prometheus metrics, and Loki pipeline logs in a single pane of glass.
π‘ Architectural Summary & Conclusion: End-to-end telemetry gives platform engineers deep visibility into build bottlenecks, test suite degradation, and deployment latencies across all OpenShift clusters.
| Pillar | Platform Telemetry (Jenkins & ArgoCD) | Workload Telemetry (Spring Boot & Angular) | End-to-End Correlation Link |
|---|---|---|---|
| Traces (OpenTelemetry) | Pipeline Root Spans, Stage Spans, Step Spans, Image Push & ArgoCD Sync Spans | Incoming HTTP Controller Spans, Database Queries, Downstream REST calls |
W3C traceparent Header: Extracted in CI |
| Metrics (Prometheus) |
jenkins_runs_total, jenkins_executor_queue_time_bucket, argocd_app_sync_total
|
http_server_requests_seconds_bucket, jvm_memory_used_bytes, jvm_gc_pause_seconds
|
Prometheus Exemplars: High latency spikes in Grafana graph link directly to the specific OTel trace ID. |
| Logs (Structured) | Jenkins Controller & Agent console logs formatted with build metadata | Spring Boot Logback JSON logs with %X{trace_id} and %X{span_id}
|
Trace-to-Logs Derived Fields: 1-click jump from a Grafana trace span to the exact container log lines. |
The platform maintains unbroken distributed trace continuity using standard W3C Trace Context (traceparent):
- Pipeline Execution: The Jenkins OpenTelemetry plugin generates a root
trace_id(e.g.4bf92f3577b34da6a3ce929d0e0e4736). - Shared Library Step (
otelLogEvent.groovy): Emits span annotations with build number, git commit SHA, and target cluster, exportingCURRENT_TRACEPARENTto the agent environment:otelLogEvent( name: 'cd.orchestration.initialized', app: params.APP_NAME, imageTag: params.IMAGE_TAG, gitCommit: env.GIT_COMMIT_SHORT, caller: params.TRIGGERED_BY ) - Application Runtime Tracing: Spring Boot 3 uses
micrometer-tracing-bridge-otelto ingest the trace context from incoming requests and forwards spans to the OpenTelemetry Collector:management: tracing: sampling: probability: 1.0 propagation: type: W3C otlp: tracing: endpoint: http://otel-collector.observability.svc.cluster.local:4318/v1/traces metrics: distribution: percentiles-histogram: http.server.requests: true
- Client-Side SPA Tracing: Angular Single Page Apps instrumented with
@opentelemetry/sdk-trace-webattach thetraceparentHTTP header to all AJAX/Fetch calls, connecting user button clicks in the browser to backend Java transactions.
Grafana 13.2.0 is pre-configured with Prometheus Exemplars enabled in helm/observability/grafana-values.yaml:
- When Prometheus collects
http_server_requests_seconds_bucketlatency metrics, Micrometer attaches the activetrace_idas an exemplar. - In Grafana 13.2.0, hovering over a latency spike displays a blue exemplar dot; clicking it opens the exact OpenTelemetry trace span in the side-by-side Trace View.
The repository ships with 3 production-grade, pre-provisioned Grafana Dashboards:
| Dashboard UID | Dashboard Name | Scope & Visualized Metrics |
|---|---|---|
jenkins-performance-otel |
Jenkins Platform & Ephemeral Agent APM | Stage durations, p95 queue latency, success/failure rate, dynamic Kubernetes agent pod concurrency, OTel trace spans. |
argocd-gitops-sync |
ArgoCD 3.5 Multi-Cluster GitOps Sync | Application health status (Healthy/Degraded), sync phases (Synced/OutOfSync), sync waves progression, drift detection. |
workload-apm-correlation |
Workload APM & CI/CD GitOps Correlation | Request throughput (req/sec), p50/p90/p95/p99 latency percentiles with OTel Exemplars, HTTP 5xx error budget, JVM heap & GC pause metrics, correlated CI/CD deployment annotations. |
6. Centralized Configuration Architecture: config/environments.env vs jenkins-git-parameter-global-vars
An enterprise-grade cloud-native platform maintains a strict separation between Platform Bootstrap (Day-1 IaC) and Dynamic Workload / Cluster Inventory Governance (Day-2 GitOps SSOT).
ποΈ Click to expand: Platform IaC vs Centralized Governance Integration Flow Diagram
flowchart TB
subgraph Day1["1. Platform Bootstrap & IaC (jenkins-git-parameter)"]
direction TB
EnvFile["π config/environments.env<br/>β’ GLOBAL_VARS_REPO_URL<br/>β’ OCP_CLUSTER_DEV/STG/PRD<br/>β’ OCP_APPS_DOMAIN"]
DeployScript["βοΈ deploy.sh / Makefile"]
JCasC["π¦ JCasC (jenkins-jcasc.yaml)<br/>β’ Injects env.GLOBAL_VARS_REPO"]
EnvFile --> DeployScript
DeployScript --> JCasC
end
subgraph Day2["2. Centralized Governance SSOT (jenkins-git-parameter-global-vars)"]
direction TB
ClustersDir["π clusters/<br/>β’ ocp-dev-cluster.yaml<br/>β’ ocp-staging-cluster.yaml<br/>β’ ocp-prod-cluster.yaml"]
EnvsDir["π environments/<br/>β’ dev.yaml<br/>β’ staging.yaml<br/>β’ prod.yaml"]
AppInventory["π apps/<br/>β’ applications-inventory.yaml"]
end
subgraph Runtime["3. Jenkins CI/CD & ArgoCD Runtime Execution"]
direction TB
JobDSL["π Job DSL (pipelines-cd.groovy)<br/>β’ gitParameter queries GLOBAL_VARS_REPO"]
UIForm["π UI Dropdown: GLOBAL_VARS_REVISION<br/>β’ Real-time git ls-remote resolution"]
PipelineStage["π Jenkinsfile.release-orchestrator<br/>β’ Dynamic checkout of selected branch/tag<br/>β’ Parses cluster YAMLs & triggers ArgoCD"]
JCasC --> JobDSL
JobDSL --> UIForm
UIForm --> PipelineStage
end
Day2 -.->|"Queried dynamically in UI"| UIForm
Day2 -.->|"Checked out at runtime"| PipelineStage
- Day 1 Platform IaC (
jenkins-git-parameter): Provisions Jenkins controller, JCasC, Job DSL scripts, and cluster-wide Helm charts. - Day 2 Governance (
jenkins-git-parameter-global-vars): Holds environment variables, OpenShift cluster inventories, Helm values, and Vault secret references. - Pipeline Synchronization: CD Release Orchestrators query global configuration to dynamically inject environment parameters at runtime.
π‘ Architectural Summary & Conclusion: Decoupling platform infrastructure code from environmental configuration allows central platform teams to enforce governance policies across microservices without modifying core Jenkins automation code.
| Dimension | config/environments.env (Platform IaC) |
jenkins-git-parameter-global-vars (Workload SSOT) |
|---|---|---|
| Primary Role | Day-0 / Day-1 Platform deployment, Helm version pinning, namespace provisioning. | Day-2 Workload governance, cluster inventory, environment parameter overlays. |
| Consuming Actors | Platform Engineers, Bash scripts (deploy.sh, destroy.sh), Makefile. |
Developers, Release Managers, Jenkins gitParameter UI, CD Orchestrators. |
| Modification Frequency | Infrequent (Cluster upgrades, Helm chart updates, new platform tools). | High (Daily feature branches, environment config tweaks, new microservices). |
| Failure Blast Radius | High (Platform-wide provisioning disruption if misconfigured). | Isolated (Targeted to a specific application or promotional environment). |
| Git Branching Policy | Trunk-based (main), changes deployed via infrastructure maintenance windows. |
Multi-branch & Semantic Tags (main, feature/*, env/staging-override, v*.*.*-release). |
- Zero-Downtime Governance Changes:
Adding a new cluster target (
clusters/ocp-dr-cluster.yaml), updating microservice memory limits (environments/prod.yaml), or adding a new application toapps/applications-inventory.yamlrequires zero changes and zero restarts on Jenkins, ArgoCD, or JCasC. - Immutable Platform, Mutable Workloads:
The Jenkins controller and JCasC configuration remain static and secure. Operators interact with
jenkins-git-parameter-global-varsvia standard Pull Requests, enabling review gates, branch protections, and compliance audits before a configuration is released.
jenkins-git-parameter/
βββ README.md # Architectural analysis, documentation, and references
βββ Makefile # Platform lifecycle commands (deploy, destroy, lint, status)
βββ deploy.sh # 1-Click deployment automation script
βββ destroy.sh # 1-Click decommissioning script
βββ reinstall.sh # Clean reinstall orchestration
βββ config/
β βββ clusters.yaml # Multi-cluster topology definition (DEV, STAGE, PROD)
β βββ environments.env # Pinned version matrix and environment parameters
βββ helm/
β βββ jenkins/
β β βββ Chart.yaml # Jenkins Helm chart wrapper
β β βββ values.yaml # Pinned base values & plugin list
β β βββ values-openshift.yaml # OpenShift 4.20+ overrides (SCC, Routes, JCasC mounts)
β β βββ plugins.txt # Pinned plugin manifest with exact version numbers
β βββ argocd/
β β βββ values-argocd-3.5.yaml # ArgoCD 3.5 Helm values & ApplicationSet controller
β βββ observability/
β βββ otel-collector-values.yaml # OpenTelemetry Collector configuration
β βββ grafana-values.yaml # Grafana datasources & dashboard providers
β βββ prometheus-values.yaml # Prometheus scrape configurations
βββ jcasc/
β βββ jenkins-jcasc.yaml # Jenkins Configuration as Code (Security, OTel, Seed Job)
β βββ pod-templates.yaml # Ephemeral Kubernetes Agent pod templates
β βββ github-app-credentials.yaml # Automated short-lived GitHub App authentication
βββ jobdsl/
β βββ seed-job.groovy # Master Seed Job provisioning all pipelines
β βββ pipelines-ci.groovy # Job DSL for Application CI pipelines (Patterns 1 & 2)
β βββ pipelines-cd.groovy # Job DSL for CD Release Orchestrators (Global Vars Git Parameter)
βββ jenkinsfiles/
β βββ ci/
β β βββ Jenkinsfile.app-java-maven # Pattern 2: Declarative CI pipeline for Java 21
β β βββ Jenkinsfile.app-angular # Pattern 2: Declarative CI pipeline for Angular 18+
β β βββ Jenkinsfile.app-java-maven-dual-dropdown # Pattern 1: Dual-Dropdown Multi-Remote SCM pipeline
β β βββ Jenkinsfile.app-angular-dual-dropdown # Pattern 1: Dual-Dropdown Angular pipeline
β βββ cd/
β βββ Jenkinsfile.release-orchestrator # Pattern 2: Multi-Cluster Release & Promotion pipeline
β βββ Jenkinsfile.hotfix-deploy # Fast-track emergency hotfix pipeline
βββ shared-library/
β βββ vars/
β β βββ argoAppSync.groovy # Step: Trigger & wait for ArgoCD 3.5 sync
β β βββ skopeoPromote.groovy # Step: Promote container image between cluster registries
β β βββ gitopsCommit.groovy # Step: Update GitOps environment repository
β β βββ otelLogEvent.groovy # Step: Annotate OpenTelemetry spans
β β βββ cosignSign.groovy # Step: Cosign container image signing & SLSA 3 attestation
β β βββ sbomGenerate.groovy # Step: Syft SBOM generation & Cosign attestation
β βββ src/com/nubenetes/gitops/
β βββ ClusterEnvironment.groovy # Strongly typed Groovy cluster model
βββ security/
β βββ external-secrets-operator/
β β βββ cluster-secret-store-vault.yaml # Vault HashiCorp ClusterSecretStore
β β βββ external-secret-template.yaml # ExternalSecret custom resource definition
β βββ openshift-image-signature-policy.yaml# OpenShift MachineConfig signature verification policy
βββ argocd-apps/
β βββ root-app-of-apps.yaml # ArgoCD Root App-of-Apps pattern
β βββ applicationset-clusters.yaml # Multi-Cluster ApplicationSet generator
β βββ applicationset-pull-request-preview.yaml # Dynamic ephemeral PR preview generator
β βββ apps/
β βββ dev/jhipster-microservice.yaml
β βββ dev/grafana-observability.yaml # ArgoCD GitOps Application for Grafana 13.2.0
β βββ staging/jhipster-microservice.yaml
β βββ prod/jhipster-microservice.yaml
βββ sample-apps/
β βββ jhipster-microservice/ # PoC Java 21 / Spring Boot 3 microservice
β β βββ Dockerfile # Multi-stage container build
β β βββ pom.xml
β β βββ src/...
β β βββ k8s/ # Kustomize base & overlays (dev, staging, prod)
β β βββ rollout/ # Argo Rollouts progressive delivery manifests
β β βββ rollout-canary-jhipster.yaml
β β βββ analysis-template-prometheus.yaml
β β βββ services-active-canary.yaml
β βββ nubenetes-global-vars/ # Centralized Global Configuration template reference
β βββ apps/applications-inventory.yaml
β βββ clusters/
β β βββ ocp-dev-cluster.yaml
β β βββ ocp-staging-cluster.yaml
β β βββ ocp-prod-cluster.yaml
β βββ environments/
β βββ dev.yaml
β βββ staging.yaml
β βββ prod.yaml
βββ observability/
β βββ dashboards/
β βββ jenkins-performance-otel.json # Grafana Dashboard: Pipeline & OTel Spans
β βββ argocd-gitops-sync.json # Grafana Dashboard: ArgoCD GitOps Sync & Health
β βββ app-full-stack-correlation.json # Grafana Dashboard: Workload APM & CI/CD Correlation
βββ scripts/
βββ ocp-setup-scc.sh # Configure OpenShift SCC & RBAC
βββ setup-argocd-clusters.sh # Register STAGING and PROD clusters in ArgoCD
βββ generate-tokens.sh # Generate auth secrets and tokens
- OpenShift 4.20+ CLI (
ocorkubectl) logged in with cluster administrator permissions (cluster-admin). - Helm 3.14+.
- Bash shell.
To automatically provision all namespaces, security context constraints, JCasC ConfigMaps, OpenTelemetry Collector, Prometheus, Grafana, ArgoCD 3.5, and Jenkins Controller with the Seed Job:
git clone https://github.com/nubenetes/jenkins-git-parameter.git
cd jenkins-git-parameter
chmod +x deploy.sh
./deploy.shOr using Make:
make deployAfter deployment completes, the script outputs the operational routes:
| Service | URL / Route | Credentials |
|---|---|---|
| Jenkins Master | https://jenkins-jenkins.apps.ocp-dev.nubenetes.internal |
admin / admin123! |
| ArgoCD 3.5 UI | https://argocd-server.apps.ocp-dev.nubenetes.internal |
admin / (retrieved via secret) |
| Grafana 13.2.0 Dashboards | http://grafana.observability.svc.cluster.local:3000 |
admin / admin123! |
| OTel Collector | http://otel-collector.observability.svc.cluster.local:4317 |
OTLP gRPC endpoint |
This platform provides flexible ways to select and propagate the GLOBAL_VARS_REVISION (branch, tag, or commit of the centralized jenkins-git-parameter-global-vars repository) across both CI and CD pipelines.
When starting from the application CI build pipeline, developers select their application revision and specify which global configuration branch should be targeted downstream.
-
Navigate to Jenkins UI
$\rightarrow$ 01-CI-Build-Pipelines$\rightarrow$ jhipster-microservice-ci-build. - Click "Build with Parameters" in the sidebar.
- Configure the build parameters:
-
APP_GIT_REVISION(Git Parameter Dropdown): Select the application Git branch, tag, or PR fromjhipster-microservice(e.g.main,feature/payment-v2,v2.1.0). -
TRIGGER_CD_RELEASE(Checkbox, defaulttrue): Auto-triggers Pipeline02upon successful build and vulnerability scan. -
GLOBAL_VARS_BRANCH(Text input, defaultmain): Enter the branch, tag, or commit ofjenkins-git-parameter-global-varsto use (e.g.main,release-2026.1,staging-env-v3). -
TARGET_ENVIRONMENT(Choice Dropdown): Select initial deployment environment (dev,staging,prod).
-
- Click Build.
How Parameter Propagation Works:
Pipeline 01 compiles the code, builds the container image with a unique SHA-based tag (e.g. 2.1.0-42-a1b2c3d), pushes it to the OCP DEV registry, and automatically passes GLOBAL_VARS_BRANCH as GLOBAL_VARS_REVISION to Pipeline 02:
build job: '02-CD-Release-Orchestrators/multi-cluster-release-orchestrator',
parameters: [
string(name: 'GLOBAL_VARS_REVISION', value: params.GLOBAL_VARS_BRANCH ?: 'main'),
string(name: 'APP_NAME', value: env.APP_NAME),
string(name: 'IMAGE_TAG', value: env.CALCULATED_TAG),
string(name: 'TARGET_ENVIRONMENT', value: params.TARGET_ENVIRONMENT ?: 'dev'),
booleanParam(name: 'AUTO_PROMOTE_TO_STAGING', value: true),
booleanParam(name: 'REQUIRE_PROD_APPROVAL', value: true),
string(name: 'TRIGGERED_BY', value: 'CI_PIPELINE'),
string(name: 'CHANGE_REQUEST_ID', value: "CI-AUTO-${BUILD_NUMBER}")
],
wait: falseWhen operators, release engineers, or DevOps teams want to deploy or promote an existing immutable container image against a specific configuration branch:
-
Navigate to Jenkins UI
$\rightarrow$ 02-CD-Release-Orchestrators$\rightarrow$ multi-cluster-release-orchestrator. - Click "Build with Parameters".
- Configure the parameters:
-
GLOBAL_VARS_REVISION(Interactive Git Parameter Dropdown with live search):- The Jenkins Git Parameter plugin dynamically queries
https://github.com/nubenetes/jenkins-git-parameter-global-vars.gitin real-time. - You can scroll or type to search all remote branches and tags (e.g.
main,v2.1.0-release,env/staging-hotfix).
- The Jenkins Git Parameter plugin dynamically queries
-
APP_NAME(Choice Dropdown): Selectjhipster-microserviceorangular-frontend. -
IMAGE_TAG(Text input): Enter the pre-built image tag to deploy/promote (e.g.2.1.0-42-a1b2c3d). -
TARGET_ENVIRONMENT(Choice): Selectdev,staging,prod, orfull-promotion-chain. -
AUTO_PROMOTE_TO_STAGING/REQUIRE_PROD_APPROVAL: Toggle automated stage gates.
-
- Click Build.
How Configuration Checkout Works:
In the first stage (Initialize & Resolve Global Configuration), Pipeline 02 checks out the global variables repository at the exact branch/tag you selected:
dir('jenkins-git-parameter-global-vars') {
checkout([
$class: 'GitSCM',
branches: [[name: "${params.GLOBAL_VARS_REVISION}"]],
userRemoteConfigs: [[url: 'https://github.com/nubenetes/jenkins-git-parameter-global-vars.git']]
])
}In enterprise environments, production deployments and cross-cluster promotions are rarely triggered manually by individual developers clicking buttons in a CI tool. Instead, organizations enforce structured, auditable IT Service Management (ITSM) workflows using Jira Service Management (JSM) Forms, Jira Assets / CMDB, ServiceNow, or Backstage Developer Portals.
π« Click to expand: Jira ITSM & Backstage IDP Self-Service Architecture Diagram
flowchart TB
subgraph SelfServicePortals["1. Governed Self-Service & Developer Portals"]
direction LR
subgraph JiraTrack["ITSM & Governance Track"]
JiraUser["π¨βπ» Release Engineer"]
JiraForm["π Jira Service Mgmt Form<br/>(App, Version & Env)"]
CMDB[("ποΈ Jira CMDB / Assets<br/>(Apps, Clusters, CAB)")]
CAB["π‘οΈ Change Advisory Board<br/>(CAB Approval Gate)"]
JiraWebhook["β‘ Jira Webhook Trigger"]
end
subgraph BackstageTrack["Developer Portal Track"]
DevUser["π©βπ» Application Developer"]
BackstageUI["ποΈ Backstage IDP Portal<br/>(Software Template)"]
BackstageCatalog[("π Backstage Catalog<br/>(Components & APIs)")]
BackstagePlugin["β‘ Backstage Plugin<br/>(API Dispatch)"]
end
end
subgraph CI_CD_Layer["2. CI/CD Release Orchestration Engine"]
JenkinsCD["π 02-CD-Release-Orchestrator<br/>(Git Param: Global Vars)"]
GlobalVars[("π¦ Global Variables Repo<br/>(Environment Configs)")]
end
subgraph DeploymentObservabilityLayer["3. Multi-Cluster GitOps & Telemetry"]
Argo["π ArgoCD 3.5 Controller<br/>(Multi-Cluster Sync Waves)"]
OCP["βΈοΈ OpenShift 4.20+ Clusters<br/>(DEV β STAGING β PROD)"]
OTel["π OpenTelemetry & Grafana<br/>(Traces, Metrics & Logs)"]
end
JiraUser -->|Submit Release Form| JiraForm
JiraForm <-->|Query CMDB CIs| CMDB
JiraForm -->|Request CAB Approval| CAB
CAB -->|Approve Change| JiraWebhook
JiraWebhook -->|POST /buildWithParameters| JenkinsCD
DevUser -->|Trigger Self-Service| BackstageUI
BackstageUI <-->|Fetch Catalog Metadata| BackstageCatalog
BackstageUI -->|Dispatch API Call| BackstagePlugin
BackstagePlugin -->|POST /buildWithParameters| JenkinsCD
JenkinsCD -->|Clone Selected Revision| GlobalVars
JenkinsCD -->|Promote & Sync GitOps| Argo
Argo -->|Apply Manifests| OCP
JenkinsCD -.->|Emit W3C Trace Spans| OTel
JenkinsCD -.->|Close Jira Ticket| JiraForm
JenkinsCD -.->|Update Status in UI| BackstageUI
- Backstage IDP Scaffolding: Developers select software templates in Backstage, which triggers Jenkins Pipeline 02 via REST API.
- ITSM Governance Gate: Jira Service Management / ServiceNow Change Requests invoke Pipeline 02 upon formal CAB approval.
- Downstream Deployment: Pipeline 02 executes Skopeo image promotion and ArgoCD synchronization across target clusters.
π‘ Architectural Summary & Conclusion: Parameterized CD pipelines seamlessly integrate into enterprise developer portals and ITSM tools, transforming Jenkins into a governed execution engine for self-service operations.
-
Centralized Configuration Management Database (CMDB) as Single Source of Truth:
- Modern IT organizations manage hundreds of microservices. The CMDB maintains a single source of truth for Application Metadata, Business Criticality (Tier 1 vs Tier 3), Regulatory Scope (PCI-DSS, HIPAA, SOX, GDPR), Data Classification, and Assigned Service Owners.
- Connecting Jira Forms to CMDB Assets ensures developers only select validated, registered applications, compliant target clusters, and authorized environment variables.
-
Schema-Driven, Governed Self-Service via Jira Forms:
- Rather than providing direct cluster admin or Jenkins master access to developers, engineers fill out an intuitive Jira Release Request Form.
- When the user selects an application (e.g.
jhipster-microservice), Jira's schema-driven form dynamically queries the CMDB to auto-populate:- The approved GitOps configuration repository (
jenkins-git-parameter-global-vars). - The target OpenShift cluster topology (
ocp-dev,ocp-staging,ocp-prod). - The required approval gates (e.g., automated QA lead sign-off for STAGING, automated CAB approval for standard PROD changes, or VP approval for emergency hotfixes).
- The approved GitOps configuration repository (
-
Segregation of Duties (SoD) & Regulatory Audit Compliance:
- Regulated industries require strict Segregation of Duties (the engineer who writes the code cannot be the sole approver of the production release).
- Jira Forms + CMDB enforce immutable change records where the Jira Ticket ID (
CHG-2026-98124) tracks:- Exact Git commit SHA and Container Image Digest.
- Selected Global Configuration branch/tag (
GLOBAL_VARS_REVISION). - Test execution evidence, security scan (Trivy/SonarQube) results, and CAB approval timestamps.
-
Automated Webhook Dispatch to Jenkins with Parameter Injection:
- When the Jira Change Request reaches the
Approvedstate, a Jira Automation Rule fires an HTTP POST webhook to Jenkins'buildWithParametersendpoint, injecting the form inputs directly:
- When the Jira Change Request reaches the
# Jira Automation / ServiceNow REST API Dispatch Payload
curl -X POST "https://jenkins-jenkins.apps.ocp-dev.nubenetes.internal/job/02-CD-Release-Orchestrators/job/multi-cluster-release-orchestrator/buildWithParameters" \
--user "ci-service:service123!" \
--data-urlencode "GLOBAL_VARS_REVISION=v2.1.0-release" \
--data-urlencode "APP_NAME=jhipster-microservice" \
--data-urlencode "IMAGE_TAG=2.1.0-42-a1b2c3d" \
--data-urlencode "TARGET_ENVIRONMENT=full-promotion-chain" \
--data-urlencode "AUTO_PROMOTE_TO_STAGING=true" \
--data-urlencode "REQUIRE_PROD_APPROVAL=true" \
--data-urlencode "TRIGGERED_BY=JIRA_FORMS_CMDB" \
--data-urlencode "CHANGE_REQUEST_ID=CHG-2026-98124"- Closed-Loop Feedback & Automated Ticket Closure:
- During pipeline execution, Jenkins publishes progress comments to the Jira issue via the Jira REST API.
- Upon successful multi-cluster deployment and ArgoCD health verification, Jenkins updates the Jira issue with the Skopeo image promotion digest, OpenShift Route URL, and OpenTelemetry trace link, automatically transitioning the Jira ticket to
Closed / Resolved.
| Trigger Entrypoint | Parameter Name | UI Element Type | Target Repository | Default Value | Propagation Logic |
|---|---|---|---|---|---|
| Pipeline 01 (CI) | APP_GIT_REVISION |
Git Parameter Dropdown | Application Repo | main |
Used to build source code |
| Pipeline 01 (CI) | GLOBAL_VARS_BRANCH |
Text Field with Default | jenkins-git-parameter-global-vars |
main |
Forwarded to Pipeline 02 as GLOBAL_VARS_REVISION |
| Pipeline 02 (CD) | GLOBAL_VARS_REVISION |
Git Parameter Dropdown | jenkins-git-parameter-global-vars |
main |
Cloned directly to drive GitOps manifests |
| External API / ITSM | GLOBAL_VARS_REVISION |
HTTP POST Parameter | jenkins-git-parameter-global-vars |
Explicit String | Injected into Pipeline 02 runtime |
To transition this platform into a mission-critical, regulated enterprise production environment, we have implemented 5 advanced architectural capabilities:
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β ENTERPRISE ARCHITECTURE ADVANCED CAPABILITIES β
βββββββββββββββββββββββββββββββββ¬ββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β 1. Supply Chain Security β Cosign Keyless Signing, Syft SBOM & SLSA Level 3 β
β 2. Zero-Trust Secrets β External Secrets Operator (ESO) + HashiCorp Vault β
β 3. Dynamic PR Preview Envs β ArgoCD 3.5 ApplicationSet Pull Request Generator β
β 4. Progressive Delivery β Argo Rollouts (Canary + Prometheus Metric Auto) β
β 5. Automated Identity β GitHub App Short-Lived Token Rotation via JCasC β
βββββββββββββββββββββββββββββββββ΄ββββββββββββββββββββββββββββββββββββββββββββββββββββ
In multi-cluster promotion (ocp-dev ocp-staging ocp-prod), promoting raw container images without cryptographic signatures creates a software supply chain vulnerability.
π Click to expand: Cosign Image Signing & SLSA Level 3 Attestation Flow Diagram
flowchart LR
CI["ποΈ CI Build (Maven/Node)"]
Trivy["π‘οΈ Trivy Scan & Syft SBOM"]
Cosign["π Cosign Signature & SLSA Attestation"]
Registry["π¦ OCP DEV Registry"]
Skopeo["π Skopeo Cross-Cluster Promotion"]
ClusterPolicy["π‘οΈ OpenShift Image Signature Policy"]
ProdEnv["βΈοΈ OCP Production Workload"]
CI --> Trivy
Trivy --> Cosign
Cosign -->|Signed Digest & SBOM| Registry
Registry -->|Promote Digest + Sig| Skopeo
Skopeo --> ClusterPolicy
ClusterPolicy -->|Signature Verified Valid| ProdEnv
- Artifact Creation: Maven build packages container image.
- Cosign Signing: Ephemeral agent signs the container digest using private keys stored in HashiCorp Vault.
- Attestation Generation: Generates and attaches CycloneDX SBOM and in-toto provenance metadata to the OpenShift registry.
- Admission Verification: OpenShift Image Signature Policy enforces signature verification before pod startup.
π‘ Architectural Summary & Conclusion: Enforcing SLSA Level 3 supply chain security guarantees that only cryptographically verified container images built by authorized Jenkins pipelines can run in production.
- Shared Library Step:
shared-library/vars/cosignSign.groovyautomatically signs the image digest, generates CycloneDX SBOMs via Syft, and attaches in-toto SLSA build provenance statements. - OpenShift Signature Policy:
security/openshift-image-signature-policy.yamlconfigures OpenShift's nativeClusterImagePolicyto strictly reject unsigned images innubenetes-prod-apps.
Plaintext database credentials, API tokens, and private keys should never be committed into Git repositories.
π Click to expand: External Secrets Operator & Vault Synchronization Flow Diagram
flowchart LR
Vault[("π HashiCorp Vault<br/>(Raw Secrets & Passwords)")]
GlobalVars[("π¦ Global Vars Repo<br/>(ExternalSecret Custom Resource)")]
ESO["β‘ External Secrets Operator<br/>(OpenShift Cluster Controller)"]
K8sSecret["π Native Kubernetes Secret<br/>(Decrypted in Memory)"]
Pod["βΈοΈ Application Pod"]
GlobalVars -->|GitOps Sync Manifest| ESO
ESO <-->|Kubernetes SA Token Auth| Vault
ESO -->|Creates / Rotates Secret| K8sSecret
K8sSecret -->|Mounted as Env / Volume| Pod
- Central Secret Storage: HashiCorp Vault stores raw database passwords and API tokens securely.
- External Secrets Operator (ESO): Synchronizes secrets from Vault into native Kubernetes
Secretresources based onExternalSecretcustom resources. - Pod Injection: Workload pods consume secrets as environment variables or volume mounts without hardcoding credentials in Git.
π‘ Architectural Summary & Conclusion: ESO with HashiCorp Vault eliminates hardcoded secrets across all Git repositories, ensuring centralized secret rotation and dynamic access control.
- ClusterSecretStore:
security/external-secrets-operator/cluster-secret-store-vault.yamlintegrates OpenShift service accounts directly with Vault using Kubernetes Auth. - Declarative ExternalSecrets:
jenkins-git-parameter-global-vars/secrets/declares Vault secret mappings (external-secrets-prod.yaml) that synchronize secrets into in-memory Kubernetes Secrets with automatic rotation.
Supercharges Pattern 1 (Inner-Loop) by automatically provisioning isolated preview namespaces for active GitHub Pull Requests, and deleting them upon PR merge/close.
β‘ Click to expand: Ephemeral PR Preview Environment Provisioning Flow Diagram
flowchart LR
Dev["π¨βπ» Developer"]
PR["π GitHub Pull Request #42"]
AppSet["β‘ ArgoCD ApplicationSet<br/>(Pull Request Generator)"]
PreviewNS["βΈοΈ Ephemeral Preview Namespace<br/>(pr-42-preview)"]
Route["π Preview Route URL<br/>pr-42-jhipster.apps.ocp-dev..."]
Dev -->|Opens PR| PR
PR -->|Webhook Notification| AppSet
AppSet -->|Provisions Namespace & Deploy| PreviewNS
PreviewNS -->|Generates Endpoint| Route
PR -.->|PR Merged or Closed| AppSet
AppSet -.->|Automatically Prunes & Deletes| PreviewNS
- PR Webhook: Opening a GitHub PR triggers Jenkins CI to build and push an ephemeral preview container image.
- ArgoCD Dynamic Sync: ArgoCD provisions an isolated namespace
pr-preview-<id>on the DEV cluster. - Automated Cleanup: Closing or merging the pull request automatically tears down the namespace and destroys temporary cloud resources.
π‘ Architectural Summary & Conclusion: Dynamic preview environments enable automated visual and integration testing for every pull request, drastically accelerating review velocity before merging to main.
- PR Generator Manifest:
argocd-apps/applicationset-pull-request-preview.yamldynamically generates preview applications for PRs labeledpreview-environment.
Replaces risky all-at-once rolling updates in STAGING and PROD with automated canary analysis that continuously measures Prometheus / OpenTelemetry telemetry.
π£ Click to expand: Argo Rollouts Canary Traffic Splitting & Metric Analysis Diagram
flowchart LR
Ingress["π OpenShift Route Traffic"]
Canary["π£ Canary Pods (10% - 25% - 50%)<br/>v2.1.0 (New Image)"]
Stable["π‘οΈ Stable Pods (90% - 75% - 50%)<br/>v2.0.8 (Current Image)"]
Prometheus["π Prometheus / OTel Metrics<br/>(5xx Rate < 0.1%, p99 < 250ms)"]
RolloutCtrl["β‘ Argo Rollouts Controller"]
Ingress -->|Traffic Split| Canary
Ingress -->|Traffic Split| Stable
Canary -.->|Emits Telemetry| Prometheus
Prometheus -.->|Metric Evaluation| RolloutCtrl
RolloutCtrl -->|Pass: Promote to 100%<br/>Fail: Automated Rollback| Ingress
- Traffic Routing: Argo Rollouts splits OpenShift route traffic, directing 20% to canary pods and 80% to stable pods.
- Metric SLA Validation: Automated analysis queries Prometheus metrics (error rates and latency thresholds).
- Automated Promotion / Rollback: If SLAs pass, traffic scales to 100%; if errors occur, instant automated rollback protects live users.
π‘ Architectural Summary & Conclusion: Progressive canary delivery with automated metric analysis eliminates deployment risk, ensuring zero-downtime releases and automated safety rollbacks.
-
AnalysisTemplate:
sample-apps/jhipster-microservice/rollout/analysis-template-prometheus.yamlevaluates HTTP 5xx error rate ($\le 0.1%$ ) and p99 latency ($\le 250\text{ms}$ ). -
Rollout Definition:
sample-apps/jhipster-microservice/rollout/rollout-canary-jhipster.yamlorchestrates progressive traffic steps (10%$\rightarrow$ 25%$\rightarrow$ 50%$\rightarrow$ 100%) with automated rollbacks on SLA violations.
Replaces static, long-lived Personal Access Tokens (PATs) with fine-grained GitHub Apps that issue short-lived, self-rotating installation tokens (1-hour lifespan).
- JCasC GitHub App Configuration:
jcasc/github-app-credentials.yamlconfigures GitHub App ID, Private Key, and automated token renewal natively in Jenkins.
| Recommendation | Target Area | Business Value | Implemented Artifacts |
|---|---|---|---|
| Cosign + SBOM (SLSA 3) | Supply Chain Security | Cryptographic proof of origin & automated vulnerability tracking | cosignSign.groovy, openshift-image-signature-policy.yaml |
| External Secrets Operator | Zero-Trust Secrets | Eliminates plaintext secrets from Git repositories | cluster-secret-store-vault.yaml, secrets/ |
| GitHub App Auth | Identity & Security | Short-lived, self-rotating credentials with least privilege | github-app-credentials.yaml |
| ArgoCD PR Generator | Developer Experience | 1-click preview environments per pull request | applicationset-pull-request-preview.yaml |
| Argo Rollouts (Canary) | Production Resiliency | Automated metric analysis with zero-downtime rollback | rollout-canary-jhipster.yaml, analysis-template-prometheus.yaml |
To cleanly delete all Helm releases, ConfigMaps, and namespaces:
./destroy.sh
# or
make destroyTo perform a complete wipe and redeployment:
./reinstall.sh
# or
make reinstallArchitectural deep dives, video walkthroughs, and technical shorts for jenkins-git-parameter and multi-cluster GitOps promotion are hosted on the Nubenetes YouTube Channel (@nubenetes).
π Full-Length Technical Deep Dives & Explanations
- π Link: https://www.youtube.com/watch?v=qntcMvzBx4w
- π Language: English (Original Audio)
- β±οΈ Duration: 7:52
- π·οΈ Domain: CI/CD Decoupling, SCM Blind Spot & Evolution to Pure GitOps
- π Full Description:
π Architectural breakdown of the SCM pre-execution render paradox when using Jenkins git-parameter plugins across multiple repositories, and how shifting to a pure GitOps model permanently solves it.
π Core Discussion Points: β’ The Pre-Execution Render Paradox: Why UI parameter dropdowns fail before checkout in multi-repo topologies. β’ Jenkins as a Pure Build Factory: Compiling immutable containers, scanning with Trivy, and cryptographically signing with Cosign (SLSA Level 3). β’ ArgoCD Multi-Cluster Synchronization: Replacing push deployment scripts with pull-based internal controllers. β’ Dynamic Tuning without Throttling: Eliminating pod-level CPU limits to prevent Linux CFS bandwidth throttling on multi-threaded runtimes.
π Architecture Video Shorts & Guides
- π Link: https://www.youtube.com/shorts/0Zd7zNSae48
- π Language: English (Original Audio)
- β±οΈ Duration: 1:13
- π·οΈ Domain: Immutable Container Promotion & Jenkins Parameterization
- π Full Description:
π Why rebuilding code for production risks sneaking in subtle bugs, and how immutable container promotion with Jenkins Git Parameters prevents it.
π Key Concepts: β’ Strict blocking of recompilation during production release runs. β’ Dynamic scanning of repository tags with the Jenkins Git Parameter plugin. β’ Promoting pre-validated container images between dev and prod registries via Skopeo. β’ Bumping GitOps manifests for bit-for-bit parity.
π Architectural Blueprint (This Repository): https://github.com/nubenetes/jenkins-git-parameter π Next Architectural Stage (Pure GitOps without Jenkins parameter plugins): https://github.com/nubenetes/jenkins-without-git-parameter
- π Link: https://www.youtube.com/shorts/iKTgIsbQCcQ
- β±οΈ Duration: 1:23
- π Full Description:
π Why leading platform engineering teams eliminate manual UI deploy buttons, moving from fragile multi-repo parameter dropdowns to webhook-triggered CI and pull-based ArgoCD synchronization.
- π Link: https://www.youtube.com/shorts/0-NIxNk7cuM
- β±οΈ Duration: 1:12
- π Full Description:
π How GitOps completely inverts traditional deployment architecture: replacing fragile external push scripts with an internal ArgoCD controller pulling state from Git without exposing cluster credentials.
The design patterns and technical configurations implemented in this repository are based on official documentation, security frameworks, and industry standards:
-
Jenkins Core, IaC & Job DSL:
- Jenkins Official Helm Chart Repository
- Jenkins Configuration as Code (JCasC) Reference
- Jenkins Job DSL Plugin API & Dynamic Multi-Remote Guide
- Jenkins Git Parameter Plugin Documentation
- Jenkins Declarative Pipeline Syntax Specification
- Jenkins Official Blue Ocean Deprecation Notice
- Jenkins Pipeline Graph View Plugin
-
Red Hat OpenShift 4.20+ Hardening & Networking:
-
ArgoCD 3.5 & Multi-Cluster GitOps:
-
Progressive Delivery & Automated Rollouts:
-
Supply Chain Security & Attestation (SLSA Level 3):
- Sigstore / Cosign: Container Image Signing & Verification
- SLSA (Supply-chain Levels for Software Artifacts) Specification
- in-toto Framework for Supply Chain Integrity
- Anchore Syft: Software Bill of Materials (SBOM) Generation
- CycloneDX SBOM Standard Specification
- Aqua Security Trivy Vulnerability & Misconfiguration Scanner
- Skopeo Container Image Copy Tool
-
Zero-Trust Secrets & Identity Management:
-
ITSM, Developer Portals & CMDB Integration:
-
Observability & Distributed Tracing: