How to Build a Secure Centralized Push‑Based GitOps Pipeline with GitLab CI
This article explains how to replace a naïve push‑based GitOps workflow with a centralized, permission‑controlled deployment pipeline using GitLab CI, detailing the architecture, advantages such as improved security and maintainability, and providing complete YAML examples for both service and central pipelines.
Introduction
When a team cannot or does not want to adopt Argo CD Image Updater, a push‑based GitOps workflow is still possible if the push operation is performed by a dedicated, centrally managed pipeline rather than by each service’s CI job.
Why a naive push model fails
Directly letting every service CI modify the GitOps repository scatters deployment logic and high‑privilege write tokens, leading to unclear responsibilities, over‑privileged access, and difficult maintenance.
Centralized Deployment Pipeline Architecture
Key principles
Responsibility separation Service CI builds and pushes the container image, then stops.
Trigger and delegation After the image is ready, Service CI triggers the central pipeline via an API call, webhook, or GitLab downstream pipeline trigger instead of editing the GitOps repo itself.
Centralized authority The central pipeline is the sole entity with write access to the GitOps repository. It receives parameters such as application name, image tag, and target environment and performs all Git operations in a standardized way.
Advantages of the refined push model
Security improvement The high‑privilege token for the GitOps repo is stored only in the central pipeline’s CI/CD variables, dramatically reducing the attack surface.
True decoupling Service CI no longer needs to understand Kustomize, Helm, or any Git logic; it only signals that the image is ready for deployment.
High maintainability (DRY) All scripts that modify manifests—whether Kustomize, Helm, or plain YAML—are centralized. Switching tools (e.g., from sed to yq ) requires a single change.
Powerful flow control and extensibility The central pipeline can host complex deployment strategies such as manual approvals, integration testing, or canary releases with tools like Flagger.
Manual approval – add a job with when: manual.
Integration testing – run a test job before merging deployment changes.
Canary release – integrate with Flagger for progressive rollouts.
Hands‑On Example: Implementing with GitLab CI
1. Service CI configuration ( service-repo/.gitlab-ci.yml )
The service pipeline builds the image and then triggers the central pipeline using GitLab’s trigger keyword.
stages:
- build
- deploy
build-image:
stage: build
script:
- echo "Building and pushing image docker.io/my-org/my-app:$CI_COMMIT_TAG..."
# (docker build & push commands omitted)
only:
- tags
trigger-deployment:
stage: deploy
trigger:
project: 'your-group/gitops-repo' # GitOps repository path
branch: 'main'
strategy: depend
variables:
APP_NAME: "my-app"
APP_IMAGE_TAG: $CI_COMMIT_TAG
TARGET_ENV: "staging"
only:
- tags2. Central deployment pipeline ( gitops-repo/.gitlab-ci.yml )
This pipeline receives the variables and updates the manifest in the target environment.
workflow:
rules:
- if: $APP_NAME && $APP_IMAGE_TAG && $TARGET_ENV # Run only when triggered
stages:
- update-manifest
update-kustomization-manifest:
stage: update-manifest
image:
name: alpine/k8s:1.23.5 # Contains kubectl and kustomize
script:
- echo "Updating $APP_NAME in $TARGET_ENV to tag $APP_IMAGE_TAG"
- git config --global user.email "[email protected]"
- git config --global user.name "GitLab CI"
- cd apps/$TARGET_ENV/$APP_NAME
- kustomize edit set image my-app=docker.io/my-org/my-app:$APP_IMAGE_TAG
- git add kustomization.yaml
- git commit -m "ci: Bump $APP_NAME in $TARGET_ENV to $APP_IMAGE_TAG"
- git push https://gitlab-ci-token:[email protected]/your-group/gitops-repo.git HEAD:mainNote: $GITOPS_REPO_TOKEN is a Project Access Token with write permission, stored securely in the CI/CD variables of the gitops-repo project.
Conclusion
A centralized push model provides a pragmatic, secure, and maintainable alternative to the pure pull‑based Argo CD Image Updater. By consolidating deployment responsibilities in a single authoritative pipeline, teams retain the proactive nature of push while preserving the GitOps principle of separation of concerns.
Ops Development & AI Practice
DevSecOps engineer sharing experiences and insights on AI, Web3, and Claude code development. Aims to help solve technical challenges, improve development efficiency, and grow through community interaction. Feel free to comment and discuss.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
