Infra gitops deployment review
Skill ivanshamaev/de-agent-skills/group_skills/infra_dataops_group_skills/infra_gitops_deployment_review
Профессиональные Data Engineering Agent Skills для разработки AI Agentic Data Platform
npx -y skills add ivanshamaev/de-agent-skills --skill infra_gitops_deployment_reviewAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
2 things to look at
- no licenseNo license file was found in the repository. Code published without one is not open source by default, so using it at work is a question for whoever answers licensing questions where you are.
- 13 stars13 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
What its author says it does
Copied from the file, not written here
GitOps deployment review — ArgoCD Application/AppProject CRDs, app-of-apps pattern, sync policies (automated+self-heal+prune), drift detection and remediation, FluxCD HelmRelease/Kustomization, git repository structure for GitOps (app code vs config repo separation), image update automation, progressive delivery (Argo Rollouts canary/blue-green), GitOps for data platform components (Airflow/Kafka/Spark)
SKILL.md
9.7 KB, as published. Nobody here has run it
GitOps Deployment Review
When to Use
- Setting up ArgoCD or FluxCD for a data platform
- Reviewing GitOps repo structure and separation of concerns
- Diagnosing drift between Git desired state and cluster actual state
- Implementing progressive delivery (canary/blue-green) for pipeline components
- Onboarding a new team to GitOps workflow
Repository Structure
Config Repo Separation
# app-code-repo/ — application source, Dockerfiles, unit tests
# gitops-config-repo/ — K8s manifests only, no app code
gitops-config-repo/
apps/ # ArgoCD App-of-Apps root
production/
airflow.yaml
kafka.yaml
spark-history.yaml
staging/
airflow.yaml
base/ # Kustomize base manifests
airflow/
deployment.yaml
service.yaml
kustomization.yaml
overlays/ # environment-specific patches
production/
airflow/
kustomization.yaml # patches: replicas, image tag, resources
patch-replicas.yaml
staging/
airflow/
kustomization.yaml
helm/ # Helm values per environment
airflow/
values-prod.yaml
values-staging.yaml
ArgoCD — Application CRD
Basic Application
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: airflow-production
namespace: argocd
finalizers:
- resources-finalizer.argocd.argoproj.io # cascade delete on app removal
spec:
project: data-platform
source:
repoURL: https://github.com/my-org/gitops-config
targetRevision: main # or specific tag: v1.2.3
path: overlays/production/airflow
destination:
server: https://kubernetes.default.svc
namespace: airflow
syncPolicy:
automated:
prune: true # delete resources removed from Git
selfHeal: true # revert manual cluster changes
allowEmpty: false # never sync if source results in empty manifests
syncOptions:
- CreateNamespace=true
- PrunePropagationPolicy=foreground
- RespectIgnoreDifferences=true
retry:
limit: 5
backoff:
duration: 5s
factor: 2
maxDuration: 3m
ignoreDifferences:
- group: apps
kind: Deployment
jsonPointers:
- /spec/replicas # HPA manages replicas — ignore diff
- group: ""
kind: ConfigMap
name: airflow-config
jsonPointers:
- /data/airflow.cfg # airflow generates this at runtime
Helm Application
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: kafka-production
namespace: argocd
spec:
project: data-platform
source:
repoURL: https://charts.bitnami.com/bitnami
chart: kafka
targetRevision: "26.6.2" # pin exact chart version
helm:
releaseName: kafka
valuesObject: # inline values
replicaCount: 3
persistence:
size: 500Gi
storageClass: gp3
valueFiles:
- values-prod.yaml # from source repo at path
destination:
server: https://kubernetes.default.svc
namespace: kafka
App-of-Apps Pattern
# apps/root-app.yaml — bootstraps all other apps
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: root
namespace: argocd
spec:
project: default
source:
repoURL: https://github.com/my-org/gitops-config
targetRevision: main
path: apps/production # directory containing all Application YAMLs
destination:
server: https://kubernetes.default.svc
namespace: argocd
syncPolicy:
automated:
prune: true
selfHeal: true
# apps/production/airflow.yaml
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: airflow
namespace: argocd
spec:
project: data-platform
source:
repoURL: https://github.com/my-org/gitops-config
targetRevision: main
path: helm/airflow
helm:
valueFiles: [values-prod.yaml]
destination:
server: https://kubernetes.default.svc
namespace: airflow
syncPolicy:
automated:
prune: true
selfHeal: true
AppProject — RBAC and Scope Control
apiVersion: argoproj.io/v1alpha1
kind: AppProject
metadata:
name: data-platform
namespace: argocd
spec:
description: "Data platform workloads — Airflow, Kafka, Spark"
sourceRepos:
- https://github.com/my-org/gitops-config
- https://charts.bitnami.com/bitnami
- https://helm.releases.hashicorp.com
destinations:
- server: https://kubernetes.default.svc
namespace: airflow
- server: https://kubernetes.default.svc
namespace: kafka
- server: https://kubernetes.default.svc
namespace: spark
clusterResourceWhitelist:
- group: ""
kind: Namespace
- group: rbac.authorization.k8s.io
kind: ClusterRole
namespaceResourceBlacklist:
- group: ""
kind: ResourceQuota # only platform team can set quotas
roles:
- name: developer
description: "Can sync apps but not delete"
policies:
- p, proj:data-platform:developer, applications, get, data-platform/*, allow
- p, proj:data-platform:developer, applications, sync, data-platform/*, allow
groups:
- data-engineering-team
Drift Detection and Remediation
# Check all app sync status
argocd app list
# Detailed sync status for an app
argocd app get airflow-production
# Show diff between Git desired state and cluster actual state
argocd app diff airflow-production
# Force sync (overwrite manual changes)
argocd app sync airflow-production --force
# Hard refresh (bypass cache, re-evaluate manifests)
argocd app get airflow-production --hard-refresh
# Sync specific resources only
argocd app sync airflow-production --resource apps:Deployment:airflow-scheduler
Drift Detection Script
#!/bin/bash
# Report all apps with drift
argocd app list -o json | \
jq -r '.[] | select(.status.sync.status != "Synced") |
"\(.metadata.name): sync=\(.status.sync.status) health=\(.status.health.status)"'
FluxCD Alternative
HelmRelease
apiVersion: helm.toolkit.fluxcd.io/v2beta2
kind: HelmRelease
metadata:
name: airflow
namespace: airflow
spec:
interval: 10m
chart:
spec:
chart: airflow
version: "1.13.*" # semver range — auto-upgrade patch
sourceRef:
kind: HelmRepository
name: apache-airflow
namespace: flux-system
values:
executor: KubernetesExecutor
workers:
replicas: 0
upgrade:
remediation:
retries: 3
strategy: rollback
rollback:
timeout: 5m
cleanupOnFail: true
Image Update Automation
# Flux: automatically update image tag when new image is pushed
apiVersion: image.toolkit.fluxcd.io/v1beta2
kind: ImageUpdateAutomation
metadata:
name: airflow-image-update
namespace: flux-system
spec:
interval: 5m
sourceRef:
kind: GitRepository
name: gitops-config
git:
checkout:
ref:
branch: main
commit:
author:
email: [email protected]
name: FluxCD Bot
messageTemplate: "ci: auto-update airflow image to {{range .Updated.Images}}{{.}}{{end}}"
push:
branch: main
update:
path: ./overlays/production/airflow
strategy: Setters
Argo Rollouts — Progressive Delivery
# Canary deployment for Airflow API server
apiVersion: argoproj.io/v1alpha1
kind: Rollout
metadata:
name: airflow-webserver
namespace: airflow
spec:
replicas: 5
selector:
matchLabels:
app: airflow-webserver
template:
spec:
containers:
- name: webserver
image: apache/airflow:2.8.0
strategy:
canary:
steps:
- setWeight: 20 # 20% traffic to new version
- pause: {duration: 5m} # wait 5 min, check metrics
- setWeight: 50
- pause: {duration: 5m}
- setWeight: 100 # full rollout
canaryService: airflow-webserver-canary
stableService: airflow-webserver-stable
trafficRouting:
nginx:
stableIngress: airflow-ingress
Anti-Patterns
- Storing secrets in Git — even encrypted secrets rotate manually; use External Secrets Operator + Vault/SSM + reference in Git, not the secret value.
- Pointing ArgoCD at
mainbranch HEAD — config changes deploy instantly without review; use areleasebranch or tag promotion workflow. - No
ignoreDifferencesfor HPA-managed replicas — ArgoCD resets replica count every sync cycle; always ignore/spec/replicasfor HPA-scaled deployments. - App-of-apps without AppProject scoping — any app can deploy to any namespace; always define AppProject with explicit destination namespaces.
prune: truewithout testing in staging — accidental resource deletion on first sync; enable pruning only after the config repo is trusted.- Applying ArgoCD YAML with kubectl instead of ArgoCD CLI — bypasses ArgoCD reconciliation; always manage Application resources through ArgoCD itself.
References
- ArgoCD:
argo-cd.readthedocs.io/en/stable/ - Argo Rollouts:
argo-rollouts.readthedocs.io/en/stable/ - FluxCD:
fluxcd.io/flux/ - GitOps principles:
opengitops.dev - Related skills:
[[github-actions-dataops]],[[infra-kubernetes-security-audit]],[[infra-terraform-review]]