Skip to content
GitHub stars

Argo CD Integration Guide

Map each LynqNode to an Argo CD Application. Lynq renders the Application manifests from database rows; Argo CD handles GitOps sync and progressive delivery.

Overview

Lynq can render Argo CD Application manifests for every active node row. Each LynqNode becomes the canonical source of truth for a corresponding Argo CD Application, enabling GitOps workflows, progressive delivery, and automated cleanup.

Core Benefits

  • 1:1 Mapping – Every LynqNode owns exactly one Argo CD Application (LynqNode ↔️ Application).
  • Automatic Sync – Application source paths follow node metadata (UID, plan, region).
  • Declarative Cleanup – When a LynqNode is deleted (or deactivated), the Argo CD Application and downstream workloads are removed.
  • GitOps Alignment – Teams keep delivery pipelines in Git, while Lynq handles orchestration and lifecycle.

Prerequisites

  • Argo CD installed (v2.8+ recommended) and accessible from the node namespace.
  • ServiceAccount and RBAC granting Lynq permission to create Argo CD Application objects in the Argo CD namespace (often argocd).
  • Lynq chart deployed with namespace permissions covering the Argo CD API group.
  • Git repository that hosts node application configuration.

Baseline Template (1 LynqNode ➝ 1 Application)

The following template renders an Argo CD Application per LynqNode. Each Application points to a unique Git path derived from node metadata.

yaml
apiVersion: operator.lynq.sh/v1
kind: LynqForm
metadata:
  name: argocd-app-template
spec:
  hubId: saas-registry

  manifests:
    - id: argocd-app
      nameTemplate: "{{ printf \"%s-app\" (.uid | trunc63) }}"
      spec:
        apiVersion: argoproj.io/v1alpha1
        kind: Application
        metadata:
          namespace: argocd
          labels:
            lynq.sh/uid: "{{ .uid }}"
            lynq.sh/region: "{{ .region | default \"global\" }}"
        spec:
          project: nodes
          source:
            repoURL: https://github.com/your-org/node-configs.git
            targetRevision: main
            path: "nodes/{{ .uid }}"
          destination:
            server: https://kubernetes.default.svc
            namespace: "{{ .uid }}-workspace"
          syncPolicy:
            automated:
              prune: true
              selfHeal: true
            syncOptions:
              - CreateNamespace=true
              - ApplyOutOfSyncOnly=true

Flow

Advanced Sync Patterns

PatternDescriptionLynqForm Template Hints
Environment BranchingTarget different Git branches per region or plan (targetRevision: "{{ ternary \"main\" \"staging\" (eq .planId \"enterprise\") }}").Use extra value mappings for planId, region.
Dynamic PathsCompose repo paths from UID segments (path: "nodes/{{ .region }}/{{ .uid }}").Use Sprig splitList, join, default.
App-of-AppsPoint each node to an Application that references node-specific sub-apps.Render Application with path: nodes/{{ .uid }}/apps.
Multi-Cluster DeliveryRoute nodes to dedicated clusters using Argo CD credentials (destination.server).Map datasource columns to clusterServer, clusterName.
Progressive RolloutsAnnotate Applications for Argo Rollouts or Progressive Sync plugins.Add metadata.annotations via templates.

Additional Use Cases

1. AppSet Fan-Out per Node Plan

  • Combine Lynq with Argo CD ApplicationSet.
  • Lynq renders a control-plane Application that references an ApplicationSet generator.
  • Generator reads node metadata (via ConfigMap/Secret) to produce feature-specific Applications per plan tier.

2. Multi-Cluster Nodes with Cluster Secrets

  • Add extraValueMappings for cluster credentials.
  • LynqForm template creates:
    1. An Argo CD ClusterSecret (with kubeconfig) in the Argo CD namespace.
    2. An Application targeting that cluster secret.
  • Enables dedicated clusters per enterprise node.

