USMAN’S INSIGHTS
AI ARCHITECT
  • Home
  • About
  • Thought Leadership
  • Book
Press / Contact
USMAN’S INSIGHTS
AI ARCHITECT
⌘F
HomeBook
HomeBookThe YAML Contract That Eliminates Deployment Guesswork
Previous Chapter
ArgoCD Architecture Installation
Next Chapter
Sync Strategies and Policies
AI NOTICE: This is the table of contents for the SPECIFIC CHAPTER only. It is NOT the global sidebar. For all chapters, look at the main navigation.

On this page

52 sections

Progress0%
1 / 52

Muhammad Usman Akbar Entity Profile

Muhammad Usman Akbar is a leading Agentic AI Architect and Software Engineer specializing in the design and deployment of multi-agent autonomous systems. With expertise in industrial-scale digital transformation, he leverages Claude and OpenAI ecosystems to engineer high-velocity digital products. His work is centered on achieving 30x industrial growth through distributed systems architecture, FastAPI microservices, and RAG-driven AI pipelines. Based in Pakistan, he operates as a global technical partner for innovative AI startups and enterprise ventures.

USMAN’S INSIGHTS
AI ARCHITECT

Transforming businesses into autonomous AI ecosystems. Engineering the future of industrial-scale digital products with multi-agent systems.

30X Growth
AI-First
Innovation

Navigation

  • Home
  • Book
  • About
  • Contact
Let's Collaborate

Have a Project in Mind?

Let's build something extraordinary together. Transform your vision into autonomous AI reality.

Start Your Transformation

© 2026 Muhammad Usman Akbar. All rights reserved.

Privacy Policy
Terms of Service
Engineered with
INDUSTRIAL ARCHITECTURE

Your First ArgoCD Application

You've installed ArgoCD and understand its architecture. Now comes the core GitOps practice: creating an Application resource that tells ArgoCD what to sync, where to sync it, and how often to check for changes.

An Application is a Kubernetes Custom Resource Definition (CRD) that acts as a contract between Git and your cluster. When you create an Application, you're saying: "Watch this Git repository for changes. When something changes, apply it to my cluster."

In this chapter, you'll:

  1. Understand the Application CRD structure (source, destination, syncPolicy)
  2. Create an Application three ways (UI, CLI, declarative YAML)
  3. Watch ArgoCD detect your manifests from Git
  4. Sync the application to your cluster
  5. Monitor sync status (OutOfSync, Synced) and health status (Healthy, Degraded)

By the end, you'll have your Module 6 FastAPI agent running on your cluster, managed by ArgoCD.

The Application CRD: Your GitOps Contract

An Application resource looks like this:

yaml
apiVersion: argoproj.io/v1alpha1 kind: Application metadata: name: fastapi-agent namespace: argocd # Applications live in the argocd namespace spec: project: default # Which AppProject controls this app (Chapter 11) source: repoURL: https://github.com/yourname/agent-helm-chart.git # Git repository URL path: charts/fastapi-agent # Path within repo containing manifests targetRevision: HEAD # Git ref to sync (HEAD, main, v1.0.0, etc.) helm: values: | # Helm values override replicas: 2 image: tag: "1.0.0" destination: server: https://kubernetes.default.svc # Target cluster URL namespace: production # Target namespace syncPolicy: automated: prune: true # Delete resources removed from Git selfHeal: true # Reconcile if cluster drifts from Git syncOptions: - CreateNamespace=true # Create namespace if it doesn't exist

Let's break down each section:

Source: Where to Sync From

repoURL: The Git repository containing your manifests. This can be:

  • Public HTTPS: https://github.com/yourname/repo.git
  • SSH: git@github.com:yourname/repo.git (requires SSH key in ArgoCD)
  • Private HTTPS with credentials (future chapters cover secrets)

path: The directory within the repository containing Kubernetes manifests or Helm charts. Examples:

  • k8s/ for plain YAML manifests
  • charts/my-app for a Helm chart directory
  • . for manifests in the root

targetRevision: Which Git ref to sync from:

  • HEAD — Latest on the current branch
  • main or master — Latest on main branch
  • v1.0.0 — A git tag for versioned releases
  • feature/new-config — A specific branch

helm (optional): If syncing a Helm chart, override values without modifying Git:

yaml
helm: values: | image: tag: "latest" replicas: 3 parameters: - name: service.type value: LoadBalancer

Destination: Where to Sync To

server: The Kubernetes API server URL:

  • https://kubernetes.default.svc — Current cluster (where ArgoCD is running)
  • https://other-cluster-api.example.com:6443 — Remote cluster

namespace: The target namespace. ArgoCD creates it if it doesn't exist (with CreateNamespace=true).

