Integrating Tekton CI/CD with Argo CD for GitOps: A Step‑by‑Step Guide
This tutorial shows how to refactor a Tekton‑based CI/CD pipeline by extracting Helm chart templates into a separate repository, configuring an Argo CD AppProject and Application, adding sync and manifest‑update tasks, customizing health checks, and finally achieving a streamlined GitOps workflow on Kubernetes.
Previously we built a CI/CD pipeline with Tekton where the CD stage (deploy and rollback) was implemented as Tekton tasks. In this guide we replace that CD part with Argo CD using a GitOps approach.
First, the Helm chart directory from the source repository http://git.k8s.local/course/devops-demo.git is extracted into a dedicated repo http://git.k8s.local/course/devops-demo-deploy so that Argo CD can manage it directly.
In Argo CD we create an AppProject named demo that defines sourceRepos , destinations , and roles . The manifest looks like:
apiVersion: argoproj.io/v1alpha1
kind: AppProject
metadata:
name: demo
namespace: argocd
spec:
destinations:
- namespace: '*'
server: https://kubernetes.default.svc
sourceRepos:
- http://git.k8s.local/course/devops-demo-deploy.gitAfter the project is created, an Application called devops-demo is defined to point to the Helm chart path and use my-values.yaml for parameters:
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: devops-demo
namespace: argocd
spec:
destination:
namespace: default
server: 'https://kubernetes.default.svc'
project: demo
source:
path: helm
repoURL: 'http://git.k8s.local/course/devops-demo-deploy.git'
targetRevision: HEAD
helm:
parameters:
- name: replicaCount
value: '2'
valueFiles:
- my-values.yamlThe application initially appears in OutOfSync because it has not been applied yet.
Next we modify the original Tekton pipeline.yaml . The final deploy and rollback tasks are removed; after the Docker image is built we only need to update the Helm values file and trigger an Argo CD sync.
A new Task named sync is added to log in to Argo CD and run argocd app sync and argocd app wait :
apiVersion: tekton.dev/v1alpha1
kind: Task
metadata:
name: sync
spec:
volumes:
- name: argocd-secret
secret:
secretName: $(inputs.params.argocd_secret)
params:
- name: argocd_url
description: "The URL of the ArgoCD server"
- name: argocd_secret
description: "Secret containing username/password for ArgoCD"
- name: app_name
description: "Name of the Argo CD application"
- name: app_revision
default: "HEAD"
description: "Revision of the application"
steps:
- name: deploy
image: argoproj/argocd
volumeMounts:
- name: argocd-secret
mountPath: /var/secret
command: ["sh"]
args:
- -ce
- |
set -e
echo "update commit id"
argocd login --insecure $(params.argocd_url) --username $(/bin/cat /var/secret/username) --password $(/bin/cat /var/secret/password)
argocd app sync $(params.app_name) --revision $(params.app_revision)
argocd app wait $(params.app_name) --healthTo modify the Helm image.tag we create a Task called change-manifests that checks out the manifest repo, updates my-values.yaml with yq , commits, and pushes the change.
apiVersion: tekton.dev/v1beta1
kind: Task
metadata:
name: change-manifests
spec:
params:
- name: git_url
description: Git repository containing manifest files to update
- name: git_email
default: [email protected]
- name: git_name
default: Tekton Pipeline
- name: git_manifest_dir
description: Manifests files dir
- name: tool_image
default: cnych/helm-kubectl-curl-git-jq-yq
- name: image_tag
description: Deploy docker image tag
steps:
- name: git-push
image: $(params.tool_image)
env:
- name: GIT_USERNAME
valueFrom:
secretKeyRef:
name: gitlab-auth
key: username
optional: true
- name: GIT_PASSWORD
valueFrom:
secretKeyRef:
name: gitlab-auth
key: password
optional: true
command: ["/bin/bash"]
args:
- -c
- |
set -eu
git config --global user.email "$(params.git_email)"
git config --global user.name "$(params.git_name)"
git clone --branch master --depth 1 http://${GIT_USERNAME}:${GIT_PASSWORD}@$(params.git_url) repo
cd "repo/$(params.git_manifest_dir)"
yq w --inplace my-values.yaml 'image.tag' "$(params.image_tag)"
if ! git diff-index --quiet HEAD --; then
git add .
git commit -m "helm values updated by tekton pipeline in change-manifests task"
git push
else
echo "no changes, git repository is up to date"
fiThe updated pipeline now consists of the following tasks (in order): clone , test , build , docker , manifests (change‑manifests), and finally sync . All required parameters for the Argo CD integration (URL, secret, app name, revision) are passed through the pipeline.
A Kubernetes Secret named argocd-auth stores the Argo CD admin credentials:
apiVersion: v1
kind: Secret
metadata:
name: argocd-auth
type: Opaque
stringData:
username: admin
password: admin321The Tekton TriggerTemplate is updated to supply the new parameters (git URLs, image, tag, Argo CD details) when a GitLab push event occurs.
After the pipeline runs, the application is deployed, but the Argo CD health check may stay in Progressing because the default Ingress health rule expects a non‑empty status.loadBalancer.ingress . We customize the health check by editing the argocd-cm ConfigMap and adding a Lua script that always returns Healthy for extensions/Ingress resources.
# kubectl edit cm -n argocd argocd-cm
apiVersion: v1
data:
resource.customizations: |
extensions/Ingress:
health.lua: |
hs = {}
hs.status = "Healthy"
return hsWith the custom health rule the application shows as healthy, and rollbacks can be performed directly from the Argo CD UI.
Finally, the article provides screenshots of the pipeline run, the Argo CD UI, and a diagram summarizing the Tekton‑Argo CD GitOps workflow.
DevOps Cloud Academy
Exploring industry DevOps practices and technical expertise.
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.