Argo CD Plugin Development and Integration: CLI and Config-Management Plugin Guide
Argo CD supports two distinct extension mechanisms: CLI plugins that add subcommands via executables named argocd-<name>, and Config-Management Plugins (CMP) that run as gRPC services on the server to generate manifests and discover repositories.
The argoproj/argo-cd repository provides a flexible plugin architecture that enables you to customize both the command-line interface and the server-side manifest generation process. Whether you need to add custom subcommands to the argocd binary or support alternative configuration management tools beyond Helm and Kustomize, Argo CD plugin integration follows well-defined conventions backed by concrete protocol buffer definitions and service implementations.
Understanding Argo CD Plugin Architecture
Argo CD distinguishes between client-side extensions that enhance the CLI and server-side extensions that customize manifest generation.
CLI Plugins (Client-Side Extensions)
CLI plugins are standalone executables that extend the argocd command-line tool. When a user runs argocd foo, the CLI searches $PATH for an executable named argocd-foo and invokes it directly. According to the source in cmd/argocd/commands/plugin.go, the CLI does not parse global flags before passing arguments to the plugin; the binary receives all arguments after the subcommand unchanged.
This mechanism relies on a simple naming convention: any executable on the host's $PATH prefixed with argocd- automatically becomes available as a subcommand.
Config-Management Plugins (Server-Side Extensions)
Config-Management Plugins (CMP) are sophisticated server-side extensions defined by the ConfigManagementPlugin custom resource. These plugins run inside the Argo CD control plane and communicate via gRPC. The protobuf definition in cmpserver/plugin/plugin.proto specifies four primary RPCs: GenerateManifest, MatchRepository, GetParametersAnnouncement, and CheckPluginConfiguration.
The core service implementation lives in cmpserver/plugin/plugin.go, where the CMP server handles manifest generation, repository discovery, and dynamic parameter exposure.
Developing Config-Management Plugins
CMP development involves creating a plugin.yaml configuration and understanding the gRPC service lifecycle.
Plugin Configuration Structure
Each CMP requires a configuration file named plugin.yaml placed alongside the application source. The structure is defined by PluginConfig and PluginConfigSpec in cmpserver/plugin/config.go, which ReadPluginConfig parses at runtime.
A minimal configuration specifies:
- generate: The command that produces Kubernetes manifests
- discover: Rules determining which repositories the plugin can handle
- init: Optional setup commands run before generation
The CMP gRPC Service Implementation
The CMP server implements the ConfigManagementPluginService defined in cmpserver/plugin/plugin.proto. The service architecture in cmpserver/plugin/plugin.go processes requests through several key functions:
- getTempDirMustCleanup: Creates isolated working directories for safe execution
- runCommand: Executes the configured init and generate commands
- matchRepository (lines 324-368): Evaluates discovery rules against repository contents
When Argo CD needs manifests, it streams application files to the GenerateManifest RPC, which orchestrates the execution flow and splits output using kube.SplitYAMLToString.
Manifest Generation and Parameter Handling
The manifest generation flow follows a strict sequence:
- Optional initialization via
spec.Init.Command - Execution of
spec.Generate.Commandin the application directory - Parsing stdout into individual YAML documents
- Returning the manifest list to the Argo CD application controller
For dynamic UI integration, CMPs expose parameters through GetParametersAnnouncement. The plugin can define static parameters or execute a Dynamic command that outputs apiclient.ParameterAnnouncement messages, enabling custom input forms in the Argo CD UI.
Building CLI Plugins for Argo CD
Creating a CLI plugin requires no compilation or registration beyond placing an executable on the system path.
#!/usr/bin/env bash
# Save as argocd-hello on $PATH and make executable
if [[ "$1" == "world" ]]; then
echo "Hello from Argo CD plugin!"
else
echo "Usage: argocd hello world"
fi
After running chmod +x argocd-hello and ensuring the file is in $PATH, the command argocd hello world invokes the script. The discovery logic in cmd/argocd/commands/plugin.go uses exec.LookPath to locate the binary and os.Exec to run it with the provided arguments.
Practical Example: Helm Config-Management Plugin
Below is a complete CMP configuration that treats repositories containing Chart.yaml as Helm charts.
apiVersion: argoproj.io/v1alpha1
kind: ConfigManagementPlugin
metadata:
name: helm-cmp
spec:
version: v1
generate:
command: ["helm", "template", "."]
discover:
fileName: "Chart.yaml"
The server-side execution in cmpserver/plugin/plugin.go processes this configuration:
func (s *Service) generateManifest(ctx context.Context, appDir string, envEntries []*apiclient.EnvEntry) (*apiclient.ManifestResponse, error) {
// Run optional initialization
if len(s.initConstants.PluginConfig.Spec.Init.Command) > 0 {
if _, err := runCommand(ctx, s.initConstants.PluginConfig.Spec.Init, appDir, env); err != nil {
return nil, err
}
}
// Execute the generation command from plugin.yaml
out, err := runCommand(ctx, s.initConstants.PluginConfig.Spec.Generate, appDir, env)
if err != nil {
return nil, err
}
// Split combined output into individual manifests
manifests, err := kube.SplitYAMLToString([]byte(out))
if err != nil {
return nil, err
}
return &apiclient.ManifestResponse{Manifests: manifests}, nil
}
Register the plugin by applying the custom resource to your cluster: kubectl apply -f helm-plugin.yaml. Argo CD automatically routes matching applications to this CMP based on the discovery rules.
Testing and Validation
The argoproj/argo-cd repository includes comprehensive testing infrastructure for plugin development:
- Unit tests for CMP logic reside in
cmpserver/plugin/plugin_test.go, covering repository matching and command execution - Integration tests in
test/e2e/validate end-to-end plugin workflows using actual plugin configurations - Run
make testbefore submitting changes to ensure no regressions in the plugin subsystem
When testing locally, verify that your plugin.yaml syntax matches the PluginConfig struct in cmpserver/plugin/config.go to avoid runtime unmarshaling errors.
Summary
Argo CD plugin development provides two powerful extension paths:
- CLI plugins extend the
argocdbinary through executable files namedargocd-<command>discovered in$PATH, implemented incmd/argocd/commands/plugin.go - Config-Management Plugins run as gRPC services in
cmpserver/plugin/plugin.go, handling manifest generation viaGenerateManifest, repository discovery viaMatchRepository, and dynamic parameters viaGetParametersAnnouncement - CMP configurations use
plugin.yamlfiles processed bycmpserver/plugin/config.goto define generation commands, init steps, and discovery rules - Both mechanisms support comprehensive testing through unit tests in
cmpserver/plugin/plugin_test.goand end-to-end test suites
Frequently Asked Questions
What is the difference between CLI plugins and Config-Management Plugins?
CLI plugins are client-side executables that add new subcommands to the argocd CLI tool, running on the user's machine wherever the binary is installed. Config-Management Plugins are server-side gRPC services that run within the Argo CD control plane to generate Kubernetes manifests, discover repository types, and expose application parameters. CLI plugins handle user interactions, while CMPs handle manifest generation logic.
How does Argo CD discover which CMP to use for a repository?
Argo CD invokes the MatchRepository RPC defined in cmpserver/plugin/plugin.proto to determine plugin suitability. The evaluation logic in cmpserver/plugin/plugin.go (lines 324-368) checks the Discover section of your plugin.yaml, which can specify file names, glob patterns, or custom commands. If the discovery criteria match the repository contents, Argo CD selects that CMP for manifest generation.
Can CMPs run initialization commands before generating manifests?
Yes. The ConfigManagementPlugin spec supports an optional Init field that specifies commands to run before the Generate step. According to the implementation in cmpserver/plugin/plugin.go, the server executes init commands via runCommand within the same isolated working directory used for generation, allowing you to download dependencies or prepare templates before manifest creation.
Where should the plugin.yaml file be located for a CMP to work?
The plugin.yaml file must reside in the application source repository, typically at the root or alongside the application manifests. The CMP server reads this configuration via ReadPluginConfig in cmpserver/plugin/config.go when processing the repository. Additionally, you must register the plugin with Argo CD by creating a ConfigManagementPlugin custom resource that references the configuration.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →