# ArgoCD - the GitOps way

As we adapt to building cloud-native applications, we are coming up with lots of toolings and processes. Gitops is one of the processes of implementing continuous deployment for cloud-native applications. ArgoCD is the declarative, Gitops tool specifically designed for cloud-native applications deployed in Kubernetes. In this blog post, we will see the below things.

* What is GitOps?
    
* ArgoCD tool
    
* Installing ArgoCD locally
    
* Setting up the app for Argocd
    
* Syncing out-of-sync app
    

# What is GitOps?

GitOps is a framework used to automate the process of provisioning the infrastructure. The Git repository is the center of the GitOps framework. The concept has evolved from the DevOps culture. DevOps is a mature framework that focuses more on the communication and collaboration of different teams in an organization. GitOps is the kind of branch of DevOps that focuses on using Git repositories for infrastructure and application deployments.

GitOps uses configuration files stored as code(Infrastructure as Code). The good practice of GitOps requires us to keep the infrastructure-related code repository separate from the application-related code repository. The Git repository is a source of truth for all the infrastructure definitions. Any configuration change of manual updates to the infrastructure would be overwritten to the configuration defined in the Git repository.

# ArgoCD tool

ArgoCD is a declarative, GitOps tool used to do continuous delivery for Kubernetes. ArgoCD uses the GitOps principles of using the Git repository as a source of truth. The application definitions, configurations, and environments will be stored in a separate Git repository from the application code repository and also declarative and version controlled.

ArgoCD will be part of the k8s cluster. ArgoCD agent pulls the k8s manifest changes and applies them to the k8s cluster. ArgoCD is configured to track the Git repository that contains manifest files. ArgoCD monitors for any changes to manifest files and tries to be in sync with the k8s cluster.

### ArgoCD workflow

* The developer commits the code and creates a tag that will trigger the CI pipeline.
    
* The CI pipeline builds the artifact and then creates a docker image which then will be stored in the docker hub.
    
* Once the docker image is created, the CI server can update the manifest files with a new/updated docker image.
    
* Once manifest files are updated, the argoCD will be out of sync.
    
* ArgoCD will update the cluster to be in sync with the manifest files as Git is the source of truth.
    

# Installing ArgoCD locally

### Prerequisite:

The tools which are required for ArgoCD to be installed locally are:

* Docker
    
* Kubernetes cluster ( [minikube](https://minikube.sigs.k8s.io/docs/), [kind](https://kind.sigs.k8s.io/), [docker-desktop](https://docs.docker.com/desktop/))
    
* Kubectl tool
    

ArgoCD can be installed within the Kubernetes cluster or external to the cluster. We will be installing ArgoCD inside the docker-desktop Kubernetes cluster.

First, we need to create a namespace to install ArgoCD by using the below command.

```bash
kubectl create namespace argocd
```

ArgoCD provides the manifest yaml file that can be applied to the locally running Kubernetes cluster.

```bash
kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml
```

verify the installation

```bash
kubectl get pods -n argocd
NAME                                                READY   STATUS    RESTARTS   AGE
argocd-application-controller-0                     1/1     Running   1          2d10h
argocd-applicationset-controller-695df5687d-lcghx   1/1     Running   1          2d10h
argocd-dex-server-54c99dd844-vt69d                  1/1     Running   1          2d10h
argocd-notifications-controller-7d7568845c-m5txb    1/1     Running   4          2d10h
argocd-redis-6d8cffcc47-jbwpd                       1/1     Running   1          2d10h
argocd-repo-server-647c6568c9-m6gt6                 1/1     Running   2          2d10h
argocd-server-8bdf66d5-jfxjh                        1/1     Running   2          2d10h
```

Once it is installed, we can open the argoCD instance locally by port-forwarding it to a host port.

```bash
kubectl port-forward svc/argocd-server -n argocd 8080:443
```

We will get the login screen as shown below.

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1678547889629/9ffa2719-970e-40c2-b6fa-22a12e535efd.png align="center")

The username is **admin** and password we need to get using the below command.

```bash
kubectl -n argocd get secret argocd-initial-admin-secret -o jsonpath="{.data.password}" | base64 -d
```

Once logged in, we should see the homepage as shown below. The application tiles will be empty.

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1678548155536/2046c2ca-54df-4917-8280-bd3dbfb35ef6.png align="center")

