Skip to main content

Hands-on exercises and projects


Table of Contents

  1. Exercise 1: ArgoCD setup
  2. Exercise 2: First GitOps deployment
  3. Exercise 3: Multi-environments
  4. Exercise 4: Secrets management
  5. Final project: Complete pipeline
  6. Additional resources

1 - Exercise 1: ArgoCD setup

Objective

Install and configure ArgoCD on a Kubernetes cluster.

Prerequisites

  • Kubernetes cluster (minikube, kind, or cloud)
  • kubectl configured
  • Git repository

Steps

# 1. Créer le namespace
kubectl create namespace argocd

# 2. Installer ArgoCD
kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml

# 3. Attendre que les pods soient prêts
kubectl wait --for=condition=Ready pods --all -n argocd --timeout=300s

# 4. Récupérer le mot de passe admin
kubectl -n argocd get secret argocd-initial-admin-secret \
-o jsonpath="{.data.password}" | base64 -d && echo

# 5. Port-forward pour accéder à l'UI
kubectl port-forward svc/argocd-server -n argocd 8080:443

# 6. Accéder à https://localhost:8080
# Username: admin
# Password: (récupéré à l'étape 4)

Validation

Validation checklist
  • All ArgoCD pods are Running
  • The UI is accessible
  • Admin login successful
  • Dashboard visible without errors

🔝 Back to table of contents


2 - Exercise 2: First GitOps deployment

Objective

Deploy a simple application via GitOps.

Repo structure

gitops-exercice/
├── apps/
│ └── hello-world/
│ ├── deployment.yaml
│ └── service.yaml
└── README.md

Files to create

# apps/hello-world/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: hello-world
labels:
app: hello-world
spec:
replicas: 2
selector:
matchLabels:
app: hello-world
template:
metadata:
labels:
app: hello-world
spec:
containers:
- name: hello-world
image: nginx:1.25
ports:
- containerPort: 80
# apps/hello-world/service.yaml
apiVersion: v1
kind: Service
metadata:
name: hello-world
spec:
selector:
app: hello-world
ports:
- port: 80
targetPort: 80

Create the ArgoCD Application

# Appliquer via kubectl ou UI
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: hello-world
namespace: argocd
spec:
project: default
source:
repoURL: https://github.com/VOTRE-USER/gitops-exercice.git
targetRevision: HEAD
path: apps/hello-world
destination:
server: https://kubernetes.default.svc
namespace: default
syncPolicy:
automated:
prune: true
selfHeal: true

Tests

# Vérifier le déploiement
kubectl get deployment hello-world
kubectl get pods -l app=hello-world

# Tester le self-healing
kubectl delete pod -l app=hello-world
# Les pods sont recréés automatiquement

# Tester la réconciliation
kubectl scale deployment hello-world --replicas=5
# ArgoCD rétablit à 2 replicas (comme dans Git)

🔝 Back to table of contents


3 - Exercise 3: Multi-environments

Objective

Configure deployments for dev and prod with Kustomize.

Structure

gitops-exercice/
└── apps/
└── hello-world/
├── base/
│ ├── kustomization.yaml
│ ├── deployment.yaml
│ └── service.yaml
└── overlays/
├── dev/
│ ├── kustomization.yaml
│ └── namespace.yaml
└── prod/
├── kustomization.yaml
├── namespace.yaml
└── replicas-patch.yaml

Kustomize files

# base/kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization

resources:
- deployment.yaml
- service.yaml

commonLabels:
app: hello-world
# overlays/dev/kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization

namespace: dev

resources:
- ../../base
- namespace.yaml

images:
- name: nginx
newTag: "1.25"
# overlays/dev/namespace.yaml
apiVersion: v1
kind: Namespace
metadata:
name: dev
# overlays/prod/kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization

namespace: prod

resources:
- ../../base
- namespace.yaml

patches:
- path: replicas-patch.yaml

images:
- name: nginx
newTag: "1.25-alpine"
# overlays/prod/replicas-patch.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: hello-world
spec:
replicas: 5

ArgoCD Applications

# hello-world-dev
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: hello-world-dev
namespace: argocd
spec:
source:
path: apps/hello-world/overlays/dev
destination:
namespace: dev
---
# hello-world-prod
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: hello-world-prod
namespace: argocd
spec:
source:
path: apps/hello-world/overlays/prod
destination:
namespace: prod

Validation

# Vérifier dev
kubectl get all -n dev
# 2 replicas, nginx:1.25

# Vérifier prod
kubectl get all -n prod
# 5 replicas, nginx:1.25-alpine

🔝 Back to table of contents


4 - Exercise 4: Secrets management

Objective

Use Sealed Secrets to manage secrets in GitOps.

Installation

# Installer le controller
kubectl apply -f https://github.com/bitnami-labs/sealed-secrets/releases/download/v0.24.0/controller.yaml

