← Recipes

阅读中文版本

Block Argo CD Syncs During a Release Freeze

Use sync windows to deny automatic syncs during a freeze while still allowing audited manual syncs for real emergencies.

~30 minargocdgitopsrelease

Task

Prevent Argo CD from rolling out changes during a freeze window without locking engineers out of a genuine incident.

When to use this

A marketing launch runs on Saturday and an unrelated merge to main auto-syncs at 09:00, restarting the API pods during peak traffic.

Prerequisites

  • Argo CD 2.9 or newer
  • An AppProject that owns the affected Applications
  • argocd CLI logged in to the instance

Steps

1. Add a deny window for the freeze and an allow window for normal working days.

apiVersion: argoproj.io/v1alpha1
kind: AppProject
metadata:
  name: payments
  namespace: argocd
spec:
  syncWindows:
    - kind: deny
      schedule: "0 0 * * 6"
      duration: 48h
      timeZone: Europe/London
      applications:
        - "*"
      manualSync: true
    - kind: allow
      schedule: "0 0 * * 1-5"
      duration: 120h
      timeZone: Europe/London
      applications:
        - "*"

Expected output: Automatic sync is denied from Saturday 00:00 for 48 hours, while manual sync stays available.

2. Confirm the project windows are what the controller will evaluate.

argocd proj windows list payments

Expected output: Both windows appear with the correct schedule, duration, time zone, and manual sync flag.

3. Verify that an out-of-sync application is not synced inside the deny window.

argocd app get payments-api -o json | jq -r '.status.sync.status, .status.operationState.phase'

Expected output: Sync status is OutOfSync while the operation phase stays empty during the freeze.

4. Perform an emergency sync explicitly and confirm it is attributed to a user.

argocd app sync payments-api --server-side --prune --timeout 300

Expected output: The sync runs despite the deny window and appears in the app history with the initiating account.

Troubleshooting

Problem

The application syncs anyway during the freeze

Solution

Sync windows belong to the AppProject that owns the application; check that the app is not still in the default project.

Problem

The window never matches the intended time

Solution

The controller evaluates the window time zone, which is UTC by default; set timeZone explicitly and confirm the controller clock.

Limitations

  • Sync windows do not stop direct kubectl changes; pair them with admission policy for a real freeze.
  • A deny window with manualSync disabled can block a genuine emergency; keep manual sync enabled and audited.

Freeze automation without freezing people

A release freeze is usually a calendar instruction, and calendar instructions are ignored by automation. Argo CD sync windows move the freeze into the reconciliation loop: inside a deny window the controller stops automatic syncing, so a merge to main cannot restart production pods during a launch. The important detail is manualSync: true. A freeze that also blocks manual sync turns a minor incident into an outage because nobody can apply the fix.

Shape the windows

Windows are evaluated in the order they appear, and the most specific match wins. Keep a deny window for the freeze period and an allow window for normal hours so an expired deny window does not leave the project in an undefined state. Set timeZone explicitly, because the controller defaults to UTC and a Saturday freeze written in local time will start eight hours early or late depending on the season.

syncWindows:
  - kind: deny
    schedule: "0 0 * * 6"
    duration: 48h
    timeZone: Europe/London
    applications: ["*"]
    manualSync: true

Verify and audit the boundary

Check the effective windows with argocd proj windows list rather than trusting the manifest, and confirm an out-of-sync application stays unsynced while the window is active. When an emergency override happens, the app history records the initiating account and the diff, which is exactly what a post-incident review needs. Announce the freeze in the same channel where the override procedure is documented, so nobody has to guess whether manual sync is allowed.