DEV Community

Python-T Point
Python-T Point

Posted on • Originally published at pythontpoint.in

🐍 Mastering Argo CD app of apps for Python microservices

πŸš€ Direct Answer β€” Argo CD app of apps Python microservice tutorial

Argo CD app of apps Python microservice tutorial

Argo CD app of apps Python microservice tutorial shows how to deploy a Python microservice stack using the App of Apps pattern in Argo CD by defining a parent Application that references child Applications for each service, letting Argo CD reconcile the entire stack automatically.

πŸ“‘ Table of Contents

  • πŸš€ Direct Answer β€” Argo CD app of apps Python microservice tutorial
  • πŸ— Architecture β€” Why It Scales
  • 🐍 Python Service β€” What the Container Looks Like
  • πŸ“¦ Helm Chart β€” How to Package the Service
  • πŸš€ Deployment Manifest
  • πŸ”§ Service Manifest
  • πŸ“ˆ Argo CD β€” How to Synchronize the Stack
  • πŸ“‚ Parent Application
  • 🧩 Child Applications
  • πŸ›‘ Observability β€” Adding Health Checks
  • 🟩 Final Thoughts
  • ❓ Frequently Asked Questions
  • How does the App of Apps pattern differ from using multiple independent Argo CD Applications?
  • Can I use Kustomize instead of Helm for the child Applications?
  • What is the recommended way to handle secret management for the Python services?
  • πŸ“š References & Further Reading

πŸ— Architecture β€” Why It Scales

A parent Application in Argo CD is a Kubernetes custom resource that references multiple child Applications, enabling hierarchical sync and version control across the entire microservice stack.

# parent-app.yaml
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata: name: python-microservices namespace: argocd
spec: project: default source: repoURL: https://github.com/example/python-microservices targetRevision: HEAD path: apps destination: server: https://kubernetes.default.svc namespace: default syncPolicy: automated: prune: true selfHeal: true syncOptions: - CreateNamespace=true
Enter fullscreen mode Exit fullscreen mode

What this does:

  • metadata.name: identifier for the parent Application.
  • spec.source.repoURL: Git repository that stores child Application manifests.
  • spec.syncPolicy.automated.prune: removes resources that are no longer defined.
  • syncOptions.CreateNamespace: ensures the target namespace exists before applying resources.

Why not use a single large Helm chart? A monolithic chart forces all services to share a single release cycle, whereas the App of Apps pattern lets each microservice evolve independently while still being managed centrally.

Key point: The parent Application provides a single point of control, yet each child can be versioned and rolled back separately, reducing blast radius during failures.


🐍 Python Service β€” What the Container Looks Like

A Dockerfile builds a reproducible image that contains the Python runtime, dependencies, and the application code, ensuring consistent behavior across environments.

