Argo CD GitOps skill for Codex

Promote by commit, roll back by revert. Codex structures GitOps repos so each environment is a directory, AppProjects restrict what teams can deploy, and ApplicationSets stamp out one Application per app and environment. It orders resources with sync waves and PreSync migration hooks, ignores only the fields controllers really own, and treats promotion as a commit and rollback as a revert, asking before any production sync or delete.

Install

curl -fsSL codexskills.dev/install.sh \  | sh -s -- argocd-gitops

Installs to ~/.agents/skills/argocd-gitops/ for every project on this machine.

104-line POSIX script. No sudo, no telemetry. Read install.sh

Use it in Codex

Start a prompt with $argocd-gitops, or pick it from /skills. You can also just describe the task: Codex reads the description below and loads the playbook when your request matches.

What Codex reads before loading it

Sets up and operates GitOps delivery with Argo CD - Application and AppProject manifests, automated sync with prune and self-heal, sync waves and PreSync/PostSync hooks, app-of-apps and ApplicationSet generators for many clusters and environments, ignoreDifferences for controller-managed fields, image promotion through Git, and safe rollbacks. Use when onboarding apps to Argo CD, structuring a GitOps repo, ordering resources during sync, debugging OutOfSync or Degraded apps, or rolling back a bad release.

Use it when

  • Apps are moving from CI-driven kubectl or helm deploys to GitOps
  • Many apps or clusters need consistent Argo CD Applications
  • Resources must be created in a specific order during sync
  • An Argo CD app is OutOfSync, Degraded or failing to sync

Use something else when

How to check the result

argocd app diff exits with no differences and argocd app wait reports Synced and Healthy for every generated Application after the change merges.

The mistake it prevents

Deleting an Application that carries the resources finalizer and unexpectedly removing every workload it managed in production.

~/.agents/skills/argocd-gitops/SKILL.md

--- name: argocd-gitops description: Sets up and operates GitOps delivery with Argo CD - Application and AppProject manifests, automated sync with prune and self-heal, sync waves and… license: MIT ---

Git is the only way changes reach the cluster: every environment is a directory or values file, promotion is a commit, rollback is a revert, and Argo CD shows Synced and Healthy for everything because live state matches Git, not because diffs are ignored wholesale.

Inspect first

  1. Read AGENTS.md, then map the GitOps repo: where Applications live, how environments are separated (directories, branches, values files), and what renders manifests (plain YAML, Kustomize, Helm).
  2. Check the Argo CD version (argocd version or the server image tag). Argo CD 3.x changed defaults from 2.x, including annotation-based resource tracking and stricter RBAC inheritance; read the upgrade notes before copying 2.x examples.
  3. List AppProjects and what they allow: argocd proj list, or the YAML in the repo.
  4. For a broken app: argocd app get <app> and argocd app diff <app> before changing anything.

The argocd CLI needs server access and login. Offline, edit and render manifests (kustomize build, helm template) and hand the cluster steps to the user.

Repo layout

Prefer directories per environment on one branch over branch-per-environment; branches drift and merges between them carry unintended changes.

gitops/
├── bootstrap/
│   └── root-app.yaml            # app-of-apps or ApplicationSet entry point
├── projects/
│   └── shop.yaml                # AppProject
├── apps/
│   └── orders/
│       ├── base/                # Kustomize base (or a Helm chart reference)
│       └── overlays/{dev,staging,production}/
└── appsets/
    └── shop-services.yaml       # ApplicationSet: one Application per app x env

AppProject: the guardrail

apiVersion: argoproj.io/v1alpha1
kind: AppProject
metadata:
  name: shop
  namespace: argocd
