DEV Community

Cover image for Building a CD Pipeline with GitOps and ArgoCD 🛠️
Panchanan Panigrahi
Panchanan Panigrahi

Posted on • Edited on

Building a CD Pipeline with GitOps and ArgoCD 🛠️

Project Objective 🚀

This project aims to establish a robust CD pipeline using a public repository and a Docker image, leveraging the power of GitOps with ArgoCD.

Prerequisites:

  1. Minikube Cluster
  2. kubectl
  3. ArgoCD
  4. GitHub Account
  5. Dockerhub Account
  6. Docker Engine

In case you are stuck somewhere you can check my repo for this project. Github repo link: https://github.com/panchanandevops/argocd-public

If you have not installed argocd yet, you can check out my Introducing to ArgoCD Blog.

Creating Our Own Docker Public Image

To establish a continuous delivery (CD) pipeline, let's create a public GitHub repository named "argocd-public." Clone this repository to your local machine.

For simulating a CD pipeline, we require a Docker image. We'll leverage the nginx Docker image and transform it into our custom Docker image named "mynginx."

To build this image, execute the following commands. Make sure to replace "your_username" with your actual Dockerhub username.

docker login
docker pull nginx:1.25.3
docker tag nginx:1.25.3 your_username/mynginx:v0.1.0
docker push your_username/mynginx:v0.1.0
Enter fullscreen mode Exit fullscreen mode

Set Up the Project Directories 📁

This will be the tree of our argocd public project,

argocd-public
├── k8s-resources
│ └── my-app
│ ├── namespace.yaml
│ └── deployment.yaml
└── argocd-application-files
└── application.yaml

To set up the project structure Execute the following commands in the argocd-public directory:

mkdir k8s-resources | mkdir k8s-resources/my-app | touch k8s-resources/my-app/namespace.yaml k8s-resources/my-app/deployment.yaml
Enter fullscreen mode Exit fullscreen mode
mkdir argocd-application-files | touch argocd-application-files/application.yaml
Enter fullscreen mode Exit fullscreen mode

YAML Code for Kubernetes Resources

Add the following code to namespace.yaml to create a namespace called foo:

---
apiVersion: v1
kind: Namespace
metadata:
  name: foo
Enter fullscreen mode Exit fullscreen mode

Add the following code to deployment.yaml to create a deployment:

---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx
  namespace: foo
  labels:
    app: nginx
spec:
  replicas: 1
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
        - name: nginx
          image: your_username/mynginx:v0.1.0
          ports:
            - containerPort: 80
Enter fullscreen mode Exit fullscreen mode

This Kubernetes YAML defines a Deployment named "nginx" in the namespace "foo" creating one replica of the "nginx" application. It specifies a container using the image "your_username/mynginx:v0.1.0" exposing port 80.

ArgoCD Application Files

Execute the following commands in the argocd-public directory:

Add the following YAML code inside application.yaml:

---
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: my-app
  namespace: argocd
  finalizers:
    - resources-finalizer.argocd.argoproj.io
spec:
  project: default
  source:
    repoURL: https://github.com/your_username/argocd-public.git
    targetRevision: HEAD
    path: k8s-resources/my-app
  destination:
    server: https://kubernetes.default.svc
  syncPolicy:
    automated:
      prune: true
      selfHeal: true
      allowEmpty: false
    syncOptions:
      - Validate=true
      - CreateNamespace=false
      - PrunePropagationPolicy=foreground
      - PruneLast=true
Enter fullscreen mode Exit fullscreen mode

Then push these resources to your GitHub repository.

Understanding CRD of ArgoCD 🧐

Let's break down the application.yaml file and understand how ArgoCD works behind the scenes.

apiVersion: argoproj.io/v1alpha1
kind: Application
Enter fullscreen mode Exit fullscreen mode

Here we are defining apiVersion and kind according to the ArgoCD CRD.

metadata:
  name: my-app
  namespace: argocd
  finalizers:
    - resources-finalizer.argocd.argoproj.io
Enter fullscreen mode Exit fullscreen mode

This YAML defines metadata for a Kubernetes resource named "my-app" in the "argocd" namespace, including a finalizer to be executed when deleting the resource.

project: default
source:
  repoURL: https://github.com/your_username/argocd-public.git
  targetRevision: HEAD
  path: k8s-resources/my-app
destination:
  server: https://kubernetes.default.svc
Enter fullscreen mode Exit fullscreen mode

This ArgoCD project configuration specifies a project named "default" with a Git repository as the source (https://github.com/your_username/argocd-public.git). The target revision is set to HEAD, and the Kubernetes manifest files are located at the path "k8s-resources/my-app." The destination is a Kubernetes cluster specified by the server URL https://kubernetes.default.svc.

syncPolicy:
  automated:
    prune: true
    selfHeal: true
    allowEmpty: false
Enter fullscreen mode Exit fullscreen mode

The syncPolicy section of this ArgoCD project configuration enables automated synchronization with the specified Git repository, allowing pruning of resources, self-healing, and disallowing synchronization of empty manifests.

syncOptions:
  - Validate=true
  - CreateNamespace=false
  - PrunePropagationPolicy=foreground
  - PruneLast=true
Enter fullscreen mode Exit fullscreen mode

The syncOptions section in this ArgoCD project configuration provides specific synchronization options, including validation, avoiding the creation of namespaces, specifying pruning propagation policy as "foreground" and enabling the pruning of the last resource during synchronization.

Now that we understand how ArgoCD works, let's apply application.yaml in the local Kubernetes cluster. This is the only time we will apply kubectl apply manually.

kubectl apply -f argocd-public/argocd-application-files/application.yaml
Enter fullscreen mode Exit fullscreen mode

You can verify your Kubernetes resources by applying these commands:

kubectl get namespaces
kubectl get deployments -n foo
Enter fullscreen mode Exit fullscreen mode

For subsequent releases, update the image section of the deployment to the second version of the image. Push the changes to your GitHub repository. After approximately 3 minutes, ArgoCD will automatically deploy the updated deployment with the second version of the mynginx image.

Acknowledgment 🙏

Special thanks to Anton Putra for sharing valuable insights and knowledge. You can find Anton on Anton Putra's YouTube channel where he provides educational content and tutorials.

Conclusion 🚀

In this project, we've crafted a GitOps-driven Continuous Delivery (CD) pipeline using ArgoCD 🛠️. Leveraging a public GitHub repository, Docker images, and Kubernetes manifests, we demonstrated seamless synchronization of Kubernetes resources 📦. As you explore this GitOps approach, ensure continuous adaptation of configurations and ongoing improvement of your CD practices 🌟. Happy deploying! 💻🔥

Top comments (0)