### Setting up the app for Argocd

To set up the application, we need a Git repository that would contain the manifest yaml files to install into the Kubernetes cluster. We will be using the git repository. [https://github.com/rahulmlokurte/argocd-demo](https://github.com/rahulmlokurte/argocd-demo) . The repository contains the manifest file for creating a namespace, deployment that uses Nginx image, and the service yaml.

test-ns.yaml

```bash
apiVersion: v1
kind: Namespace
metadata:
  name: test
spec: {}
```

test-deployment.yaml

```bash
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: nginx-demo
  name: nginx-demo
  namespace: test
spec:
  replicas: 1
  selector:
    matchLabels:
      app: nginx-demo
  strategy: {}
  template:
    metadata:
      labels:
        app: nginx-demo
    spec:
      containers:
      - image: nginx
        name: nginx-demo
        resources: {}
```

test-svc.yaml

```bash
apiVersion: v1
kind: Service
metadata:
  creationTimestamp: null
  labels:
    app: nginx-demo
  name: nginx-demo
  namespace: test
spec:
  ports:
  - port: 8080
    protocol: TCP
    targetPort: 8080
  selector:
    app: nginx-demo
```

To create an application on ArgoCD, click on the New APP and add the following details.

* **Application Name**: argocd-demo
    
* **Project Name:** default
    
* **Sync Policy:** manual
    
* **Source Repository URL:** [https://github.com/rahulmlokurte/argocd-demo](https://github.com/rahulmlokurte/argocd-demo)
    
* **revision:** main
    
* **path:** deployments
    
* **Cluster URL**: [https://kubernetes.default.svc](https://kubernetes.default.svc)
    
* **namespace**: test
    

Once the above details are entered, click on Create App, then we can see the app listed in the application tiles.

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1678549177072/6765d76a-8f1e-4db0-8fbf-b5b1b5da568b.png align="center")

We can see the status as Missing and out of sync as there is a difference in the manifest files defined in Git and the actual Kubernetes cluster.

As we have selected the sync policy as manual, we need to manually click on the nginx-demo button. Once we click on sync, it will try to sync the Kubernetes cluster with the configuration stored in Git.

```bash
Desktop kubectl get pods -n test
NAME                          READY   STATUS    RESTARTS   AGE
nginx-demo-5d7c8d874d-c5l7w   1/1     Running   0          11s
```

Once it is running, we can see the ArgoCD application is in-sync as shown below.

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1678549496245/51ae423d-a88f-4d50-a9df-d029d5e4549b.png align="center")

### Syncing out-of-sync app

Let us now change the replicas in the deployment file from '1' to '3'.

```bash
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: nginx-demo
  name: nginx-demo
  namespace: test
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx-demo
  strategy: {}
  template:
    metadata:
      labels:
        app: nginx-demo
    spec:
      containers:
      - image: nginx
        name: nginx-demo
        resources: {}
```

Now, we see the argoCD app shows out of sync because, in the Kubernetes cluster, we only have 1 pod, but in Git, it is 3 replicas.

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1678559744303/96bb574c-1138-4d24-9216-cf4d32822972.png align="center")

```bash
kubectl get pods -n test
NAME                          READY   STATUS    RESTARTS   AGE
nginx-demo-5d7c8d874d-c5l7w   1/1     Running   0          11s
```

Now, Once we click on the sync button, we see the Kubernetes cluster with 3 replicas of pods and the argoCD application tile shows synced.

```bash
Desktop kubectl get pods -n test
NAME                          READY   STATUS    RESTARTS   AGE
nginx-demo-5d7c8d874d-c5l7w   1/1     Running   0          175m
nginx-demo-5d7c8d874d-n8895   1/1     Running   0          15s
nginx-demo-5d7c8d874d-qm4zt   1/1     Running   0          15s
```

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1678560024854/3cf1b015-fb0b-4f5c-a80d-fa80aae62482.png align="center")

### Conclusion

In this blog post, we have seen the GitOps process and how the ArgoCD tool can be used that implements GitOps. We also see, how argoCD keeps track of changes in Git and tries to be in sync between the Kubernetes cluster and Git repository.

The GitHub repository for this blog post can be seen at [https://github.com/rahulmlokurte/argocd-demo](https://github.com/rahulmlokurte/argocd-demo)
