Implementing The ArgoCD Controller
Tags: kubernetes, devops, git, docker
Published: 2023-04-25 17:58:53

When you’re deploying any Kubernetes Manifest, the most sough-after method in today’s cloud-native world is GitOps. GitOps gives you the ability to deploy very differently than, for example, running a bunch of `kubectl apply -f` commands.

In this blog post, you’ll read a brief summary of what ArgoCD is and how you can get started with the Controller for a more robust and declarative experience. 

## What Is ArgoCD

Before diving into utilizing the Controller, let’s briefly talk about what ArgoCD is (if you need a deeper dive, check out [this blog post](https://dev.to/thenjdevopsguy/gitops-with-argocd-getting-started-dg)).

In short, ArgoCD is a Kubernetes Controller in itself, which makes the title of this blog post and what you’ll be learning about throughout this blog semi-confusing (until the next section).

When you’re thinking about ArgoCD, think about it from a GitOps perspective. It gives you the ability to automatically deploy containerized applications if they exist in some Kubernetes Manifest in a source control repo that’s Git-based.

The ArgoCD Controller will watch the Git repo for changes and deploy the new changes. For example, if a k8s manifest has a changed Pod spec that goes from 1 replica to 2 replicas, ArgoCD will kick into action.

You can think about GitOps overall like Configuration Management or Continuous Delivery.

## Imperative vs Declarative

In the previous section, you read that ArgoCD is a GitOps Controller, which is true. It’s a Kubernetes Controller much like the Deployment Controller or the ReplicaSet Controller.

With ArgoCD itself, you have a few ways of deploying containerized applications:

- Imperative (run a bunch of `argocd` CLI commands on the terminal).
- Use the Controller, which is also like the Deployment Controller or the ReplicaSet Controller

The ArgoCD Application Controller gives you the ability to declaratively deploy containerized applications in a Kubernetes Manifest utilizing a Custom Resource Definition (CRD) to extend the Kubernetes API.

In short, the GitOps Controller itself for ArgoCD gives your cluster the ability to utilize GitOps because out of the box, Kubernetes doesn’t come built with GitOps. The ArgoCD Application Controller allows you to deploy containerized applications utilizing GitOps without having to worry about the CLI/imperative model.

## Writing An ArgoCD Application Resource

As discussed in the previous section, when you’re deploying a resource utilizing ArgoCD, you have two options:

- The imperative method
- The declarative method

Below is an example of the imperative method. It utilizes the ArgoCD CLI along with the `app` command and `create` flag. You’ll then point to the repo where the Kubernetes Manifest exists along with the path to the code, the destination server (local k8s cluster or remote), and the Namespace that you want your Kubernetes Resource that’s being created to exist in.

```jsx
argocd app create nginxdeployment --repo https://github.com/AdminTurnedDevOps/PearsonCourses.git --path GitOps-For-Kubernetes/Section6/lab/nginx --dest-server https://kubernetes.default.svc --dest-namespace default
```

There’s nothing inherently “bad” about utilizing the ArgoCD CLI to deploy. It really just comes down to the fact that it’s imperative and not declarative. Because Kubernetes is declarative and works best with declarative methodologies, utilizing the declarative deployment method is just a bit cleaner.

Below is an example of utilizing the ArgoCD Application Controller with the `application` resource to deploy a Helm Chart for Bitnami’s Sealed Secrets.

Notice how it looks like any other Kubernetes Manifest, which is the idea of utilizing the declarative approach.

```jsx
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: sealed-secrets
  namespace: argocd
spec:
  project: default
  source:
    chart: sealed-secrets
    repoURL: https://bitnami-labs.github.io/sealed-secrets
    targetRevision: 1.16.1
    helm:
      releaseName: sealed-secrets
  destination:
    server: "https://kubernetes.default.svc"
    namespace: kubeseal
```

## Implementing The Resource

Now that you understand the theory behind the ArgoCD Application Controller, let’s learn how to utilize the code above in your Kubernetes environment.

First, ensure that you have a Namespace called `kubeseal`.

```jsx
kubectl create namespace kubeseal
```

Next, if you haven’t already done so, deploy ArgoCD. Please note that the below configuration is for High Availability (HA) environments. If you don’t have an environment with more than three (3) Worker Nodes, remove the following flags:

--set redis-ha.enabled=true
--set controller.replicas=1
--set server.autoscaling.enabled=true
--set server.autoscaling.minReplicas=2
--set repoServer.autoscaling.enabled=true
--set repoServer.autoscaling.minReplicas=2
--set applicationSet.replicaCount=2

```jsx
helm install argocd -n argocd argo/argo-cd \
--set redis-ha.enabled=true \
--set controller.replicas=1 \
--set server.autoscaling.enabled=true \
--set server.autoscaling.minReplicas=2 \
--set repoServer.autoscaling.enabled=true \
--set repoServer.autoscaling.minReplicas=2 \
--set applicationSet.replicaCount=2 \
--set server.service.type=LoadBalancer \
--create-namespace
```

Once ArgoCD is deployed, run the following code which will deploy the Helm Chart for Bitnamis Sealed Secrets.

```jsx
kubectl apply -f - <<EOF
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: sealed-secrets
  namespace: argocd
spec:
  project: default
  source:
    chart: sealed-secrets
    repoURL: https://bitnami-labs.github.io/sealed-secrets
    targetRevision: 1.16.1
    helm:
      releaseName: sealed-secrets
  destination:
    server: "https://kubernetes.default.svc"
    namespace: kubeseal
EOF
```

After 1-2 minutes, you will see that Sealed Secrets was deployed successfully.


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/fcksdhawpmy879ar754h.png)


## Wrapping Up

As mentioned in this blog post, there’s no right or wrong answer to whether or not you want to use the declarative or imperative approach. It really comes down to what workflow works best for you. I believe the declarative approach is a better option because overall, that’s what Kubernetes works best with, but both options will suffice.

Another thing to consider is that the ArgoCD Application Controller is still in Alpha. This may scare some engineers away and for good reason. However, there are several production-ready environments that are utilizing the ArgoCD Application Controller even though it’s in Alpha. The only thing to keep in mind is at some point, the Controller (because it’s still in Alpha) will change and be updated, so be prepared for (possible) breaking changes.