Cloud Native 14 min read

GitOps Workflow Example with Argo CD, GitLab CI, and Kubernetes

This article provides a step‑by‑step guide to implementing a GitOps workflow on a Kubernetes cluster using Argo CD and GitLab CI, covering Argo CD installation, Helm deployment, application configuration, CI/CD pipeline definition, and deployment to dev and prod environments.

DevOps Cloud Academy
DevOps Cloud Academy
DevOps Cloud Academy
GitOps Workflow Example with Argo CD, GitLab CI, and Kubernetes

GitOps is a declarative continuous‑delivery approach that stores the desired state of a Kubernetes cluster in a Git repository. This guide demonstrates a complete GitOps workflow using Argo CD as the delivery engine and GitLab CI for building and publishing container images.

Argo CD installation : After ensuring a reachable Kubernetes cluster, install the ingress-nginx controller, then add the Argo CD Helm chart and install it with a custom values.yaml that enables an NGINX ingress.

kubectl create ns argocd
helm repo add argo https://argoproj.github.io/argo-helm
helm install argocd -n argocd argo/argo-cd --values values.yaml
server:
  ingress:
    enabled: true
    annotations:
      kubernetes.io/ingress.class: "nginx"
      nginx.ingress.kubernetes.io/force-ssl-redirect: "true"
      nginx.ingress.kubernetes.io/ssl-passthrough: "true"
      nginx.ingress.kubernetes.io/backend-protocol: "HTTPS"
    hosts:
    - argocd.k8s.local

After the Helm release is ready, verify the pods are running and retrieve the initial admin password:

kubectl get pods -n argocd -l app.kubernetes.io/name=argocd-server -o name | cut -d'/' -f 2

GitLab project configuration : Create a GitLab repository for a simple Go web application, then define CI/CD variables (e.g., CI_REGISTRY, CI_REGISTRY_IMAGE, CI_REGISTRY_USER, CI_REGISTRY_PASSWORD, CI_USERNAME, CI_PASSWORD) in the project settings.

Argo CD application manifests : Two Application CRDs are created—one for the development namespace and one for production. They point to the Git repository and the respective deployment/dev or deployment/prod directories.

# gitops-demo-app.yaml
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: web-app-dev
  namespace: argocd
spec:
  project: default
  source:
    repoURL: http://git.k8s.local/course/gitops-webapp.git
    targetRevision: HEAD
    path: deployment/dev
  destination:
    server: https://kubernetes.default.svc
    namespace: dev
  syncPolicy:
    automated:
      prune: true
---
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: web-app-prod
  namespace: argocd
spec:
  project: default
  source:
    repoURL: http://git.k8s.local/course/gitops-webapp.git
    targetRevision: HEAD
    path: deployment/prod
  destination:
    server: https://kubernetes.default.svc
    namespace: prod
  syncPolicy:
    automated:
      prune: true

Apply the manifests: kubectl apply -f gitops-demo-app.yaml GitLab CI pipeline : The .gitlab-ci.yml defines four stages— build, publish, deploy-dev, and deploy-prod. The build stage compiles the Go binary, the publish stage builds a Docker image with Kaniko and pushes it to the registry, and the deploy stages update the Kustomize manifests and push the changes back to Git.

stages:
  - build
  - publish
  - deploy-dev
  - deploy-prod

build:
  stage: build
  image:
    name: golang:1.13.1
  script:
    - go build -o main main.go
  artifacts:
    paths:
      - main
  variables:
    CGO_ENABLED: 0

publish:
  stage: publish
  image:
    name: cnych/kaniko-executor:v0.22.0
    entrypoint: [""]
  script:
    - echo "{\"auths\":{\"$CI_REGISTRY\":{\"username\":\"$CI_REGISTRY_USER\",\"password\":\"$CI_REGISTRY_PASSWORD\"}}}" > /kaniko/.docker/config.json
    - /kaniko/executor --context $CI_PROJECT_DIR --dockerfile ./Dockerfile --destination $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA
  dependencies:
    - build
  only:
    - master

deploy-dev:
  stage: deploy-dev
  image: cnych/kustomize:v1.0
  before_script:
    - git remote set-url origin http://$CI_USERNAME:[email protected]/course/gitops-webapp.git
    - git config --global user.email "[email protected]"
    - git config --global user.name "GitLab CI/CD"
  script:
    - git checkout -B master
    - cd deployment/dev
    - kustomize edit set image $CI_REGISTRY_IMAGE:$CI_COMMIT_SHORT_SHA
    - git commit -am '[skip ci] DEV image update'
    - git push origin master
  only:
    - master

deploy-prod:
  stage: deploy-prod
  image: cnych/kustomize:v1.0
  before_script:
    - git remote set-url origin http://$CI_USERNAME:[email protected]/course/gitops-webapp.git
    - git config --global user.email "[email protected]"
    - git config --global user.name "GitLab CI/CD"
  script:
    - git checkout -B master
    - git pull origin master
    - cd deployment/prod
    - kustomize edit set image $CI_REGISTRY_IMAGE:$CI_COMMIT_SHORT_SHA
    - git commit -am '[skip ci] PROD image update'
    - git push origin master
  only:
    - master
  when: manual

When a developer pushes changes to the master branch, the pipeline builds a new image, updates the Kustomize manifests, and Argo CD automatically syncs the changes to the dev namespace. A manual trigger can promote the same image to the prod namespace.

Both environments are exposed via Ingress; adding the hostnames to /etc/hosts allows local browsers to reach http://webapp.dev.k8s.local/ and http://webapp.prod.k8s.local/. Updating the source code (e.g., changing the welcome message) and committing triggers the pipeline, resulting in a live update of the running application.

References: Weaveworks GitOps overview, Argo CD documentation, GitLab CI/CD YAML reference, a medium article on GitOps with Argo CD, and the demo repository https://github.com/cnych/gitops-webapp-demo.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

ci/cdGitLab CIGitOpshelmArgo CD
DevOps Cloud Academy
Written by

DevOps Cloud Academy

Exploring industry DevOps practices and technical expertise.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.