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:

  1. Optional initialization via spec.Init.Command
  2. Execution of spec.Generate.Command in the application directory
  3. Parsing stdout into individual YAML documents
  4. 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 test before 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 argocd binary through executable files named argocd-<command> discovered in $PATH, implemented in cmd/argocd/commands/plugin.go
  • Config-Management Plugins run as gRPC services in cmpserver/plugin/plugin.go, handling manifest generation via GenerateManifest, repository discovery via MatchRepository, and dynamic parameters via GetParametersAnnouncement
  • CMP configurations use plugin.yaml files processed by cmpserver/plugin/config.go to define generation commands, init steps, and discovery rules
  • Both mechanisms support comprehensive testing through unit tests in cmpserver/plugin/plugin_test.go and 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:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →