All resources
GitOps · Interview prep

GitOps interview questions

GitOps interview questions from fresher to senior — core principles, Argo CD and Flux, environment promotion and repo structure, and advanced multi-cluster and progressive delivery, tagged by experience level.

ExperienceAll levelsFresherJuniorMidSenior

Fresher 0–1y · Junior 1–3y · Mid 3–6y · Senior 6+y — every answer is tagged so you can prep for your level.

Fundamentals
What is GitOps?Fresher

An operating model where Git is the single source of truth for declarative infrastructure and apps, and an in-cluster agent continuously reconciles the live state to match the repo — so deploys are Git commits and the cluster is auditable.

git commitcontroller detectsreconcilecluster matches Git
What are the core GitOps principles?Fresher

Declarative desired state, versioned and immutable in Git, pulled automatically by an agent, and continuously reconciled. Together they make deploys reviewable, auditable, and self-healing.

Pull-based vs push-based deployment?Junior

Push means CI runs kubectl/helm against the cluster with credentials it holds. Pull (GitOps) means an in-cluster controller watches Git and applies changes itself, so cluster credentials never leave the cluster and drift is auto-corrected.

Push couples CI to every cluster and scatters kubeconfig credentials into pipelines; a leaked CI token becomes cluster access. Pull keeps credentials inside each cluster and turns deployment into a Git change the controller applies — more secure and auditable at scale.

CI pushes image to registryCI commits new tag to Gitin-cluster agent pullsagent applies
What is the reconciliation loop?Junior

The controller continuously compares desired state (Git) to observed state (cluster) and converges them. It is level-based, not event-based, so it self-heals: a manually deleted resource is recreated on the next sync.

Level-based means it acts on the current gap, not on a stream of events, so a missed event never leaves you inconsistent — the next reconcile still converges. That is why a hand-deleted Deployment simply comes back.

What is drift and how does GitOps handle it?Mid

Drift is any live change that diverges from Git. GitOps detects it every sync and either flags it or reverts it (self-heal), making Git the enforced source of truth rather than a hopeful record.

See exactly what drifted
argocd app diff web       # live vs desired (Git)
argocd app get  web       # Sync + Health status
Argo CD & Flux
What is an Argo CD Application?Mid

A CRD that pairs a source (repo path or Helm chart at a revision) with a destination (cluster/namespace) and a sync policy. Argo renders the manifests and reconciles them, reporting Sync and Health status.

source (repo path)render manifestssync to clusterreport Sync + Health
An Application
kind: Application
spec:
  source:
    repoURL: https://github.com/org/config
    path: apps/web/overlays/prod
    targetRevision: main
  destination:
    namespace: web
  syncPolicy:
    automated: { prune: true, selfHeal: true }
Sync status vs health status in Argo?Mid

Sync status says whether the live objects match Git (Synced / OutOfSync); health status says whether they are actually working (Healthy / Progressing / Degraded). You can be Synced but Degraded — the right YAML deployed, but the app is crashing.

What is the app-of-apps pattern and ApplicationSets?Mid

App-of-apps is a root Application that deploys child Applications, bootstrapping a whole cluster from one entry point. ApplicationSets generate Applications from a generator (list, Git directories, clusters), scaling GitOps across many apps/clusters.

App-of-apps bootstraps a cluster from a single root you point Argo at. ApplicationSets go further — a generator templates one Application per item (per Git folder, per registered cluster), so onboarding an app or cluster is adding an entry, not hand-writing YAML.

How do sync waves and hooks work?Mid

Annotations order resources into waves (e.g. CRDs and namespaces before workloads) and run PreSync/PostSync hook jobs (migrations, smoke tests). They give ordering and lifecycle control within a single sync.

Order + a pre-sync migration
metadata:
  annotations:
    argocd.argoproj.io/sync-wave: "-1"   # CRDs/namespaces first
    argocd.argoproj.io/hook: PreSync      # e.g. a DB migration job
How does Flux structure the same job?Mid

Flux is a set of controllers: a GitRepository/OCIRepository source plus Kustomization or HelmRelease objects that reconcile paths/charts, with dependsOn ordering and image-automation controllers to bump tags via commits.

