Plugins no ArgoCD: estendendo o Config Management Plugin
Objetivo
Explicar como o Config Management Plugin (CMP) do ArgoCD funciona, quando ele resolve um problema real de renderização de manifestos e como estruturar um plugin próprio sem comprometer a segurança do cluster. O foco é dar critérios para decidir se vale a pena sair do caminho padrão (Helm/Kustomize nativos) e entrar em um CMP customizado.
Premissas e escopo
Antes de seguir, duas limitações precisam ficar explícitas:
- Este post foi gerado a partir de um resumo de pesquisa vazio -- não havia fontes verificadas fornecidas para embasar o conteúdo. O que segue é conhecimento técnico geral sobre o modelo de plugins do ArgoCD (CMP v2, baseado em sidecar), não um relato de implementação testada neste pipeline.
- Nenhum comando ou manifesto abaixo foi executado neste ambiente. Trate os exemplos como ponto de partida e valide em um cluster de teste antes de levar para produção.
Assumo ArgoCD em uma versão que suporta CMP v2 (modelo de sidecar, disponível desde a série 2.x). Se você está em uma instalação mais antiga ou gerenciada (ex: algum SaaS que abstrai o argocd-repo-server), confirme na documentação oficial antes de replicar: https://argo-cd.readthedocs.io/en/stable/user-guide/config-management-plugins/
O que é o Config Management Plugin e quando ele entra em cena
O ArgoCD, por padrão, sabe renderizar Helm, Kustomize, Jsonnet e manifestos puros. O problema aparece quando sua organização usa uma ferramenta própria de templating, um pós-processador (ex: injetar labels de compliance, assinar manifestos, rodar um linter obrigatório antes do kubectl apply lógico) ou uma combinação de ferramentas que o ArgoCD não entende nativamente.
O CMP existe para esse gap: ele permite registrar um comando arbitrário que recebe o conteúdo de um diretório do Git e devolve YAML válido para o argocd-repo-server aplicar. Na prática, é um hook de generate (e opcionalmente discover) plugado no processo de renderização.
Cenários em que isso faz sentido:
- Pipeline interno que combina Helm + Kustomize + um script de normalização (ex: aplicar
securityContextpadrão em todos os workloads). - Templates escritos em ferramenta não suportada nativamente (CUE, Jsonnet com wrappers próprios, geradores em Python).
- Necessidade de validação obrigatória (policy-as-code) antes da renderização final chegar ao cluster.
Quando não faz sentido: se o problema é só "quero rodar helm template com alguns flags extras", os parâmetros nativos do Application para Helm já resolvem, sem o custo operacional de manter um sidecar.
Anatomia do CMP v2
No modelo atual, o plugin roda como um container sidecar dentro do pod do argocd-repo-server, comunicando-se com o processo principal via socket Unix. Isso é relevante porque muda o raciocínio de segurança: o plugin não é um binário isolado, ele compartilha o mesmo pod (e, por padrão, pode compartilhar filesystem via volume) que renderiza manifestos de todas as aplicações do cluster.
A configuração do plugin vive em um arquivo plugin.yaml dentro do próprio container sidecar, com três blocos principais:
apiVersion: argoproj.io/v1alpha1
kind: ConfigManagementPlugin
metadata:
name: meu-plugin-custom
spec:
version: v1.0
init:
command: ["sh", "-c"]
args: ["echo 'inicializando plugin'"]
generate:
command: ["sh", "-c"]
args: ["python3 /plugins/meu-plugin/render.py ."]
discover:
find:
glob: "**/plugin-marker.yaml"
init: roda uma vez antes da renderização, útil para instalar dependências ou preparar cache.generate: é o comando obrigatório -- recebe o diretório da aplicação e precisa imprimir YAML válido nostdout.discover: define como o ArgoCD decide automaticamente que umaApplicationdeve usar esse plugin (por arquivo marcador, padrão de glob ou comando customizado).
Registrando o plugin no argocd-repo-server
O sidecar precisa ser adicionado ao Deployment do argocd-repo-server via patch ou Helm values (se você usa o chart oficial). A ideia central:
repoServer:
extraContainers:
- name: meu-plugin-custom
image: registry.interno/meu-plugin:1.0
command: ["/var/run/argocd/argocd-cmp-server"]
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: meu-plugin-custom-config
securityContext:
runAsNonRoot: true
O ponto crítico aqui é que o binário argocd-cmp-server precisa estar presente na imagem do plugin -- ele é o processo que conversa com o repo-server via socket. Sem ele, o sidecar não se registra.
Usando o plugin em uma Application
Depois de registrado, a Application referencia o plugin pelo nome configurado:
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: app-com-plugin
namespace: argocd
spec:
source:
repoURL: https://git.interno/time/app-config.git
path: overlays/prod
plugin:
name: meu-plugin-custom
destination:
server: https://kubernetes.default.svc
namespace: prod
project: default
Se você configurou discover, pode omitir o bloco plugin inteiro e deixar o ArgoCD decidir automaticamente -- mas isso exige disciplina: dois plugins com critérios de discovery que se sobrepõem geram comportamento ambíguo e difícil de depurar.
Validação
Como não houve execução neste ambiente, trate os passos abaixo como roteiro de verificação, não como resultado confirmado:
- Antes de subir o plugin para o cluster, teste o comando de
generateisoladamente, fora do ArgoCD, apontando para um diretório real de manifestos. Se o script não produz YAML válido localmente, não vai produzir dentro do sidecar. - Use
argocd app diff <nome>para comparar o output do plugin com o estado atual do cluster antes de sincronizar. - Verifique os logs do sidecar (
kubectl logs <pod-repo-server> -c meu-plugin-custom) quando a renderização falhar -- a mensagem de erro do ArgoCD na UI costuma ser genérica. - Rode a sincronização primeiro em modo
--dry-runou em umApplicationde staging antes de aplicar em produção.
Limitações e cuidados de segurança
- Superfície de ataque maior: o plugin roda com acesso ao mesmo pod que processa o Git de todas as aplicações do cluster. Um script malicioso ou comprometido no repositório pode, em tese, interagir com esse processo. Trate o código do plugin com o mesmo rigor de revisão que daria a um controller.
- Sem isolamento de rede por padrão: se o plugin precisa chamar serviços externos (ex: um serviço de assinatura de manifestos), avalie
NetworkPolicypara limitar o alcance do sidecar. - Acoplamento operacional: cada atualização do plugin exige rebuild de imagem e rollout do
argocd-repo-server. Isso adiciona uma dependência de release que times menores subestimam. - Debug mais difícil: erros de template ficam "escondidos" dentro de um processo customizado, exigindo logging explícito no próprio script -- o ArgoCD não tem visibilidade sobre a lógica interna do plugin.
Quando considerar alternativas
Antes de adotar um CMP, vale medir o problema contra opções mais simples:
- Kustomize plugins (exec ou Go plugin), se a necessidade é só transformação de YAML dentro do próprio Kustomize.
- Helm post-renderer, se o pós-processamento é compatível com o modelo de pipe do Helm.
- ApplicationSet generators, se o problema é gerar múltiplas
Applicationsa partir de uma fonte (Git, lista, cluster), não transformar o conteúdo de uma aplicação.
O CMP custa mais para manter porque introduz um processo customizado no caminho crítico de sync. Reserve-o para casos em que nenhuma dessas alternativas cobre a necessidade.
Próximo passo
Se você está avaliando um CMP, comece construindo o script de generate fora do ArgoCD, validando o output como YAML puro contra um cluster de teste, antes de empacotar como sidecar. Isso isola o problema de template do problema de integração com o argocd-repo-server e reduz o tempo de troubleshooting quando algo falhar em produção.