DEPLOY
Platform Ops DevOps CI/CD & GitOps
Issue #052 · August 2026

CI/CD & GITOPS
DEEP-DIVE

Pipelines · ArgoCD/Flux · Security Gates · Deploy Strategy

From commit to production: building pipelines that don't lie to you, letting Git — not a script — be the source of truth for what's running, gating builds before they ship, and rolling out changes without betting the whole fleet at once.

15
Concepts Covered
5
Pipeline Layers
2
GitOps Engines
CI Pipelines3
Jenkinsfile.gitlab-ci.ymlStages
GitOps3
ArgoCDFluxReconciliation
Pipeline Security3
SASTImage ScanSBOM
Deploy Strategies3
CanaryBlue-GreenRollback
Secrets & Artifacts3
VaultSealed SecretsRegistry
Jenkinsfile GitLab CI ArgoCD Flux Reconciliation Loop SAST / DAST Trivy Image Scan SBOM Canary Rollout Blue-Green Deploy HashiCorp Vault Sealed Secrets Jenkinsfile GitLab CI ArgoCD Flux Reconciliation Loop SAST / DAST Trivy Image Scan SBOM Canary Rollout Blue-Green Deploy HashiCorp Vault Sealed Secrets

COMMIT TO PRODUCTION

Five stages between a developer's push and a change running in the cluster — each with its own failure modes and its own tooling.

🔴 Build & Test
Jenkins / GitLab CI
Unit / Integration Tests
Container Build
Artifact Push
Pipeline as Code
🟠 GitOps Sync
Git Repo (Desired State)
ArgoCD / Flux Controller
Reconciliation Loop
Drift Detection
Auto / Manual Sync
🔵 Security Gates
SAST (code)
Image Scanning
SBOM Generation
Policy Admission (OPA)
DAST (runtime)
🟢 Rollout
Canary
Blue-Green
Progressive Delivery
Automated Rollback
Health Gates
🟣 Secrets / Artifacts
Vault / Sealed Secrets
Container Registry
Image Signing (cosign)
Helm / OCI Charts
Retention Policy
Deep-Dive

CI/CD REFERENCE

Click any layer to explore concepts, pipeline snippets, and production-tested guidance.

CI PIPELINES — JENKINS & GITLAB CI
Turning a commit into a tested, versioned, deployable artifact
3 Concepts
🏗️
Pipeline as Code
The pipeline definition lives in the repo it builds — versioned, reviewed, and reproducible, instead of a job configured by hand in a UI.
Must Know
Must Know
Jenkinsfile (declarative)
Jenkinsfile
pipeline {
  agent any
  stages {
    stage('Build') { steps { sh 'mvn package' } }
    stage('Test')  { steps { sh 'mvn test' } }
    stage('Image') { steps { sh 'docker build -t $REGISTRY/app:$TAG .' } }
  }
}
.gitlab-ci.yml
yaml
stages: [build, test, image, deploy]
build:
  stage: build
  script: [mvn package]
image:
  stage: image
  script: [docker build -t $CI_REGISTRY_IMAGE:$CI_COMMIT_SHORT_SHA .]