spec:
  sourceRepos:
    - https://github.com/example/gitops.git
  destinations:
    - { server: https://kubernetes.default.svc, namespace: "shop-*" }
  clusterResourceWhitelist: []        # no cluster-scoped objects from app teams
  namespaceResourceBlacklist:
    - { group: "", kind: ResourceQuota }

Never put team apps in the default project; it allows any repo and any destination.

Application

apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: orders-production
  namespace: argocd
  finalizers:
    - resources-finalizer.argocd.argoproj.io   # deleting the app deletes its resources
spec:
  project: shop
  source:
    repoURL: https://github.com/example/gitops.git
    targetRevision: main
    path: apps/orders/overlays/production
  destination:
    server: https://kubernetes.default.svc
    namespace: shop-prod
  syncPolicy:
    automated:
      prune: true
      selfHeal: true
    syncOptions:
      - CreateNamespace=true
      - ServerSideApply=true
      - PruneLast=true
    retry:
      limit: 5
      backoff: { duration: 10s, factor: 2, maxDuration: 3m }
  ignoreDifferences:
    - group: apps
      kind: Deployment
      jsonPointers: [/spec/replicas]          # owned by the HPA
  revisionHistoryLimit: 10

The resources finalizer makes deleting the Application cascade to every workload it manages. Deleting an Application is therefore a destructive production action: confirm with the user, and remove the finalizer first if the intent is only to stop managing it.

Many apps: ApplicationSet

apiVersion: argoproj.io/v1alpha1
kind: ApplicationSet
metadata:
  name: shop-services
  namespace: argocd
spec:
  goTemplate: true
  goTemplateOptions: ["missingkey=error"]
  generators:
    - matrix:
        generators:
          - git:
              repoURL: https://github.com/example/gitops.git
              revision: main
              directories:
                - path: apps/*
          - list:
              elements:
                - { env: staging, namespace: shop-staging }
                - { env: production, namespace: shop-prod }
  template:
    metadata:
      name: "{{.path.basename}}-{{.env}}"
    spec:
      project: shop
      source:
        repoURL: https://github.com/example/gitops.git
        targetRevision: main
        path: "{{.path.path}}/overlays/{{.env}}"
      destination:
        server: https://kubernetes.default.svc
        namespace: "{{.namespace}}"
      syncPolicy:
        automated: { prune: true, selfHeal: true }
PatternUse when
Single ApplicationOne app, one environment, hand-managed
App of appsA small, curated set; bootstrap of platform components in a fixed order
ApplicationSet (git directories, list, cluster, matrix)Many apps or clusters following one convention

ApplicationSets delete generated Applications when a generator stops producing them (for example a directory rename). Set spec.syncPolicy.preserveResourcesOnDeletion: true or use applicationsSync: create-update while restructuring.

Ordering: waves and hooks

metadata:
  annotations:
    argocd.argoproj.io/sync-wave: "-1"      # lower waves apply and become healthy first

Typical waves: -2 namespaces and CRDs, -1 config, secrets and migrations, 0 workloads, 1 ingress and post-deploy checks. Argo CD waits for each wave to be healthy before the next.

Database migration as a hook:

apiVersion: batch/v1
kind: Job
metadata:
  name: orders-migrate
  annotations:
    argocd.argoproj.io/hook: PreSync
    argocd.argoproj.io/hook-delete-policy: BeforeHookCreation
spec:
  backoffLimit: 1
  template:
    spec:
      restartPolicy: Never
      containers:
        - name: migrate
          image: registry.example.com/shop/orders:1.14.2
          command: ["./orders", "migrate", "up"]

Migrations must be backward compatible with the running version; a failed PreSync hook stops the sync, but schema changes already applied stay applied.

Promotion and rollback

  • Promotion = a commit changing the image tag in the next environment’s overlay or values (by CI, a PR bot, or Argo CD Image Updater writing back to Git).
  • Rollback = git revert of the promotion commit; Argo CD syncs the old state. This keeps Git truthful.
  • argocd app rollback <app> <history-id> works only with automated sync disabled and leaves Git out of sync with the cluster. Use it as an emergency step, with user confirmation, then revert in Git and re-enable auto-sync.
  • Production syncs, hard refreshes with prune, and rollbacks need the user’s explicit go-ahead.

Debugging states

StateCheckTypical cause
OutOfSync right after syncargocd app diffController or webhook mutates a field (replicas, caBundle, defaults); add a narrow ignoreDifferences plus RespectIgnoreDifferences=true
Sync failedargocd app get <app> operation messageSchema error, AppProject denies kind or namespace, hook failed
Progressing foreverResource health in UI, pod eventsPods not ready; debug the workload ($kubernetes-debugging)
DegradedHealth of child resourcesFailed Job, CrashLoopBackOff, PVC pending
Unknown / ComparisonErrorrepo-server logsRender error in Helm/Kustomize, private repo credentials, plugin failure
Manual kubectl change revertedselfHealWorking as designed; make the change in Git

Workflow

- [ ] 1. Map repo layout, Argo CD version, projects, existing apps
- [ ] 2. Render the target path locally (kustomize build / helm template)
- [ ] 3. Write AppProject, Application or ApplicationSet; scope the project tightly
- [ ] 4. Add sync waves and hooks only where order matters
- [ ] 5. Open a PR; after merge, watch the app sync (or argocd app sync with confirmation)
- [ ] 6. Confirm Synced + Healthy and a clean argocd app diff

Verification

kustomize build apps/orders/overlays/production | kubeconform -strict -summary -ignore-missing-schemas
argocd app get orders-production --refresh
argocd app diff orders-production            # exit code 0 means no diff
argocd app wait orders-production --health --sync --timeout 600
argocd appset get shop-services              # generated applications listed

Output

**Apps:** orders-staging, orders-production generated by ApplicationSet shop-services
**Project:** shop (repo and shop-* namespaces only, no cluster-scoped resources)
**Sync:** automated, prune + selfHeal, ServerSideApply; replicas ignored (HPA-owned)
**Order:** wave -1 migration Job (PreSync hook), wave 0 Deployment, wave 1 Ingress
**State:** Synced / Healthy in staging; production waits for the promotion PR
**Rollback:** git revert of the promotion commit (documented in README)

What the zip contains

SKILL.md plus the interface file below. Nothing runs on install.

agents/openai.yamlgenerated from this page

Gives the Codex app a display name, a one-line description and a starter prompt for this skill.

interface:
  display_name: "Argo CD GitOps"
  short_description: "Promote by commit, roll back by revert"
  default_prompt: "$argocd-gitops Onboard our three services to Argo CD with staging and production"

About this skill

Written and maintained by the Codex Skills editors to the same editorial standard as every skill here: a selective description, a real workflow, known pitfalls and a way to verify the work. First published , last updated . MIT licensed. Something wrong or out of date? Tell us.

esc
Just launched

Codex Skills Pro is live

79 premium skills for Codex, each with scripts, references and an evidence report that proves the result.

Bought one by one$882.21
All 79 skills$49
94% off

That's $0.62 a skill, paid once.

Get all 79 for $49Or pick single skills from $4.99 →

Secure checkout by Creem