DevOps · GitOps|14 min read|

GitOps for Enterprises with ArgoCD

GitOps is an operational model where the declarative state of your infrastructure and applications lives in Git, and an automated operator continuously reconciles the current cluster state against that desired state. For enterprises, this isn't just a process improvement — it transforms operational accountability: every production change has an author, timestamp, review trail, and can be reverted in seconds. This guide documents how we implement GitOps with ArgoCD in real enterprise environments.

Why GitOps changes enterprise operations

The traditional push-based model (CI pipeline applies changes directly to the cluster via kubectl) has fundamental auditability and consistency problems. What version is running in production right now? Who applied the last change and when? Can I reproduce the exact cluster state from three weeks ago? With GitOps, all these questions are answered by the Git history.

The less talked-about benefit: GitOps makes manual production changes non-persistent by design. ArgoCD detects any deviation from the declared state in Git and automatically reverts it. This eliminates the practice of applying hotfixes directly to the cluster without documentation — one of the most frequent sources of hard-to-diagnose incidents.

ArgoCD: base configuration for production

ArgoCD introduces the Application as a Kubernetes resource. Each Application defines which Git repository to watch, which path contains the manifests, and which cluster/namespace to apply them to.

yaml
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: api-production
  namespace: argocd
spec:
  project: default
  source:
    repoURL: https://github.com/company/infra-gitops.git
    targetRevision: main
    path: apps/api/production
  destination:
    server: https://kubernetes.default.svc
    namespace: production
  syncPolicy:
    automated:
      prune: true       # removes resources no longer defined in Git
      selfHeal: true    # reverts manual cluster changes
    syncOptions:
    - CreateNamespace=true

selfHeal: true enables automatic reconciliation against drift. prune: true removes cluster resources that are no longer defined in Git. For high-criticality changes, consider disabling automated sync and requiring manual sync with approval — the balance between automation and control depends on the service SLA.

App of Apps: architecture for multiple teams

The App of Apps pattern allows a root Application to manage all other applications as code. Instead of manually creating each Application through the UI or kubectl, you define a root app that watches a directory containing all other application manifests.

yaml
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: root-apps
  namespace: argocd
spec:
  source:
    repoURL: https://github.com/company/infra-gitops.git
    path: apps/
    directory:
      recurse: true
  destination:
    server: https://kubernetes.default.svc
    namespace: argocd
  syncPolicy:
    automated:
      prune: true
      selfHeal: true

With this architecture, each team manages their own applications through PRs to the central infrastructure repository. No developer needs direct access to the production cluster — ArgoCD is the only actor that applies changes.

Secrets Management with GitOps: the real challenge

Secrets management is the primary barrier to GitOps adoption in enterprises. You can't commit credentials to Git, even in private repositories. The two production-grade solutions we use in enterprise projects:

Sealed Secrets (Bitnami): Encrypts secrets with the cluster's public key. The encrypted SealedSecret can safely live in Git — only the cluster can decrypt it with its private key. This is the simplest solution when all secrets are cluster-specific.

bash
# Create and seal a Secret in one command
kubectl create secret generic db-credentials \
  --from-literal=password=mysecretpassword \
  --dry-run=client -o yaml | \
  kubeseal --format yaml > sealed-db-credentials.yaml

# The sealed file can be safely committed to Git

External Secrets Operator: Syncs secrets from AWS Secrets Manager, HashiCorp Vault, GCP Secret Manager, or Azure Key Vault directly to Kubernetes Secrets. The best choice for enterprises that already have a centralized secrets management solution or need to rotate credentials without redeploying.

Enterprise RBAC with ArgoCD Projects

In an organization with multiple teams sharing the same cluster, access control in ArgoCD is critical. AppProjects let you restrict which repositories each team can use, which clusters they can deploy to, and which namespaces they can manage.

yaml
apiVersion: argoproj.io/v1alpha1
kind: AppProject
metadata:
  name: team-payments
  namespace: argocd