⚖️
Jenkins vs GitLab CI
Both run stages of shell commands in containers or agents. The difference is mostly about coupling, runner model, and plugin ecosystem.
Important
Important
TraitJenkinsGitLab CI
CouplingStandalone server, any SCMTightly integrated with GitLab repos/MRs
ConfigJenkinsfile (Groovy DSL).gitlab-ci.yml (pure YAML)
RunnersStatic/dynamic agents, plugin-managedGitLab Runners — shared, group, or project-specific
Ecosystem1800+ plugins, huge but uneven qualityBuilt-in features (SAST, container scanning, etc.)
Ops burdenYou maintain the Jenkins master + pluginsLower if using GitLab.com or GitLab-managed runners
Pipeline Performance & Caching
A slow pipeline is a productivity tax paid every single commit. Cache dependencies, parallelize what doesn't depend on itself.
Operations
Recommended
1
Cache package manager directories (.m2, node_modules, pip wheel cache) between runs
2
Run independent test suites (unit, lint, security scan) in parallel stages, not sequentially
3
Use layer caching for Docker builds — order Dockerfile instructions from least to most frequently changed
4
Fail fast: run the cheapest checks (lint, unit tests) before the expensive ones (integration, image build)
GITOPS — ARGOCD & FLUX
Git is the single source of truth; a controller makes the cluster match it
3 Concepts
🔁
Push vs Pull Deployment
Traditional CI/CD pushes changes into the cluster with kubectl/helm from the pipeline. GitOps flips it: an in-cluster agent pulls and reconciles.
Must Know
Must Know
Push (Traditional CI/CD)
1Pipeline builds image
2Pipeline runs kubectl apply / helm upgrade
3Pipeline needs cluster credentials
4No record of drift if someone edits the cluster directly
Pull (GitOps)
1Pipeline builds image, updates a manifest repo
2ArgoCD/Flux inside the cluster notices the Git change
3Controller applies it — no external credentials needed
4Continuously reconciles — drift is detected and can self-heal
⚖️
ArgoCD vs Flux
Both implement the GitOps pattern; they differ in UI philosophy and how tightly they integrate with the rest of the Flux/Argo ecosystems.
Important
Important
TraitArgoCDFlux
UIRich web UI, app-of-apps visual treeCLI/API-first, UI via Weave GitOps (optional)
Model"Application" CRD per deployable unitKustomization/HelmRelease CRDs, more composable
Multi-tenancyProjects with RBAC built inNamespace-based, relies more on K8s RBAC directly
Best fitTeams that want visibility/UI for many appsTeams already deep in Flux/Kustomize, GitOps purists
ArgoCD Application (excerpt)
yaml
apiVersion: argoproj.io/v1alpha1
kind: Application
spec:
  source: {repoURL: git@repo:billing-manifests.git, path: overlays/prod}
  syncPolicy: {automated: {prune: true, selfHeal: true}}
🧬
The Two-Repo Pattern
Application source code and Kubernetes manifests live in separate repos — the pipeline's job ends where GitOps begins.
Pattern
Recommended
Why Split Repos
🔵App repo change frequency ≠ deploy frequency — decouples "code changed" from "environment changed"
🔵Manifest repo becomes the audit trail: every prod change is a diffable commit
Typical Flow
1
CI builds image, tags it app:sha-abc123
2
CI bumps the image tag in the manifest repo (via a bot commit or PR)
3
ArgoCD/Flux picks up the manifest change and syncs the cluster
PIPELINE SECURITY GATES
Catching problems before they're an image running in production
3 Concepts
🔬
SAST, Dependency & Image Scanning
Three different scanners catch three different classes of problems — code flaws, vulnerable dependencies, and vulnerable base images.
Must Know
Must Know
Scan Types
🔴SAST (Static Application Security Testing) — scans your own source for code-level flaws (SonarQube, Semgrep)
🟠SCA (dependency scanning) — flags known CVEs in third-party libraries (Snyk, Dependabot)
🟠Container/image scanning — checks the built image's OS packages and layers (Trivy, Grype)
CI stage: image scan gate
trivy
trivy image --exit-code 1 --severity CRITICAL,HIGH $REGISTRY/app:$TAG
# Non-zero exit fails the pipeline — no image with a critical CVE ships
📋
SBOM & Supply Chain
A Software Bill of Materials lists every component in the image — the artifact you need when the next zero-day drops and you must answer "are we affected?" in minutes, not days.
Important
Important
1
Generate an SBOM per build (syft $IMAGE -o spdx-json) and store it alongside the artifact
2
Sign images with cosign so deployment can verify provenance before running them
3
When a CVE drops, grep SBOMs across all past builds instead of re-scanning everything from scratch
🚧
Admission Control (OPA / Kyverno)
The last gate isn't in the pipeline at all — it's at the cluster's API server, refusing to admit anything that violates policy, pipeline or not.
Runtime
Recommended
🔵Block unsigned images, images with :latest tag, or missing resource limits — before they're admitted
🔵Kyverno and OPA/Gatekeeper both implement this as ValidatingAdmissionWebhooks — policy as code, versioned in Git like everything else
DEPLOYMENT STRATEGIES
Shipping a change without betting the entire fleet on it at once
3 Concepts
🐤
Canary Releases
Route a small slice of traffic to the new version, watch the golden signals, and only then ramp it up — or auto-rollback if it looks bad.
Must Know
Must Know
Argo Rollouts canary step (excerpt)
yaml
strategy:
  canary:
    steps:
    - {setWeight: 10}
    - {pause: {duration: 5m}}
    - {setWeight: 50}
    - {pause: {duration: 10m}}
    - {setWeight: 100}
