# ArgoCD Integration

Argo CD is a declarative GitOps continuous delivery tool for Kubernetes. It watches your Git repositories and automatically syncs the desired state into your cluster. Through its Notifications Engine, Argo CD can push webhook events to external systems like itoc360 whenever an application's sync or health status changes — making it straightforward to wire on-call alerting directly into your deployment pipeline.

### Prerequisites

* Docker Desktop installed and running
* `minikube` and `kubectl` available on your machine
* An ITOC360 source token for Argo CD

### Setting Up a Local Kubernetes Cluster

Since Argo CD runs inside Kubernetes, you need a local cluster first. Install minikube via Homebrew if you haven't already:

```bash
brew install minikube
```

Then start the cluster using Docker as the driver:

```bash
minikube start --driver=docker
```

Minikube will pull the necessary images and initialize a single-node cluster. The whole process takes a couple of minutes depending on your connection speed.

### Installing Argo CD

Create a dedicated namespace and apply the official Argo CD manifest:

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

This installs all the Argo CD components — server, application controller, notifications controller, Redis, and the supporting RBAC configuration.

Wait for the server pod to become ready before proceeding:

```bash
kubectl wait --for=condition=ready pod -l app.kubernetes.io/name=argocd-server -n argocd --timeout=120s
```

Once you see `condition met`, open a port-forward so you can reach the UI locally:

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

Retrieve the initial admin password:

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

Open `https://localhost:8081` in your browser (accept the self-signed certificate warning), log in with username `admin` and the password you just retrieved.

<figure><img src="https://4108595529-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FimJRSa33y5Ej6rwXrBeA%2Fuploads%2FWMz8VRHPbk7ty4AYVd1J%2FEkran%20Resmi%202026-03-25%2013.14.31.png?alt=media&#x26;token=85318cfd-1ad3-4b74-8ee1-3f1e66fdf08b" alt=""><figcaption></figcaption></figure>

### Creating a Test Application

Argo CD's notification system only fires when an Application resource exists. Create one that tracks a public example repository:

```bash
kubectl apply -n argocd -f - <<EOF
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: itoc360-test
  namespace: argocd
spec:
  project: default
  source:
    repoURL: https://github.com/<your-repo-url>
    targetRevision: HEAD
    path: guestbook
  destination:
    server: https://kubernetes.default.svc
    namespace: default
  syncPolicy:
    automated:
      prune: true
      selfHeal: true
EOF
```

After a few seconds the application card appears in the Argo CD dashboard.

<figure><img src="https://4108595529-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FimJRSa33y5Ej6rwXrBeA%2Fuploads%2FH7xlaWhX9B7Ucdk19wG7%2Fimage.png?alt=media&#x26;token=dc7ec1cf-57c5-413a-a779-449dc287ae87" alt=""><figcaption></figcaption></figure>

### Configuring the Notification Webhook

Argo CD sends notifications through the `argocd-notifications-cm` ConfigMap. Apply the following to configure the ITOC360 webhook, the message template, and the trigger rules:

```bash
kubectl apply -f - <<'EOF'
apiVersion: v1
kind: ConfigMap
metadata:
  name: argocd-notifications-cm
  namespace: argocd
data:
  service.webhook.itoc360: |
    url: https://<your-url>/functions/v1/integrations?token=<your-source-token>
    headers:
    - name: Content-Type
      value: application/json
  template.app-sync-itoc360: |
    webhook:
      itoc360:
        method: POST
        body: |
          {
            "app_name": "{{.app.metadata.name}}",
            "sync_status": "{{.app.status.sync.status}}",
            "health_status": "{{.app.status.health.status}}",
            "namespace": "{{.app.spec.destination.namespace}}",
            "server": "{{.app.spec.destination.server}}"
          }
  trigger.on-sync-itoc360: |
    - when: app.status.sync.status == 'OutOfSync' || app.status.health.status == 'Degraded'
      send: [app-sync-itoc360]
    - when: app.status.sync.status == 'Synced' && app.status.health.status == 'Healthy'
      send: [app-sync-itoc360]
EOF
```

Then subscribe the test application to the trigger:

```bash
kubectl annotate application itoc360-test -n argocd \
  notifications.argoproj.io/subscribe.on-sync-itoc360.itoc360=""
```

### How It Works

Whenever the `itoc360-test` application changes state, the notifications controller fires a POST request to your ITOC360 endpoint with a JSON body containing the application name, sync status, health status, destination namespace, and cluster server URL.

itoc360 maps these fields as follows:

* `health_status: Degraded` or `sync_status: OutOfSync` → **ALERT**, HIGH priority
* `health_status: Missing` → **ALERT**, HIGH priority
* `health_status: Progressing` → **ALERT**, MEDIUM priority
* `sync_status: Synced` and `health_status: Healthy` → **RESOLVE**

Alerts are correlated by application name and namespace, so a degraded deployment and its eventual recovery are treated as a single incident lifecycle.

### Verifying the Integration

Trigger a manual sync to confirm the webhook fires end-to-end:

```bash
kubectl patch application itoc360-test -n argocd --type merge \
  -p '{"operation":{"initiatedBy":{"username":"admin"},"sync":{"revision":"HEAD"}}}'
```

You should see the application transition through its sync phases in the Argo CD UI, and a corresponding alert appear in your ITOC360 dashboard within a few seconds.

<figure><img src="https://4108595529-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FimJRSa33y5Ej6rwXrBeA%2Fuploads%2FCZMOtHOoqi2eqaXCoOuk%2Fimage.png?alt=media&#x26;token=1809f465-4ede-4cf1-9af4-c7d30fef60b3" alt=""><figcaption></figcaption></figure>