spec:
  description: Payments team project
  sourceRepos:
  - 'https://github.com/company/payments-service.git'
  destinations:
  - namespace: payments-*
    server: https://kubernetes.default.svc
  clusterResourceWhitelist:
  - group: ''
    kind: Namespace

The payments team can only deploy from their repository, only to namespaces prefixed with payments-. Any attempt to access other namespaces or clusters fails at ArgoCD validation, without requiring manual intervention.

CI Integration: the pull vs. push distinction

With GitOps, the CI pipeline only updates the infrastructure repository (new image tag, new configuration). ArgoCD detects the change and applies the new state to the cluster. CI never communicates directly with the cluster.

yaml
# GitLab CI — stage that updates the image tag in the infra repo
update-image-tag:
  stage: deploy
  script:
    - git clone https://oauth2:${GITOPS_TOKEN}@github.com/company/infra-gitops.git
    - cd infra-gitops
    - |
      sed -i "s|image: company/api:.*|image: company/api:${CI_COMMIT_SHORT_SHA}|g" \
        apps/api/production/deployment.yaml
    - git config user.email "ci@company.com"
    - git config user.name "GitLab CI"
    - git commit -am "ci: update api to ${CI_COMMIT_SHORT_SHA}"
    - git push origin main
  only:
    - main

This separation is fundamental for auditing and compliance. Every production change has a Git commit with an identified author. Rollback is a git revert. ArgoCD's reconciliation guarantees the cluster state always converges to the state declared in Git.

Rollback in 30 Seconds

One of the most concrete advantages of GitOps is instant rollback. The desired state is the Git commit — rolling back means selecting a previous revision in ArgoCD or running git revert in the repository. No complex kubectl commands, no configuration reconstruction.

In production, an ArgoCD rollback takes as long as reconciliation (typically 30-90 seconds). Compared to the manual process of identifying the previous image, editing the deployment, applying and verifying, the MTTR difference can be minutes to hours.

For database changes accompanying deployments, an ArgoCD rollback only reverts the application code. Database migrations require a backward compatibility strategy or separate rollback. GitOps doesn't replace a database migration strategy — it complements it.

Frequently Asked Questions

Is GitOps only for Kubernetes?
GitOps as an operational model applies to any infrastructure manageable as code. Terraform + Atlantis implements GitOps for cloud infrastructure. However, the most mature implementation with the most available tooling is the Kubernetes + ArgoCD or FluxCD combination.
ArgoCD or FluxCD for an enterprise?
ArgoCD has a richer UI and is easier to operate for teams that aren't Kubernetes-native. FluxCD is more lightweight and better integrated with the GitOps ecosystem (Flagger for canary deployments, image automation controllers). For most enterprises adopting GitOps for the first time, ArgoCD is the more pragmatic choice due to its gentler learning curve.
How do I handle feature flags and application configuration in GitOps?
Non-sensitive application configuration (timeouts, boolean feature flags, endpoints) should live in ConfigMaps in the infrastructure repository. Feature flags with complex logic should be in a dedicated system (LaunchDarkly, Unleash) that the application reads at runtime — not in the infrastructure repository. Configuration changes go through the same PR/review process as code.
What happens if someone does a manual kubectl edit in production?
With selfHeal: true in ArgoCD, the manual change will be automatically reverted in the next reconciliation cycle (every 3 minutes by default). ArgoCD will detect the drift and flag it in the UI. This behavior is exactly the point: GitOps makes manual changes non-persistent, forcing everything through the repository.
How long does it take to implement GitOps in a company using manual deploys?
In real projects, the first critical service running with ArgoCD (including secrets management and an updated CI pipeline) takes 2-3 weeks. Full ecosystem migration is a 2-4 month process depending on the number of services and integration complexity. The largest time investment is not technical — it's the cultural shift for the operations team.

Is your team transitioning from manual kubectl deploys to a professional GitOps workflow? We implement ArgoCD in production with the right practices from the start.

Talk to our team

Related articles

IQS

Engineering Team — IQS

Software, cloud, and DevOps engineers with enterprise project experience.