# Installer kubeseal
brew install kubeseal # macOS
# ou télécharger depuis GitHub

Create a Sealed Secret

# 1. Créer le secret en clair (local, ne pas commiter)
kubectl create secret generic db-creds \
--from-literal=username=admin \
--from-literal=password=supersecret123 \
--namespace=prod \
--dry-run=client -o yaml > secret.yaml

# 2. Chiffrer avec kubeseal
kubeseal --format yaml < secret.yaml > sealed-secret.yaml

# 3. Supprimer le secret en clair
rm secret.yaml

# 4. Ajouter le sealed-secret au repo
mv sealed-secret.yaml apps/hello-world/overlays/prod/

Use the secret

# Modifier deployment pour utiliser le secret
spec:
containers:
- name: hello-world
env:
- name: DB_USERNAME
valueFrom:
secretKeyRef:
name: db-creds
key: username
- name: DB_PASSWORD
valueFrom:
secretKeyRef:
name: db-creds
key: password

Validation

# Le SealedSecret est dans Git ✅
# Le Secret Kubernetes est créé automatiquement
kubectl get secret db-creds -n prod

# Vérifier les valeurs
kubectl get secret db-creds -n prod -o jsonpath='{.data.username}' | base64 -d
# admin

🔝 Back to table of contents


5 - Final project: Complete pipeline

Objective

Create a complete GitOps pipeline with CI/CD, multi-environments, and secrets.

Architecture

Complete structure

gitops-final/
├── .github/
│ └── workflows/
│ └── validate.yml
├── apps/
│ └── webapp/
│ ├── base/
│ │ ├── kustomization.yaml
│ │ ├── deployment.yaml
│ │ ├── service.yaml
│ │ └── configmap.yaml
│ └── overlays/
│ ├── dev/
│ ├── staging/
│ └── prod/
├── infrastructure/
│ ├── argocd/
│ └── sealed-secrets/
└── README.md

GitHub Actions for validation

# .github/workflows/validate.yml
name: Validate

on:
pull_request:
paths:
- 'apps/**'

jobs:
validate:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- name: Install tools
run: |
curl -s "https://raw.githubusercontent.com/kubernetes-sigs/kustomize/master/hack/install_kustomize.sh" | bash
sudo mv kustomize /usr/local/bin/

- name: Validate YAML
run: |
pip install yamllint
yamllint apps/

- name: Build Kustomize
run: |
for overlay in apps/webapp/overlays/*/; do
echo "Building $overlay"
kustomize build $overlay > /dev/null
done

ApplicationSet

apiVersion: argoproj.io/v1alpha1
kind: ApplicationSet
metadata:
name: webapp
namespace: argocd
spec:
generators:
- list:
elements:
- env: dev
namespace: dev
- env: staging
namespace: staging
- env: prod
namespace: production
template:
metadata:
name: 'webapp-{{env}}'
spec:
project: default
source:
repoURL: https://github.com/VOTRE-USER/gitops-final.git
targetRevision: HEAD
path: 'apps/webapp/overlays/{{env}}'
destination:
server: https://kubernetes.default.svc
namespace: '{{namespace}}'
syncPolicy:
automated:
prune: true
selfHeal: true
syncOptions:
- CreateNamespace=true

Expected deliverables

Project checklist
  • Structured GitOps repository
  • Kustomize base + 3 overlays (dev, staging, prod)
  • GitHub Actions for validation
  • Sealed Secrets for credentials
  • ApplicationSet deploying the 3 environments
  • README with documentation
  • Documented promotion workflow

🔝 Back to table of contents


6 - Additional resources

Official documentation

ResourceLink
ArgoCDhttps://argo-cd.readthedocs.io/
Fluxhttps://fluxcd.io/docs/
Kustomizehttps://kustomize.io/
Sealed Secretshttps://sealed-secrets.netlify.app/

Example repos

# ArgoCD examples
git clone https://github.com/argoproj/argocd-example-apps

# Flux examples
git clone https://github.com/fluxcd/flux2-kustomize-helm-example

Certifications

  • Certified Kubernetes Administrator (CKA)
  • Certified GitOps Associate (CGOA) - Linux Foundation
  • "GitOps and Kubernetes" - Billy Yuen, et al.
  • "Argo CD in Practice" - Livio Zanol Puppato

🔝 Back to table of contents


Congratulations!

You have completed the GitOps course! You now master:

  • ✅ The fundamental principles of GitOps
  • ✅ The difference between Push and Pull models
  • ✅ Using ArgoCD and/or Flux
  • ✅ Secrets management in GitOps
  • ✅ Multi-environment deployments
  • ✅ GitOps best practices

Next steps

  1. Practice on personal projects
  2. Contribute to open source projects
  3. Explore ArgoCD Rollouts for progressive deployments
  4. Go deeper with Argo Events and Argo Workflows

← Back to the course table of contents