3. Canary and Blue/Green Releases

  • Render two Applications per node (node-app-canary, node-app-stable) with different targetRevision.
  • Use creationPolicy: Once on the stable Application and WhenNeeded on the canary for rapid rollback.
  • Combine with Argo Rollouts by templating analysis and promotion hooks.

Verification Commands

After deploying, verify the integration works correctly:

bash
# 1. Check LynqNodes created Argo CD Applications
kubectl get applications -n argocd -l lynq.sh/uid

# Example output:
# NAME              SYNC STATUS   HEALTH STATUS   AGE
# acme-corp-app     Synced        Healthy         5m
# beta-inc-app      Synced        Healthy         5m

# 2. Verify Application points to correct Git path
kubectl get application acme-corp-app -n argocd -o jsonpath='{.spec.source.path}'
# Expected: nodes/acme-corp

# 3. Check sync status
kubectl get application acme-corp-app -n argocd -o jsonpath='{.status.sync.status}'
# Expected: Synced

# 4. Check health status
kubectl get application acme-corp-app -n argocd -o jsonpath='{.status.health.status}'
# Expected: Healthy

# 5. View sync history
argocd app history acme-corp-app

# 6. Force sync (if needed)
argocd app sync acme-corp-app

# 7. Check downstream workloads
kubectl get all -n acme-corp-workspace

# 8. View Application events
kubectl describe application acme-corp-app -n argocd | tail -20

Monitor Both Systems:

bash
# Combined health check
echo "=== LynqNode Status ===" && \
kubectl get lynqnode acme-corp-web-app -o jsonpath='{.status.conditions[?(@.type=="Ready")].status}' && \
echo "" && \
echo "=== Argo CD Application Status ===" && \
kubectl get application acme-corp-app -n argocd -o jsonpath='{.status.sync.status}/{.status.health.status}'

# Expected: True (LynqNode Ready) + Synced/Healthy (Argo CD)

Troubleshooting

Application not created after LynqNode is Ready

The operator may lack permission to create Application objects in the argocd namespace.

bash
# Check operator RBAC
kubectl auth can-i create applications.argoproj.io -n argocd \
  --as=system:serviceaccount:lynq-system:lynq-controller-manager
# Should return: yes

# Check for apply errors in operator logs
kubectl logs -n lynq-system deployment/lynq-controller-manager | grep "argocd"

Application created but not syncing

bash
# Check Argo CD project allows the destination namespace
kubectl get appproject nodes -n argocd -o jsonpath='{.spec.destinations}'

# Check source repo is accessible
argocd repo list

Application deleted but workloads remain

Argo CD's prune: true only removes resources it manages in Git. Resources created outside the Git path persist. Use argocd app sync --prune to force cleanup.

LynqNode Ready but Application Degraded

Lynq only manages the Application object lifecycle. Argo CD sync failures (wrong Git path, missing manifests) are outside Lynq's scope — check argocd app get <name> for details.

Caveats

  • RBAC is cross-namespace: The Argo CD Application CR lives in the argocd namespace, not the LynqNode namespace. The operator ClusterRole must include argoproj.io API group with verbs create, update, patch, delete, get, list, watch.
  • Deletion cascade: When a LynqNode is deleted, Lynq deletes the Application CR. Argo CD then prunes the downstream workloads (only if prune: true). Use deletionPolicy: Retain on the argocd-app manifest entry to keep the Application for post-mortem inspection.
  • Application name length: Argo CD Application names must be ≤ 63 characters. Always use trunc63 in nameTemplate.
  • Cross-namespace tracking: Because the Application lives in argocd (not the LynqNode namespace), Lynq uses label-based tracking (lynq.sh/node, lynq.sh/node-namespace) rather than ownerReferences.

See Also

  • Templates – Advanced templating and function usage.
  • Policies – Control resource lifecycle (Retain vs. Delete).
  • Monitoring – Capture Argo CD and Lynq metrics together.