A minimal Flask app demonstrating Scenario 3: GitOps with Argo CD, GitHub, and AKS from the Microsoft Architecture Center.
Developer pushes code
│
▼
GitHub (paktech-hello)
│
▼
GitHub Actions CI
├── Lint (ruff + black)
├── Build Docker image
├── Push to ACR
└── Update image tag in paktech-hello-gitops repo
│
▼
GitHub (paktech-hello-gitops)
apps/paktech-hello/deployment.yaml
│
│ Argo CD polls every 3 min
▼
AKS Cluster
└── Argo CD detects drift → syncs
│
▼
paktech-hello namespace
└── Flask app pods (2 replicas)
└── LoadBalancer service (public IP)
| Repo | Purpose |
|---|---|
paktech-hello |
App code, Dockerfile, GitHub Actions CI |
paktech-hello-gitops |
Kubernetes manifests — source of truth for Argo CD |
paktech-hello/
├── app/
│ ├── app.py # Flask application
│ └── requirements.txt # Python dependencies
├── Dockerfile # Multi-stage Docker build
├── terraform/ # Infrastructure as Code
│ ├── main.tf # AKS + ACR + Argo CD + OIDC
│ ├── variables.tf
│ ├── outputs.tf
│ └── terraform.tfvars.example
└── .github/
└── workflows/
└── ci.yml # Build → Push → Update GitOps repo
- Azure CLI (
az) - Terraform >= 1.6
- kubectl
- Docker
- GitHub account with two repos created under
PakTechLimited:paktech-hello(this repo)paktech-hello-gitops
cd terraform
cp terraform.tfvars.example terraform.tfvars
# Edit terraform.tfvars with your subscription_id
az login
terraform init
terraform plan -var="subscription_id=$(az account show --query id -o tsv)" -out=tfplan
terraform apply tfplanAfter terraform apply, run:
terraform output argocd_instructionsAdd these secrets to github.com/PakTechLimited/paktech-hello → Settings → Secrets:
| Secret | Value |
|---|---|
AZURE_CLIENT_ID |
from terraform output github_actions_client_id |
AZURE_TENANT_ID |
from terraform output tenant_id |
AZURE_SUBSCRIPTION_ID |
your subscription ID |
ACR_LOGIN_SERVER |
from terraform output acr_login_server |
ACR_NAME |
from terraform output acr_name |
GITOPS_PAT |
GitHub PAT with repo write scope for paktech-hello-gitops |
az aks get-credentials \
--resource-group paktech-hello-rg-dev \
--name paktech-hello-aks-dev# Port-forward Argo CD UI
kubectl port-forward svc/argocd-server -n argocd 8080:80 &
# Get admin password
ARGOCD_PASSWORD=$(kubectl get secret argocd-initial-admin-secret \
-n argocd -o jsonpath="{.data.password}" | base64 -d)
# Login to Argo CD CLI
argocd login localhost:8080 \
--username admin \
--password $ARGOCD_PASSWORD \
--insecure
# Add the GitOps repo (if private — needs a PAT)
argocd repo add https://github.com/PakTechLimited/paktech-hello-gitops \
--username git \
--password <YOUR_GITHUB_PAT>kubectl apply -f https://raw.githubusercontent.com/PakTechLimited/paktech-hello-gitops/main/apps/paktech-hello/argocd-app.yamlOr via Argo CD UI at http://localhost:8080.
Push any commit to main:
git commit --allow-empty -m "ci: trigger first deployment"
git pushGitHub Actions will:
- Build the Docker image
- Push to ACR
- Update the image tag in
paktech-hello-gitops
Argo CD will detect the change within 3 minutes and deploy to AKS.
kubectl get svc -n paktech-hello
# Wait for EXTERNAL-IP to be assigned (1-2 minutes)Open http://<EXTERNAL-IP> in your browser.
See Argo CD UI at http://localhost:8080:
# Check sync status
argocd app get paktech-hello
# Manual sync
argocd app sync paktech-hello
# View app history
argocd app history paktech-hello
# Rollback to previous version
argocd app rollback paktech-hello <revision-number>cd terraform
terraform destroy -var="subscription_id=$(az account show --query id -o tsv)"