The DatadogPodAutoscaler (DPA) is a Kubernetes custom resource definition (CRD) that enables autoscaling of Kubernetes workloads using Datadog Kubernetes Autoscaling (DKA). This guide demonstrates how to manage DatadogPodAutoscaler resources using ArgoCD and GitOps principles to deploy an autoscaling configuration.
ArgoCD is a declarative, GitOps continuous delivery tool for Kubernetes. It monitors Git repositories containing Kubernetes manifests and keeps your cluster synchronized with the desired state defined in Git. This approach provides version control, audit trails, and automated deployment of your autoscaling infrastructure.
Activating autoscaling at scale: To roll out autoscaling across many workloads or namespaces with a shared policy, label the workloads or namespaces with autoscaling.datadoghq.com/profile instead of authoring one DatadogPodAutoscaler per workload. See Cluster profiles in the Kubernetes Autoscaling overview.
Prerequisites
Before you begin, ensure you have the following:
Kubernetes cluster: A working Kubernetes cluster (1.20 or later) with access using kubectl
ArgoCD installed: ArgoCD deployed in your cluster and accessible via CLI or UI
Datadog API credentials: Valid Datadog API key and application key
Git repository: A Git repository to store your manifests
Project structure
This guide uses the App of Apps pattern with ArgoCD sync waves to ensure proper dependency creation and deployment order.
.├──argocd/│├──root-app.yaml# App of Apps controller│└──apps/│├──datadog-operator.yaml# ArgoCD Application for Operator│├──datadog-agent.yaml# ArgoCD Application for Agent│└──nginx-dka-demo.yaml# ArgoCD Application for workload├──manifests/│└──stage2-agent/│└──datadog-agent.yaml# DatadogAgent custom resource└──charts/└──nginx-dka-demo/├──Chart.yaml├──values.yaml└──templates/├──deployment.yaml└──pod-autoscaler.yaml
Deployment stages
A multi-stage deployment approach is essential when working with Kubernetes custom resource definitions (CRDs) and ArgoCD. This ordered approach is necessary to ensure that you create and install the dependencies required for each stage in the process.
Kubernetes CRDs must be installed in the cluster before you can create custom resources that use them. The DatadogPodAutoscaler CRD is created when you install the Datadog Operator in Stage 1. ArgoCD needs these CRDs to be present before it can successfully sync resources that depend on them.
ArgoCD uses sync waves to control the deployment order through annotations. Sync waves are executed in ascending order (lower numbers first), and ArgoCD waits for all resources in a wave to be healthy before proceeding to the next wave.
Stage 1 (Wave 0): Datadog Operator using Helm (creates CRDs)
DatadogAgent custom resource with Autoscaling requirements enabled
Stage 3 (Wave 2): Application workload with DatadogPodAutoscaler
NGINX deployment in demo namespace
DatadogPodAutoscaler resource for autoscaling the NGINX deployment
Set up configuration files
First, create a Git repository. You need to update all repoURL references in the ArgoCD Application manifests to point to your repository, as ArgoCD pulls manifests from Git.
Set up the following configuration files for each stage in the process.
Stage 1: Root Application (App of Apps)
The root Application is the App of Apps controller that manages all child Applications.
The ignoreDifferences entry pairs with RespectIgnoreDifferences=true to instruct ArgoCD not to revert changes the Datadog Cluster Agent applies to the autoscaled workload. The managedFieldsManagers form leverages Kubernetes server-side apply field ownership, so any field the Cluster Agent owns (replicas, annotations under autoscaling.datadoghq.com/, container resources) is preserved automatically. See Allow the Datadog Cluster Agent to update autoscaled workloads for the full rationale and global-configuration alternative.
Create the Helm chart for the NGINX application:
charts/nginx-dka-demo/Chart.yaml
apiVersion:v2name:nginx-dka-demodescription:NGINX demo application with DatadogPodAutoscalertype:applicationversion:0.1.0appVersion:"1.0"
Allow the Datadog Cluster Agent to update autoscaled workloads
When applyPolicy.mode: Apply is set on a DatadogPodAutoscaler, the Datadog Cluster Agent mutates the target workload directly. It updates spec.replicas, container resources, and writes annotations under the autoscaling.datadoghq.com/ prefix to track its recommendations and applied state. Without additional ArgoCD configuration, ArgoCD interprets these mutations as drift and, with selfHeal: true enabled, reverts them on every sync. This causes a conflict between ArgoCD and the autoscaler.
Two options are available to prevent this conflict:
Per-application: Add ignoreDifferences and RespectIgnoreDifferences=true to each ArgoCD Application that contains an autoscaled workload. This is shown in Stage 4 above.
Global: Configure argocd-cm once so the ignoreDifferences rule applies to every Application in the instance.
Supported target workload kinds
The ignoreDifferences configuration must cover every workload kind that a DatadogPodAutoscaler can target through spec.targetRef:
Workload kind
API group
Note
Deployment
apps
StatefulSet
apps
Rollout
argoproj.io
Applies only if you also run Argo Rollouts
Per-application configuration
Choose one of the following variants depending on whether server-side apply is active in your cluster.
Variant 1: managedFieldsManagers (recommended)
The managedFieldsManagers approach covers every field the Cluster Agent owns (spec.replicas, container resources, and all annotations) without enumerating them individually.
This is the approach used in the Stage 4 example above. Only include the kind entries for the workload types present in each Application.
Variant 2: jqPathExpressions (works with client-side apply)
The jqPathExpressions approach explicitly targets only annotations beginning with autoscaling.datadoghq.com/, making it compatible with client-side apply. Use this variant if ServerSideApply=true is not available in your environment.
Limitation: this variant only covers autoscaling.datadoghq.com/ annotations. If the autoscaler also mutates spec.replicas or container resource requests, add separate jqPathExpressions entries for those fields. Variant 1 (managedFieldsManagers) avoids this gap by automatically covering all fields the Cluster Agent owns.
Global configuration
To apply ignoreDifferences once across all Applications in an ArgoCD instance, configure the argocd-cm ConfigMap using resource.customizations.ignoreDifferences.<group>_<kind> keys.
Important: RespectIgnoreDifferences is still required per-Application
Global ignoreDifferences configuration only suppresses diff display in the ArgoCD UI. It does not prevent ArgoCD from overwriting those fields during a sync. Each Application containing an autoscaled workload must also set RespectIgnoreDifferences=true in its syncOptions. There is no global equivalent for this sync option.
To avoid setting RespectIgnoreDifferences=true on each Application individually, define it at the AppProject level so all Applications in the project inherit it:
Many workloads or ArgoCD-wide standardization: use global configuration combined with a project-level or ApplicationSet-level RespectIgnoreDifferences=true.
Mixed environments (not all workloads are autoscaled): global configuration is safe to apply across the instance. The managedFieldsManagers rule is a no-op for workloads that have no Datadog Cluster Agent field ownership.
Deployment instructions
After you have set up the configuration files and pushed them to your Git repository, follow these steps to deploy the components using ArgoCD.
Create Datadog secret
Create a Kubernetes secret with your Datadog API and application keys in the datadog namespace:
You should see all applications appear and synchronize in wave order: datadog-operator (wave 0), then datadog-agent (wave 1), and nginx-dka-demo (wave 2).
Validate deployment
Verify that the Datadog Operator and CRDs are deployed:
kubectl get crd | grep datadoghq
kubectl get pods -n datadog
You should see the Datadog CRDs created and the datadog-operator pod running.
Verify that the Datadog Agent is deployed:
kubectl get datadogagent -n datadog
You should see the DatadogAgent custom resource created in the Running state. Also verify that the Datadog Agent and datadog-cluster-agent pods are running:
The secret must contain api-key and app-key fields.
DatadogPodAutoscaler events
Check DatadogPodAutoscaler events for scaling decisions and errors:
kubectl get events -n nginx-dka-demo --sort-by='.lastTimestamp'
Autoscaled workload keeps reverting
With selfHeal: true enabled, ArgoCD syncs approximately every 3 minutes. If spec.replicas or autoscaling.datadoghq.com/ annotations on the autoscaled workload are repeatedly reset, check for one of the following:
RespectIgnoreDifferences=true is absent from the Application’s syncOptions. Without this flag, ArgoCD only hides the drift in the UI but still overwrites the fields during apply.
The ignoreDifferences entry does not match the workload. Verify that group, kind, name, and namespace in the entry exactly match the target workload.
ServerSideApply=true is not set when using managedFieldsManagers. Without server-side apply, Kubernetes does not populate the field-ownership database, so the manager name cannot be matched.
To confirm whether server-side apply is active and which manager owns a given field, run:
kubectl get deployment <name> -n <namespace> -o yaml --show-managed-fields
Look for an entry where manager: datadog-cluster-agent and operation: Apply. If no such entry exists, server-side apply is not active for that resource.
Cluster Agent logs
Check Cluster Agent logs for autoscaling-related messages: