Your first ARGO-CD
Tags: kubernetes, istio, argocd, gitops
Published: 2023-12-25 18:32:25

## What are we going to do in the next steps?
We are going to set up Argo CD on a Kubernetes cluster that we initiated in the last blog [1- Your First K8S+Istio](https://dev.to/sambo2021/your-first-k8sistio-41jh).
Also, we will make argo-cd behind a reverse proxy, so we gonna use what we installed through Istio to reach the argo-cd ui through the browser
## How will we install the argo-cd at first?
We'll install it with Helm, create an application to use the app-of-apps pattern, and set Argo CD up so that it can update itself.

## What is Argo CD?
Argo CD is a GitOps tool to automatically synchronizes the cluster to the desired state defined in a Git repository. Each workload is defined declaratively through a resource manifest in a YAML file. Argo CD checks if the state defined in the Git repository matches what is running on the cluster, and synchronizes it if changes were detected.

## Step 01: Initialize our argo-cd Helm chart
We will use Helm to install Argo CD with the community-maintained chart from argoproj/argo-helm because The Argo project doesn't provide an official Helm chart.
We will render thier helm chart for argocd locally on our side, manipulate it and overrides its default values, and also we can helm lint the chart and templating to see if there is some errors or not, We gonna use the chart version 5.50.0 which matches appVersion: v2.8.6 you can find all details for the [chart](https://github.com/argoproj/argo-helm/tree/argo-cd-5.50.0/charts/argo-cd)
and also we gonna override some values @ [default-values.yaml](https://github.com/sambo2021/helm-charts/blob/master/charts/argocd-test/generate-chart/values-default.yaml)
```
configs:
  params:
    server.insecure: true
    server.basehref: '/argocd'
    server.rootpath: '/argocd'
dex:
  enabled: false
notifications:
  enabled: false
applicationSet:
  enabled: false

```
We start the server with the --insecure flag to serve the Web UI over HTTP. 
For this tutorial, we're using a local k8s server without a TLS setup.

also, we should override the basehref and rootpath to the subpath we gonna use to access the argo-cd UI -> http://localhost:9080/argocd/

Disable the dex component (integration with external auth providers).

Disable the notifications controller (notify users about changes to the application state).

Disable the ApplicationSet controller (automated generation of Argo CD Applications).

and BTW in the render-helm script, I deleted the part of highly available argocd deployment, so we can deploy non-HA version of Argo CD by default. If you want to run Argo CD in HA mode please have a look on [README.md](https://github.com/argoproj/argo-helm/blob/argo-cd-5.50.0/charts/argo-cd/README.md)

just go inside [helm_render.sh](https://github.com/sambo2021/helm-charts/tree/master/charts/argocd-test/generate-chart)
and run the script, it will generate for you [argo-cd](https://github.com/sambo2021/helm-charts/tree/master/charts/argocd-test/argo-cd)

sure every time you want a higher version just look at their [GitHub-repo](https://github.com/argoproj/argo-helm/tree/main/charts/argo-cd) and use the chart version you need and don't forget the appVersion also -> you can find the chart version at tags for ex: argo-cd-5.50.0, add values to [Chart.yaml](https://github.com/sambo2021/helm-charts/blob/master/charts/argocd-test/generate-chart/Chart.yaml) and [helm_render.sh](https://github.com/sambo2021/helm-charts/tree/master/charts/argocd-test/generate-chart) run the script helm_render.sh again.

to check whether the manifests in templates are good or corrupted:
```
~/helm-charts/charts/argocd-test/ $ helm lint ./argo-cd/ --debug

==> Linting ./argocd-test/argo-cd/
[INFO] Chart.yaml: icon is recommended

1 chart(s) linted, 0 chart(s) failed
```

## Step 02: Installing our argo-cd Helm chart
We have to do the initial installation manually from our local machine
Later we set up Argo CD to manage itself (meaning that Argo CD will automatically detect any changes to the helm chart and synchronize it):
```
~/helm-charts/charts/argocd-test/ $ helm install argo-cd argo-cd/
```
After a minute all resources should have been deployed:

![arrgo-cd instances](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5dwxu6l6fxbld9egqeql.png)

Accessing the Web UI
all you need now to add the path of argo-cd under the virtual service we did at the previous blog 

the service
![argo-cd service](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/igfdyhfj3vo3ajt9dybr.png)

the virtual service

![argo-cd virtual service](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/k7qsu81zvdie58mr1fz1.png)

then you can go directly to UI http://localhost:9080/argocd
username-> The default username is admin
passowrd-> is auto-generated, we can get it with:
```
$ kubectl get secret argocd-initial-admin-secret -o jsonpath="{.data.password}" | base64 -d
```
if something happened to istio deployment or you deployed argocd before istio then To access the Web UI we have to port-forward to the argocd-server service on port 443:
```
$ kubectl port-forward svc/argo-cd-argocd-server 9081:80
```
then you can go directly to UI http://localhost:9081/argocd
After logging in, we'll see the empty Web UI:
At this point, Argo CD applications could be added through the Web UI or CLI, but we want to manage everything in a declarative way (Infrastructure as code). This means need to write Application manifests in YAML, and commit them to our Git repo.

#### Step 03: manage root-app
In general, when we want to add an application to Argo CD, we need to add an Application resource in our Kubernetes cluster. The resource needs to specify where to find manifests for our application. 

The root-app is a Helm chart that renders Application manifests. Initially, it has to be added manually, and after, we will commit Application manifests with Git, and it will be deployed automatically to argo-cd apps

Creating the [root-app](https://github.com/sambo2021/helm-charts/tree/master/charts/root-app) Helm chart
***note: we will add at first step the templates/root-app.yml application so don't add the templates/argo-cd.yml now-> only the templates/root-app.yml 

https://github.com/sambo2021/helm-charts/blob/master/charts/root-app/Chart.yaml
```
apiVersion: v2
name: root-app
version: 1.0.0
```
and empty values.yaml -> https://github.com/sambo2021/helm-charts/blob/master/charts/root-app/values.yaml

then the root-app -> https://github.com/sambo2021/helm-charts/blob/master/charts/root-app/templates/root-app.yml

```
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: root-app
  finalizers:
  - resources-finalizer.argocd.argoproj.io
spec:
  project: default
  source:
    repoURL: https://github.com/sambo2021/helm-charts.git
    path: charts/root-app/
    targetRevision: master
  destination:
    server: https://kubernetes.default.svc
    namespace: default
  syncPolicy:
    automated:
      selfHeal: true
```

The above Application watches our root-app Helm chart (under https://github.com/sambo2021/helm-charts/blob/master/charts/root-app/templates/), and if changes are detected, synchronizes (meaning that it will render the Helm chart and apply the resulting manifests on the cluster) it.

How does Argo CD know our application is a Helm chart? It looks for a Chart.yaml file under path in the Git repository.

Argo CD will not use helm install to install charts. It will render the chart with helm template and then apply the output with kubectl. 
This means we can't run helm list on a local machine to get all installed releases.

after pushing your charts to the remote repo 

Now let's apply the manifest in our Kubernetes cluster. The first time we have to do it manually
```
~/helm-charts/charts/ $ helm template root-app/ | kubectl apply -f -
```
***note: api-server will understand the kind of that manifest because you already provided it by necessary crds when you deployed arg-cd 

Now Argo CD manage the root-app and synchronize it automatically:

## Step 04: let argo-cd manage itself
finally it is the moment of adding the argo-cd app that referring to our helm chart that we applied before, at the same level of root-app.yaml 
https://github.com/sambo2021/helm-charts/blob/master/charts/root-app/templates/argo-cd.yml
```
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: argo-cd
  finalizers:
  - resources-finalizer.argocd.argoproj.io
spec:
  project: default
  source:
    repoURL: https://github.com/sambo2021/helm-charts.git
    path: charts/argocd-test/argo-cd/
    targetRevision: master
  destination:
    server: https://kubernetes.default.svc
    namespace: default
  syncPolicy:
    automated:
      selfHeal: true
```
and push it to the remote repo and let argo-cd to do the magic 
We let the Argo CD controller watch for changes to the argo-cd helm chart in our repo (under  https://github.com/sambo2021/helm-charts/tree/master/charts/argocd-test/argo-cd), render the Helm chart, and apply the resulting manifests. It's done using kubectl and asynchronous.


![aargocd ui](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/s5m3vngh7e9is21mk9gu.png)

note: sometimes some apps get stuck and hanging while being deleted or resync, a small tip, is to remove the finalizer of one/multiple argo-cd applications
because if an Application or an ApplicationSet is stuck while deleting. It means it needs to wait for a response from "finalizers". So, the solution is to remove the "finalizers" from JSON
```
kubectl get applications  -o=jsonpath='{range .items[?(@.status.health.status=="Unknown")]}{.metadata.name}{"\n"}' | xargs -I {} kubectl patch application {}  --type=json -p='[{"op": "remove", "path": "/metadata/finalizers"}]'
```
## Step 05: manage istio charts by argocd
we deployed istio-base, istiod and istio-ingress before by helm install, now this is the step to migrate them to our rago-cd 
the same we did for argo-cd, in every component we pull the chart local by the helm_render script and using the argocd app

1- istio-base
the chart -> https://github.com/sambo2021/helm-charts/tree/master/charts/istio-base-test/
the argocd-app-> https://github.com/sambo2021/helm-charts/blob/master/charts/root-app/templates/istio-base.yml

2- istiod
the chart -> https://github.com/sambo2021/helm-charts/tree/master/charts/istio-istiod-test
the argocd-app-> https://github.com/sambo2021/helm-charts/blob/master/charts/root-app/templates/istio-istiod.yml

3- istio-ingress
the chart -> https://github.com/sambo2021/helm-charts/tree/master/charts/istio-ingress-test
the argocd-app-> https://github.com/sambo2021/helm-charts/blob/master/charts/root-app/templates/istio-ingress.yml

finnaly : 

![argo-cd apps](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0kokaqcdjgo2is2xw3s5.png)


an issue appeared to me for istiod-v1.20.1, specially istiod-default-validator
but a quick fix to add ignore diff parameter to istio-base argoapp as the third link mentioned :
1-https://github.com/istio/istio/issues/46727
2-https://github.com/istio/istio/issues/45738
3-https://github.com/argoproj/argo-cd/issues/9323