Argo CD Image Updater can automatically update your Kubernetes container images, but it doesn’t actually do the updating itself; it signals Argo CD to do it.

Here’s a look at how it works and how you can leverage it:

Let’s say you’ve got a simple deployment running in Kubernetes, managed by Argo CD. Your Deployment.yaml looks something like this:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-app
  namespace: default
spec:
  replicas: 1
  selector:
    matchLabels:
      app: my-app
  template:
    metadata:
      labels:
        app: my-app
    spec:
      containers:
      - name: my-app-container
        image: your-dockerhub-username/my-app:v1.0.0
        ports:
        - containerPort: 8080

And your Argo CD Application points to this manifest:

apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: my-app-app
  namespace: argocd
spec:
  project: default
  source:
    repoURL: https://github.com/your-username/your-repo.git
    targetRevision: HEAD
    path: k8s/
  destination:
    server: https://kubernetes.default.svc
    namespace: default
  syncPolicy:
    automated:
      prune: true
      selfHeal: true

Now, you push a new version of your container image, say your-dockerhub-username/my-app:v1.1.0, to your registry. You want Argo CD to pick this up and update your deployment. This is where Argo CD Image Updater comes in.

The Core Mechanism: Image Updates

Argo CD Image Updater is a separate component that runs alongside your Argo CD instance. It periodically scans your container registries for new image tags that match a defined policy. When it finds a new image, it doesn’t directly modify your Kubernetes manifests. Instead, it:

  1. Detects New Images: It queries your container registry (e.g., Docker Hub, Quay.io, GCR, ECR) for images used in your Argo CD managed applications.
  2. Applies Update Strategies: Based on your configuration, it determines which new image tag should be promoted. Common strategies include:
    • semver: Updates to the latest tag that matches a semantic versioning pattern (e.g., 1.x.x).
    • digest: Updates to the latest image digest, ensuring immutability.
    • latest: Updates to the tag literally named latest.
  3. Updates Argo CD Application: It then updates an annotation on your Argo CD Application resource. This annotation tells Argo CD that an image update is available and which image tag to use.
  4. Argo CD Syncs: Argo CD, seeing this annotation and its syncPolicy configured for automated syncs, will then apply the change. It modifies the Kubernetes manifest (e.g., the Deployment.yaml) to use the new image tag and performs the rollout.

Setting Up Argo CD Image Updater

To enable this, you’ll first need to install Argo CD Image Updater. This is typically done via Helm or by applying a manifest.

Once installed, you need to configure it to watch your applications and registries. This is usually done by annotating your Argo CD Application resource.

Let’s add annotations to our my-app-app to enable image updates:

apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: my-app-app
  namespace: argocd
  annotations:
    # Enable image updater for this application
    argocd-image-updater.argoproj.io/hermetic: "true" # Recommended: Ensures only explicitly defined images are updated.

    # Define the image to update
    argocd-image-updater.argoproj.io/my-app-container.image: your-dockerhub-username/my-app

    # Specify the update strategy (e.g., semantic versioning)
    argocd-image-updater.argoproj.io/my-app-container.update-strategy: semver

    # Define allowed semantic versioning ranges (e.g., only allow 1.x.x updates)
    argocd-image-updater.argoproj.io/my-app-container.semver-prerelease: "" # Ignore pre-release tags like -alpha, -beta
    argocd-image-updater.argoproj.io/my-app-container.allow-tags: "1.x.x" # Only allow tags matching 1.x.x

Explanation of Annotations:

  • argocd-image-updater.argoproj.io/hermetic: "true": This is a crucial setting. When true, the image updater will only consider images explicitly listed in the annotations for updating. If you have other images in your deployment (e.g., sidecars) that you don’t want updated, this prevents them from being accidentally targeted.
  • argocd-image-updater.argoproj.io/my-app-container.image: This tells the updater which image name to track in the registry.
  • argocd-image-updater.argoproj.io/my-app-container.update-strategy: Defines how to select the new image tag. semver is powerful for managing releases. Other options include digest (for immutable deployments) and latest.
  • argocd-image-updater.argoproj.io/my-app-container.semver-prerelease: Controls whether pre-release tags (like v1.2.0-beta.1) are considered. Setting it to "" means only stable releases are picked.
  • argocd-image-updater.argoproj.io/my-app-container.allow-tags: This is key for controlling which semantic versions are acceptable. 1.x.x would allow 1.0.0, 1.1.0, 1.2.5, etc., but not 2.0.0 or 0.9.0.

How it Integrates with Argo CD Sync Policies

For the actual deployment update to happen after the image updater signals Argo CD, your Argo CD Application needs an automated sync policy.

apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: my-app-app
  namespace: argocd
  # ... annotations from above ...
spec:
  project: default
  source:
    repoURL: https://github.com/your-username/your-repo.git
    targetRevision: HEAD
    path: k8s/
  destination:
    server: https://kubernetes.default.svc
    namespace: default
  syncPolicy:
    automated:
      prune: true
      selfHeal: true # This is important for automated syncs
    syncOptions:
      - CreateNamespace=true

With automated: { selfHeal: true }, Argo CD will automatically reconcile the desired state (defined in your Git repo) with the actual state in the cluster. When the image updater modifies the Application resource with the new image tag (via an annotation), Argo CD detects this drift and initiates a sync, which includes updating your deployment.

The "Secret Sauce": How the Manifest is Modified

When Argo CD Image Updater finds a new image, it doesn’t directly edit your Deployment.yaml in Git. Instead, it updates the Argo CD Application resource itself. It adds or modifies an annotation like this:

metadata:
  name: my-app-app
  namespace: argocd
  annotations:
    # ... other annotations ...
    argocd-image-updater.argoproj.io/write-back-file: "k8s/deployment.yaml" # Tells Argo CD where to find the image in the manifest
    argocd-image-updater.argoproj.io/my-app-container.new-tag: "v1.1.0" # The new tag to apply

The argocd-image-updater.argoproj.io/write-back-file annotation tells Argo CD which file in your Git repository contains the manifest that needs to be updated. The argocd-image-updater.argoproj.io/my-app-container.new-tag annotation is the actual signal for the new tag.

When Argo CD performs its sync, it reads these annotations, finds the specified file (k8s/deployment.yaml), locates the my-app-container image within it, and updates the image tag. It then commits this change back to your Git repository (if you’ve configured Git commit-back) or applies the updated manifest directly to the cluster.

This process ensures that your Git repository remains the source of truth, and the image updater acts as an intelligent agent that signals Argo CD when an update is due, rather than directly manipulating cluster state.

The next step you’ll likely encounter is managing multiple containers within a single deployment, or more complex update strategies like canary deployments.

Want structured learning?

Take the full Argocd course →