Overview
Argo CD natively supports Helm, Jsonnet, and Kustomize. For other config management tools or unsupported features, you can create Config Management Plugins (CMPs).
The repo server delegates manifest building to plugins when configured correctly.
Security Considerations Plugins are granted trust in the Argo CD system. Administrators should:
Only install plugins from trusted sources
Audit plugins for security risks
Implement plugins securely with proper input sanitization
Plugin Installation
Sidecar Architecture
Plugins run as sidecars to the repo-server, providing isolation and flexibility.
Write Plugin Configuration
Create a ConfigManagementPlugin manifest: apiVersion : argoproj.io/v1alpha1
kind : ConfigManagementPlugin
metadata :
name : my-plugin
spec :
version : v1.0
init :
command : [ sh ]
args : [ -c , 'echo "Initializing..."' ]
generate :
command : [ sh , -c ]
args :
- |
echo '{"kind": "ConfigMap", "apiVersion": "v1",
"metadata": {"name": "$ARGOCD_APP_NAME",
"namespace": "$ARGOCD_APP_NAMESPACE"}}'
discover :
fileName : "./subdir/s*.yaml"
While this looks like a Kubernetes object, it’s not a custom resource—it just follows Kubernetes-style conventions.
Place Configuration in Sidecar
The plugin config must be at /home/argocd/cmp-server/config/plugin.yaml. Option 1: Bake into Image WORKDIR /home/argocd/cmp-server/config/
COPY plugin.yaml ./
Option 2: Mount from ConfigMap apiVersion : v1
kind : ConfigMap
metadata :
name : my-plugin-config
data :
plugin.yaml : |
apiVersion: argoproj.io/v1alpha1
kind: ConfigManagementPlugin
metadata:
name: my-plugin
spec:
version: v1.0
generate:
command: [sh, -c, 'echo "..."']
Register Plugin Sidecar
Patch argocd-repo-server deployment: containers :
- name : my-plugin
command : [ /var/run/argocd/argocd-cmp-server ]
image : ubuntu
securityContext :
runAsNonRoot : true
runAsUser : 999
volumeMounts :
- mountPath : /var/run/argocd
name : var-files
- mountPath : /home/argocd/cmp-server/plugins
name : plugins
- mountPath : /home/argocd/cmp-server/config/plugin.yaml
subPath : plugin.yaml
name : my-plugin-config
- mountPath : /tmp
name : cmp-tmp
volumes :
- configMap :
name : my-plugin-config
name : my-plugin-config
- emptyDir : {}
name : cmp-tmp
Critical Requirements:
Use /var/run/argocd/argocd-cmp-server as entrypoint
Run as user 999
Config file at /home/argocd/cmp-server/config/plugin.yaml
Use separate /tmp volume (not shared with repo-server)
Plugin Configuration
Discovery Rules
Plugins use discovery rules to match Applications:
fileName (glob)
find.glob (nested)
find.command
discover :
fileName : "./subdir/s*.yaml"
Uses filepath.Glob pattern matching. discover :
find :
glob : "**/Chart.yaml"
Supports double-star for nested directories. discover :
find :
command : [ sh , -c , 'find . -name env.yaml' ]
Must exit with status 0 and produce non-empty stdout.
If discovery config is omitted, the plugin won’t match any Application automatically but can still be invoked explicitly by name.
Generate Command
The generate command must print valid Kubernetes YAML or JSON to stdout:
generate :
command : [ sh , -c ]
args :
- |
# Generate Kubernetes manifests
kustomize build . | \
sed "s/\${ENV}/$ARGOCD_ENV_ENV/g"
Debugging Tips:
Write log messages to stderr (always displayed)
Avoid printing sensitive information to stderr (visible in UI)
Exit with non-zero code on errors
Init Command
Runs before generate, useful for setup:
init :
command : [ sh ]
args :
- -c
- |
helm dependency update
npm install
Parameters
Define UI parameters for your plugin:
parameters :
static :
- name : string-param
title : Description of the string param
tooltip : Tooltip shown on hover
required : false
itemType : "string"
collectionType : "string"
string : default-string-value
- name : array-param
array : [ default , items ]
collectionType : array
- name : map-param
map :
some : value
collectionType : map
dynamic :
command : [ echo , '[{"name": "example-param", "string": "default"}]' ]
Environment Variables
Plugin commands have access to:
System Environment Variables
Variables from the sidecar container environment.
ARGOCD_APP_NAME - Application name
ARGOCD_APP_NAMESPACE - Application namespace
ARGOCD_APP_REVISION - Git revision
ARGOCD_APP_SOURCE_REPO_URL - Repository URL
ARGOCD_APP_SOURCE_PATH - Path in repository
KUBE_VERSION - Target Kubernetes version
KUBE_API_VERSIONS - Available API versions
Application Environment Variables
User-supplied variables (prefixed with ARGOCD_ENV_): apiVersion : argoproj.io/v1alpha1
kind : Application
spec :
source :
plugin :
env :
- name : FOO
value : bar
Available as $ARGOCD_ENV_FOO
Available as JSON in ARGOCD_APP_PARAMETERS and as individual env vars: parameters :
- name : values-files
array : [ values-dev.yaml ]
- name : image-tag
string : v1.2.3
Results in:
PARAM_VALUES_FILES_0=values-dev.yaml
PARAM_IMAGE_TAG=v1.2.3
Sanitize User Input Always escape user input to prevent malicious input from causing unwanted behavior.
Using Plugins in Applications
Auto-Discovery
apiVersion : argoproj.io/v1alpha1
kind : Application
metadata :
name : guestbook
spec :
project : default
source :
repoURL : https://github.com/argoproj/argocd-example-apps.git
targetRevision : HEAD
path : guestbook
plugin : {} # Auto-discover based on discovery rules
Explicit Plugin Name
source :
plugin :
name : my-plugin-v1.0 # Format: <name>-<version> or just <name>
env :
- name : FOO
value : bar
parameters :
- name : values-files
array : [ values-dev.yaml ]
Advanced Configuration
Preserve File Mode
Only enable if you trust the plugin—executable permissions could be a security risk.
spec :
preserveFileMode : true
Provide Git Credentials
Enable only for trusted plugins—credentials used to clone the source repo will be shared.
spec :
provideGitCreds : true
Credentials are provided via Git’s ASKPASS method through a socket shared between containers.
Timeout Configuration
CMP commands respect timeouts:
server.repo.server.timeout.seconds in argocd-cmd-params-cm (default: 60s)
ARGOCD_EXEC_TIMEOUT on CMP sidecar (default: 90s)
ARGOCD_EXEC_FATAL_TIMEOUT for forceful termination
If your plugin takes longer than 60s, increase both timeouts: # In argocd-cmd-params-cm
server.repo.server.timeout.seconds : "180"
# In CMP sidecar
env :
- name : ARGOCD_EXEC_TIMEOUT
value : "180"
Debugging
Enable Debug Logging
Set --loglevel=info on the sidecar to see stderr output: command : [ /var/run/argocd/argocd-cmp-server , --loglevel=info ]
Check Sidecar Status
kubectl get pod -l app.kubernetes.io/component=repo-server -n argocd
Should show 2/2 containers running.
View Logs
kubectl logs -n argocd deployment/argocd-repo-server -c my-plugin
Hard Refresh
CMP errors are cached in Redis. Always do a “Hard Refresh” in the UI when testing.
Error Cause no matches for kind "ConfigManagementPlugin"Trying to create CMP as a CRD (removed in v2.8). Use sidecar method instead. plugin not foundPlugin name mismatch or discovery rules don’t match timeout exceededCommand takes too long—increase timeout settings
Example Plugins
Check out the example plugins repository for:
Helm with custom value injection
Kustomize with additional transformations
Custom templating engines
Multi-tool pipelines
Migration from argocd-cm
Configuring plugins in argocd-cm ConfigMap was deprecated in v2.4 and removed in v2.8.
Convert ConfigMap Entry
Transform your plugin config to the new format (see examples above).
Add Discovery Rules
Add discovery rules or update Application manifests with explicit plugin names.
Verify Tool Access
Ensure your sidecar image includes all tools your plugin needs.
Test and Deploy
Test with a few Applications before migrating all of them.
Next Steps
Custom Health Checks Add health checks for custom resources
Resource Actions Define custom actions for resources
UI Extensions Extend the web interface
Example Plugins View plugin examples