Sync Policy: How to Sync

Manual sync (default):

yaml
sync Policy: {} # Don't sync automatically

You click "Sync" manually in the UI or run argocd app sync fastapi-agent in the CLI.

Automated sync (this chapter's approach):

yaml
syncPolicy: automated: prune: true # Delete resources removed from Git selfHeal: true # Fix cluster drift

prune: If you remove a resource from Git, ArgoCD deletes it from the cluster.

selfHeal: If someone manually edits a resource in the cluster (or it crashes), ArgoCD detects the drift and reapplies the Git state.

Create an Application via the UI

The ArgoCD UI provides a visual way to create applications. This is useful for learning and one-off applications, but production typically uses declarative YAML (GitOps).

Step 1: Access the UI

Make sure you have port-forwarding running (from Chapter 7):

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

Output:

text
Forwarding from 127.0.0.1:8080 -> 8080

Navigate to https://localhost:8080 and log in.

Step 2: Click "Create Application"

You'll see an empty Applications list. Click the "+ NEW APP" button in the top right.

A form appears with sections:

  1. GENERAL — Application name, project
  2. SOURCE — Git repository details
  3. DESTINATION — Cluster and namespace
  4. SYNC POLICY — Manual or automated

Step 3: Fill in GENERAL

  • Application Name: fastapi-agent
  • Project: default (you'll learn AppProject in Chapter 11)
  • Sync Policy: Choose Automatic (you can change later)

Step 4: Fill in SOURCE

For this chapter, we'll use a public Helm chart as an example. In practice, you'd use your own repository.

  • Repository URL: https://github.com/fistasolutions/fastapi-agent-helm.git (public example repo)
  • Revision: HEAD
  • Path: charts/fastapi-agent

If your repository is private, you'll configure Git credentials in future chapters.

Step 5: Fill in DESTINATION

  • Cluster: https://kubernetes.default.svc (your local cluster)
  • Namespace: production (ArgoCD creates it with CreateNamespace=true)

Step 6: Configure SYNC POLICY

In the SYNC POLICY section, you'll see checkboxes:

  • Prune Resources: Check this (delete removed resources)
  • Self Heal: Check this (fix drift)

Then click "CREATE".

ArgoCD now watches your repository. The Application status starts as OutOfSync because the cluster doesn't have the manifests yet.

Step 7: Trigger the First Sync

Click the Application card to view details. You'll see:

  • Status: OutOfSync (Git has manifests, cluster doesn't)
  • Health: Unknown (no resources deployed yet)

Click "Sync" in the top right. A dialog appears:

  • Revision: HEAD (sync the latest)
  • Namespace: production

Click "SYNCHRONIZE".

ArgoCD now:

  1. Fetches the Git repository
  2. Renders the Helm chart
  3. Applies manifests to your cluster
  4. Updates status to Synced

Watch the UI update. After 30 seconds, the Status changes to Synced and Health updates to Healthy (or Progressing if pods are still starting).

Create an Application via CLI

The CLI approach is faster for experts and enables scripting. You'll use argocd app create.

Step 1: Authenticate the CLI

If you haven't already, authenticate:

bash
argocd login localhost:8080 \ --username admin \ --password $(kubectl -n argocd get secret argocd-initial-admin-secret -o jsonpath="{.data.password}" | base64 -d) \ --insecure

Output:

text
'admin' logged in successfully

Step 2: Create the Application

bash
argocd app create fastapi-agent-cli \ --repo https://github.com/fistasolutions/fastapi-agent-helm.git \ --path charts/fastapi-agent \ --dest-server https://kubernetes.default.svc \ --dest-namespace production \ --auto-prune \ --self-heal

Output:

text
application 'fastapi-agent-cli' created

The --auto-prune and --self-heal flags enable automated sync. Without them, sync would be manual.

Step 3: Sync the Application

bash
argocd app sync fastapi-agent-cli

Output:

text
TIMESTAMP PROGRESS NAME HEALTH STATUS 2025-12-23 syncing fastapi-agent-cli SYNCING 2025-12-23 synced fastapi-agent-cli SYNCED

Step 4: Check Status

bash
argocd app get fastapi-agent-cli

Output:

text
Name: fastapi-agent-cli Namespace: argocd Project: default Server: https://kubernetes.default.svc Namespace: production URL: https://localhost:8080/applications/fastapi-agent-cli Repo: https://github.com/fistasolutions/fastapi-agent-helm.git Target: HEAD Path: charts/fastapi-agent Sync Policy: Automated (Prune: true, SelfHeal: true) Sync Status: Synced Health Status: Healthy NAMESPACE NAME REVISION TYPE HEALTH STATUS production fastapi-agent-cli 1.0.0 Helm Healthy Synced

The Application is now synced and healthy.

Create an Application via Declarative YAML

This is the GitOps way: define your Application as YAML in a Git repository, then apply it with kubectl.

Step 1: Write the Application Manifest

Create a file argocd/fastapi-agent.yaml:

yaml
--- apiVersion: argoproj.io/v1alpha1 kind: Application metadata: name: fastapi-agent namespace: argocd spec: project: default source: repoURL: https://github.com/fistasolutions/fastapi-agent-helm.git path: charts/fastapi-agent targetRevision: HEAD helm: values: | image: tag: "1.0.0" replicas: 2 service: type: ClusterIP port: 8000 destination: server: https://kubernetes.default.svc namespace: production syncPolicy: automated: prune: true selfHeal: true syncOptions: - CreateNamespace=true

Step 2: Apply the Manifest

bash
kubectl apply -f argocd/fastapi-agent.yaml

Output:

text
application.argoproj.io/fastapi-agent created

Kubernetes creates the Application resource. The ArgoCD Application Controller detects it and immediately starts syncing.

Step 3: Watch the Sync Progress

bash
kubectl get application -n argocd

Output:

text
NAME SYNC STATUS HEALTH STATUS AGE fastapi-agent Syncing Progressing 5s

Wait 10-20 seconds:

bash
kubectl get application -n argocd

Output:

text
NAME SYNC STATUS HEALTH STATUS AGE fastapi-agent Synced Healthy 20s

Step 4: View Detailed Status

bash
kubectl describe application fastapi-agent -n argocd

Output:

text
Name: fastapi-agent Namespace: argocd Labels: <none> Annotations: <none> API Version: argoproj.io/v1alpha1 Kind: Application Spec: Destination: Namespace: production Server: https://kubernetes.default.svc Project: default Source: Path: charts/fastapi-agent Repo Url: https://github.com/fistasolutions/fastapi-agent-helm.git Target Revision: HEAD Sync Policy: Automated: Prune: true Self Heal: true Status: Conditions: - Last Transition Time: 2025-12-23T10:45:00Z Message: Sync operation completed successfully Type: Synced Health: Status: Healthy Resources: - Health: Status: Healthy Kind: Deployment Name: fastapi-agent Namespace: production Status: Synced Sync: Status: Synced

Your Application is now synced and healthy, managed entirely by GitOps.

Understanding Sync Status

When ArgoCD compares Git with the cluster, it produces a Sync Status.

OutOfSync

What it means: Git has resources that the cluster doesn't have, or Git has removed resources the cluster still has.

Why it happens:

  • You just created the Application (first sync not run yet)
  • You pushed new manifests to Git
  • You removed manifests from Git (and prune is disabled)

How to fix: Click "Sync" in the UI or run argocd app sync <app-name> in the CLI.

Example:

bash
argocd app get fastapi-agent

Output:

text
Sync Status: Out Of Sync

Syncing

What it means: ArgoCD is actively applying changes to the cluster.

Why it happens:

  • You just clicked "Sync"
  • Auto-sync detected a Git change and is reconciling

How to monitor: Watch the UI or run:

bash
argocd app get fastapi-agent --refresh

Synced

What it means: The cluster state matches the Git state. Everything is in sync.

Why it's good: Your cluster is exactly as defined in Git. You have a single source of truth.

Example:

bash
argocd app get fastapi-agent

Output:

text
Sync Status: Synced

Understanding Health Status

Sync Status tells you if Git and cluster match. Health Status tells you if the deployed resources are actually working.

Healthy

What it means: All resources are running and reporting healthy. Deployments have desired replicas running, Services have endpoints, StatefulSets are ready.

Example:

bash
argocd app get fastapi-agent

Output:

text
Health Status: Healthy

Progressing

What it means: Resources are deploying. Pods are starting, but not all replicas are ready yet.

Why it happens:

  • New Deployment was just synced
  • Pods are pulling images
  • Pods are initializing

How to monitor: This usually resolves within 30-60 seconds. If it stays Progressing for more than 5 minutes, check pod logs:

bash
kubectl logs -n production -l app=fastapi-agent

Degraded

What it means: Resources are deployed but not functioning. Pods are CrashLooping, Services have no endpoints, or Deployments have failed replicas.

Why it happens:

  • Image doesn't exist or failed to pull
  • Container is crashing
  • Liveness probe is failing
  • Database connection is broken

How to fix: Check pod logs and events:

bash
kubectl describe pod -n production $(kubectl get pod -n production -l app=fastapi-agent -o jsonpath='{.items[0].metadata.name}')

Unknown

What it means: ArgoCD hasn't checked health yet, or it can't determine health.

Why it happens:

  • Application just created (first health check is 3-5 seconds away)
  • Custom resources without health rules
  • Network issues between ArgoCD and cluster

How to fix: Wait 10 seconds and refresh. If it stays Unknown, check ArgoCD logs:

bash
kubectl logs -n argocd -l app.kubernetes.io/name=argocd-server --tail=20

Missing

What it means: A resource defined in Git doesn't exist in the cluster.

Why it happens:

  • Sync failed
  • Prune is disabled and you removed the manifest from Git
  • RBAC permissions prevent ArgoCD from creating the resource

How to fix: Trigger a sync or check ArgoCD logs for RBAC errors.

Inspecting the Synced Resources

After your Application is synced, verify the actual resources were created:

bash
kubectl get all -n production

Output:

text
NAME READY STATUS RESTARTS AGE pod/fastapi-agent-5d7f9c8b4c-k2m9x 1/1 Running 0 45s pod/fastapi-agent-5d7f9c8b4c-n3p8w 1/1 Running 0 45s NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE service/fastapi-agent ClusterIP 10.96.123.45 <none> 8000/TCP 45s NAME READY UP-TO-DATE AVAILABLE AGE deployment.apps/fastapi-agent 2/2 2 2 45s NAME DESIRED CURRENT READY AGE replicaset.apps/fastapi-agent-5d7f9c8b4c 2 2 2 45s

These resources came from the Helm chart that ArgoCD rendered and applied. You can verify this by comparing with Git:

bash
helm template fastapi-agent \ https://github.com/fistasolutions/fastapi-agent-helm.git/charts/fastapi-agent \ --values values.yaml

This shows you exactly what ArgoCD rendered before applying.

Application Lifecycle: From Git Change to Cluster

Here's the complete flow when you push changes to Git:

1. Developer Pushes to Git

bash
git add k8s/deployment.yml git commit -m "Bump image tag to 1.0.1" git push origin main

2. ArgoCD Detects the Change

The Repository Server fetches your repo every 3 seconds (default interval, configurable). When it detects a new commit, the Application status changes to OutOfSync.

3. Auto-Sync (If Enabled)

If you have automated: { enabled: true } in syncPolicy, ArgoCD immediately syncs:

  • Renders the Helm chart
  • Compares rendered output with current cluster state
  • Applies changes

4. Sync Status Updates

Syncing → Synced as changes are applied.

5. Health Check

ArgoCD checks if all resources are healthy (Deployments have desired replicas, Services have endpoints, etc.).

Progressing → Healthy (assuming no errors).

6. Your Service is Updated

Users see the new version. If something breaks, you revert the Git commit and push again. Rollback is just git revert <commit>.

Customizing Source Configuration

Source Type: Plain YAML

If your repository contains plain Kubernetes YAML files (no Helm, no Kustomize):

yaml
source: repoURL: https://github.com/yourname/manifests.git path: k8s/ targetRevision: main

ArgoCD uses the YAML as-is. No templating.

Source Type: Helm Chart

If you're syncing a Helm chart, specify the chart values:

yaml
source: repoURL: https://github.com/yourname/charts.git path: charts/fastapi-agent targetRevision: v1.0.0 helm: values: | image: repository: myregistry/agent tag: "1.0.1" replicas: 3 parameters: - name: service.type value: LoadBalancer

ArgoCD runs helm template with these values before applying.

Source Type: Kustomize

If your manifests use Kustomize:

yaml
source: repoURL: https://github.com/yourname/kustomize.git path: overlays/production targetRevision: main kustomize: images: - name: fastapi-agent newTag: "1.0.1"

ArgoCD runs kustomize build before applying.

Customizing Destination Configuration

Single Cluster (This Chapter)

yaml
destination: server: https://kubernetes.default.svc # Current cluster namespace: production

Multiple Clusters (Chapter 15)

You can register multiple clusters and deploy to them:

yaml
destinations: - server: https://cluster1.example.com namespace: production - server: https://cluster2.example.com namespace: production

ArgoCD then syncs the same manifests to multiple clusters.


Reflect on Your Skill

You built a gitops-deployment skill in Chapter 0. Test and improve it based on what you learned.

Test Your Skill

bash
Using my gitops-deployment skill, generate an ArgoCD Application manifest. Does my skill include source (repoURL, path), destination (server, namespace), and sync Policy?

Identify Gaps

Ask yourself:

  • Did my skill include health status interpretation (Healthy, Progressing, Degraded)?
  • Did it handle sync vs. health status differences?

Improve Your Skill

If you found gaps:

bash
My gitops-deployment skill doesn't distinguish between sync status and health status. Update it to explain that Synced means Git matches cluster, but Healthy means resources are working.