Source + Kustomization
kind: GitRepository
spec: { url: https://github.com/org/config, ref: { branch: main } }
---
kind: Kustomization
spec:
  path: ./apps/web
  prune: true
  sourceRef: { kind: GitRepository, name: config }
Argo CD vs Flux — how do you choose?Senior

Argo CD ships a rich UI and app-centric model (Applications, projects, SSO) that teams like for visibility; Flux is lean, CRD/GitOps-toolkit native, and composes well with Kustomize/Helm controllers. Both are CNCF-graduated — pick on UI needs, multi-tenancy model, and team preference.

Promotion & structure
How do you promote across environments in GitOps?Mid

Model each environment as a path/overlay or branch; promotion is a commit/PR that updates the target environment’s desired revision or image tag. Keep it a reviewed Git change, not an imperative action.

image built + pushedPR bumps prod overlay tagreview + mergeagent reconciles prod
Promotion is a commit
# bump the tag in the prod overlay, then commit
cd overlays/prod && kustomize edit set image app=app:v2
git commit -am "promote app v2 to prod"
How do you manage secrets in GitOps?Mid

Never commit plaintext. Use Sealed Secrets (encrypted in Git, decrypted in-cluster), SOPS-encrypted manifests, or the External Secrets Operator pulling from Vault/cloud managers — so Git holds references or ciphertext only.

The rule is simple: Git never holds a readable secret. Sealed Secrets and SOPS put ciphertext in Git that only the cluster can decrypt; the External Secrets Operator keeps just a reference in Git and pulls the real value from Vault/SSM at runtime.

Seal before committing
kubeseal < secret.yaml > sealed-secret.yaml   # encrypted
git add sealed-secret.yaml                     # safe to commit
Mono-repo vs repo-per-environment?Senior

One repo with per-env overlays is simpler and keeps shared bases DRY; separate repos give stronger access boundaries and independent history. Many teams use a config repo separate from app code, with environment overlays inside it.

The bigger split is app code vs config: keep manifests in a dedicated config repo so a deploy is a config commit, not an app commit, and so cluster credentials never touch app repos. Within it, per-env overlays (dev/stg/prod) share a common base.

How does image automation fit GitOps?Senior

An image updater (Argo Image Updater, Flux image-automation) watches the registry and writes the new tag/digest back to Git, so a build promotion becomes a commit the reconciler then applies — keeping Git the source of truth.

Flux image policy
kind: ImagePolicy
spec:
  imageRepositoryRef: { name: app }
  policy: { semver: { range: ">=1.0.0" } }
# controller commits the new tag back to Git
Advanced & failure modes
How do you do progressive delivery with GitOps?Senior

Layer Argo Rollouts or Flagger on top: they drive canary/blue-green by analyzing metrics (Prometheus) and automatically promote or roll back, while GitOps still owns the desired state. GitOps deploys; the rollout controller manages the shift.

GitOps gets the new version into the cluster; the rollout controller (Argo Rollouts / Flagger) then shifts traffic in steps, runs metric analysis at each step, and promotes or rolls back automatically — so a bad version never fully rolls out.

GitOps deploys new versionshift 10% (canary)analyze metricspromote or auto-rollback
How do you run GitOps across many clusters?Senior

A management cluster with ApplicationSet cluster generators (or Flux per cluster) fans the same config out, using per-cluster values/overlays and cluster labels — with RBAC and tenancy so teams only reconcile their own scope.

One app per registered cluster
kind: ApplicationSet
spec:
  generators:
    - clusters: {}          # every registered cluster
  template:
    spec:
      destination: { name: '{{name}}', namespace: web }
What is your disaster-recovery story with GitOps?Senior

Because desired state lives in Git, you rebuild a cluster by pointing a fresh GitOps controller at the repo and letting it reconcile. You still must restore stateful data (PV backups/Velero) and any bootstrap secrets separately.

Recreating workloads is easy — install the controller, point it at the config repo, let it reconcile. The parts Git does not hold are what you must plan for: persistent volume data (Velero/snapshots) and the bootstrap secret that lets the controller decrypt everything else.

fresh clusterinstall GitOps agentpoint at config reporeconcile + restore data
A sync is stuck OutOfSync — how do you debug it?Mid

Read the status: get the app for conditions and the failing resource, diff to see what will not converge, and check for a failing hook, an immutable-field change, or a missing CRD. Then re-sync (with prune/replace if needed).

argocd app get: conditionsargocd app difffind failing resource / hooksync (prune/replace)
Triage a stuck app
argocd app get  web
argocd app diff web
argocd app sync web --prune
Someone changed the cluster by hand — what happens and how do you prevent it?Mid

With self-heal on, the next reconcile reverts it; without it, Argo shows OutOfSync. Prevent recurring drift with tight RBAC and admission policy so humans cannot mutate GitOps-managed namespaces directly.

Turn on self-heal
argocd app set web --self-heal --auto-prune
# plus RBAC so only the agent can write to that namespace
Go deeper
Full, hands-on DevSecOps courses
Browse courses