# Dockerfile
FROM python:3.11-slim # Install build dependencies
RUN apt-get update && apt-get install -y -no-install-recommends gcc libpq-dev && rm -rf /var/lib/apt/lists/* # Create non‑root user
RUN useradd -create-home appuser
WORKDIR /app
COPY requirements.txt .
RUN pip install -no-cache-dir -r requirements.txt # Copy source
COPY src/ . # Switch to non‑root user
USER appuser EXPOSE 8080
CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8080"]
Enter fullscreen mode Exit fullscreen mode

What this does:

  • FROM python:3.11-slim: base image with minimal OS footprint.
  • RUN apt-get …: installs compiled‑extension build tools needed for some Python packages.
  • USER appuser: runs the container as a non‑root user for security.
  • CMD …: starts the FastAPI server with uvicorn.

Why not use a pre‑built image from Docker Hub? Building the image locally guarantees that compiled dependencies match the exact OS version of the target environment, avoiding runtime ABI mismatches.

Build and push the image: (Also read: πŸš€ Creating aws s3 bucket policy with python boto3 tutorial)

$ docker build -t ghcr.io/example/python-service:v1.0 .
Sending build context to Docker daemon 12.34MB
Step 1/10: FROM python:3.11-slim
...
Successfully tagged ghcr.io/example/python-service:v1.0



$ docker push ghcr.io/example/python-service:v1.0
The push refers to repository [ghcr.io/example/python-service]
...
Digest: sha256:3b2c5f...
Enter fullscreen mode Exit fullscreen mode

πŸ“¦ Helm Chart β€” How to Package the Service

A Helm chart bundles Kubernetes manifests and default values, allowing the same chart to be reused for multiple environments.

# Chart.yaml
apiVersion: v2
name: python-service
description: Helm chart for the Python microservice
type: application
version: 0.1.0
appVersion: "1.0"
Enter fullscreen mode Exit fullscreen mode

What this does: declares chart metadata; appVersion tracks the Docker image tag.

πŸš€ Deployment Manifest

The Deployment defines pod replicas, container image, and health probes.

# templates/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata: name: {{ include "python-service.fullname" . }}
spec: replicas: {{ .Values.replicaCount }} selector: matchLabels: app: {{ include "python-service.name" . }} template: metadata: labels: app: {{ include "python-service.name" . }} spec: containers: - name: {{ .Chart.Name }} image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}" ports: - containerPort: 8080 livenessProbe: httpGet: path: /health port: 8080 initialDelaySeconds: 10 periodSeconds: 30 readinessProbe: httpGet: path: /ready port: 8080 initialDelaySeconds: 5 periodSeconds: 15
Enter fullscreen mode Exit fullscreen mode

What this does:

  • replicas: number of pod instances, scaling horizontally.
  • livenessProbe / readinessProbe: Kubernetes health checks that restart unhealthy pods and control service traffic.
  • image.repository & image.tag: injected from values.yaml, enabling version upgrades without editing manifests.

πŸ”§ Service Manifest

The Service exposes the pods on a stable ClusterIP for internal traffic. (Also read: 🐍 CI/CD Python App Service vs AKS β€” Which One Should You Use?)

# templates/service.yaml
apiVersion: v1
kind: Service
metadata: name: {{ include "python-service.fullname" . }}
spec: selector: app: {{ include "python-service.name" . }} ports: - protocol: TCP port: 80 targetPort: 8080
Enter fullscreen mode Exit fullscreen mode

Why not use a LoadBalancer Service here? The microservice is intended to be accessed only via an Ingress controller; exposing a LoadBalancer would allocate a public IP per service, increasing cost and attack surface. (More onPythonTPoint tutorials)

Install the chart into the cluster:

$ helm upgrade -install python-service ./python-service \ -namespace default \ -create-namespace
Release "python-service" does not exist. Installing now.
NAME: python-service
LAST DEPLOYED: Sun Oct 1 12:34:56 NAMESPACE: default
STATUS: deployed
REVISION: 1
Enter fullscreen mode Exit fullscreen mode

πŸ“ˆ Argo CD β€” How to Synchronize the Stack

Argo CD Applications declare the source repository, target namespace, and sync policy for each Helm chart, enabling continuous delivery.

πŸ“‚ Parent Application

The parent Application references a directory that contains child Application manifests for each microservice.

# apps/python-microservices/parent.yaml
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata: name: python-microservices
spec: project: default source: repoURL: https://github.com/example/python-microservices targetRevision: HEAD path: apps/children destination: server: https://kubernetes.default.svc namespace: default syncPolicy: automated: prune: true selfHeal: true
Enter fullscreen mode Exit fullscreen mode

What this does:

  • source.path: points to the folder containing child Application YAML files.
  • syncPolicy.automated.selfHeal: forces Argo CD to correct drift automatically.

🧩 Child Applications

Each child Application points to a Helm chart for a single microservice.

# apps/children/python-service.yaml
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata: name: python-service
spec: project: default source: repoURL: https://github.com/example/python-microservices targetRevision: HEAD chart: python-service helm: valueFiles: - values.yaml destination: server: https://kubernetes.default.svc namespace: default syncPolicy: automated: prune: true selfHeal: true
Enter fullscreen mode Exit fullscreen mode

What this does:

  • source.chart: name of the Helm chart to render.
  • helm.valueFiles: list of values files that override chart defaults.

Apply the parent Application to Argo CD:

$ kubectl apply -f apps/python-microservices/parent.yaml
application.argoproj.io/python-microservices created



NAME HEALTH STATUS AGE
python-microservices Healthy Synced 10s
python-service Healthy Synced 8s
Enter fullscreen mode Exit fullscreen mode

β€œWith the App of Apps pattern, a single Git commit can roll out a coordinated update across every microservice.”

According to the Argo CD documentation, the App of Apps pattern β€œenables hierarchical application management, making it possible to group related applications under a single parent for coordinated sync and versioning.”

Key point: Child Applications inherit the parent’s sync policy, ensuring consistent drift correction across the entire stack without extra configuration.


πŸ›‘ Observability β€” Adding Health Checks

Kubernetes health probes call specific HTTP endpoints; the application must expose them for the probes to succeed.

# src/main.py
from fastapi import FastAPI app = FastAPI() @app.get("/health")
async def health(): return {"status": "ok"} @app.get("/ready")
async def ready(): # Insert readiness logic, e.g., DB connection test return {"ready": True}
Enter fullscreen mode Exit fullscreen mode

What this does:

  • /health: simple liveness endpoint that always returns 200.
  • /ready: readiness endpoint that can include checks such as database connectivity.

After updating the image, trigger a sync in Argo CD:

$ argocd app sync python-microservices
Syncing application 'python-microservices'...



APPLICATION STATUS HEALTH SYNCED AGE
python-microservices Synced Healthy True 2s
Enter fullscreen mode Exit fullscreen mode

Why not rely solely on external monitoring? Native Kubernetes probes allow the kubelet to restart unhealthy pods instantly, reducing mean time to recovery (MTTR) compared with an external alert loop.


🟩 Final Thoughts

Using the App of Apps pattern in Argo CD provides a single source of truth for a multi‑service Python stack while preserving independent versioning. Each microservice can follow its own release cadence, yet the parent Application guarantees system‑wide synchronization, lowering operational overhead and preventing costly drift.

Developers can focus on writing Python code and packaging it as a Helm chart; the Git‑ops pipeline handles deployment, health monitoring, and rollback. The outcome is a reproducible, auditable, and cost‑effective production environment.


❓ Frequently Asked Questions

How does the App of Apps pattern differ from using multiple independent Argo CD Applications?

Both use separate Application resources, but the App of Apps pattern nests them under a parent, allowing a single sync operation, shared sync policies, and hierarchical RBAC, which simplifies management of large microservice fleets.

Can I use Kustomize instead of Helm for the child Applications?

Yes, Argo CD supports both Helm and Kustomize. Choose Kustomize when you need simple overlays without templating logic; Helm is preferable for parameterized charts and complex dependency management.

What is the recommended way to handle secret management for the Python services?

Store secrets in Kubernetes Secret objects and reference them in the Helm values file using envFrom or env. For production, integrate with external secret stores such as HashiCorp Vault or AWS Secrets Manager, and configure the pod to retrieve them at runtime.


πŸ’‘ Want to practise this hands-on? DigitalOcean gives new accounts $200 free credit for 60 days β€” enough to spin up a full Linux/Docker/Kubernetes environment at no cost.

πŸ“š Recommended reading: Best DevOps & cloud books on Amazon β€” from Linux fundamentals to Kubernetes in production, curated for working engineers.

πŸ“š References & Further Reading

  • Official Argo CD documentation β€” comprehensive guide to the App of Apps pattern: argo-cd.readthedocs.io
  • FastAPI official docs β€” building asynchronous Python APIs: fastapi.tiangolo.com
  • Helm documentation β€” packaging Kubernetes applications: helm.sh

Top comments (0)