Why It Works
🔴Blast radius of a bad release is capped at the canary weight, not 100% of traffic
🟠Pair with automated analysis (Argo Rollouts + Prometheus) to auto-abort on error-rate regressions
🔵🟢
Blue-Green Deployment
Run two full environments side by side; switch traffic all at once by flipping a service selector or load balancer target.
Important
Important
Trade-offs vs Canary
🟠Instant rollback — flip the selector back, no gradual ramp needed
🟠Costs 2x resources while both environments are live
🔵All-or-nothing traffic switch — no gradual exposure to catch subtle regressions
Best Fit
1
Database-schema-sensitive releases where you want an instant, clean cutover
2
Low-traffic or batch services where gradual canary weighting adds little value
Automated Rollback
A rollback that requires a human to notice, decide, and type a command is a rollback that happens too late.
Reliability
Recommended
1
Wire canary analysis to real SLIs — error rate, p99 latency — not just pod readiness
2
In GitOps, rollback is a git revert on the manifest repo — the controller reconciles back automatically
3
Keep the previous ReplicaSet/revision around (kubectl rollout undo) as the manual fallback of last resort
SECRETS & ARTIFACT MANAGEMENT
Nothing sensitive belongs in a Git diff — including in your GitOps manifest repo
3 Concepts
🔑
The GitOps Secrets Problem
GitOps wants everything in Git — but plaintext secrets in Git is a non-starter. Two patterns solve this without breaking the "Git is truth" model.
Must Know
Must Know
Sealed Secrets
🔴Encrypt the secret client-side with a cluster-specific public key
🟠Commit the encrypted blob to Git safely — only the in-cluster controller can decrypt it
External Secrets Operator + Vault
1
Secret values never touch Git at all — they stay in Vault/AWS Secrets Manager/Azure Key Vault
2
Only a reference (which secret, which path) is committed — an ExternalSecret CRD
3
The operator syncs the real value into a native K8s Secret at runtime
📦
Artifact & Registry Hygiene
Images and Helm charts pile up fast — retention policy is not optional once storage bills start showing up.
Important
Important
1
Tag images with commit SHA, never rely on :latest in any deployed manifest
2
Set a retention policy: keep last N tags per branch, expire untagged/dangling images automatically
3
Package Helm charts as OCI artifacts in the same registry — one system to secure and back up, not two
✍️
Image Signing & Verification
Proving an image came from your pipeline and hasn't been tampered with since — closing the loop the SBOM opened.
Supply Chain
Recommended
cosign
cosign sign --key cosign.key $REGISTRY/app:$TAG
cosign verify --key cosign.pub $REGISTRY/app:$TAG
# Pair with a Kyverno/OPA policy that rejects unsigned images at admission
Decision Guide

WHICH ROLLOUT STRATEGY?

A quick lookup for the question that comes up in almost every release-planning conversation.

SituationStrategyWhy
High-traffic user-facing APICanaryGradual exposure catches regressions before they hit everyone
Database schema migration involvedBlue-GreenClean cutover avoids two schema versions running concurrently
Internal batch/cron jobRolling UpdateSimplicity wins — low blast radius already, no user-facing traffic
Regulatory / compliance-critical releaseBlue-Green + manual gateInstant rollback and a clear approval checkpoint before cutover
Frequent, low-risk microserviceCanary + auto-promoteAutomated analysis lets you ship many times a day safely

COMMAND CHEATSHEET

Jenkins
jenkins-cli build <job> -f
jenkins-cli console <job> -f
curl -s $JENKINS_URL/job/<job>/lastBuild/api/json
GitLab CI
gitlab-runner exec docker build
glab ci status
glab ci view
ArgoCD
argocd app sync <app>
argocd app diff <app>
argocd app rollback <app> <revision>
argocd app get <app> -o wide
Flux
flux get kustomizations
flux reconcile source git <name>
flux logs --follow
Rollouts / Rollback
kubectl argo rollouts get rollout <name> --watch
kubectl rollout undo deploy/<name>
kubectl rollout history deploy/<name>
Secrets / Supply Chain
kubeseal --format yaml < secret.yaml
trivy image $IMAGE
syft $IMAGE -o spdx-json
VA
Vishal Abhinav
Platform Ops Engineer · @6D Technologies · Ops Newsletter — Issue #052