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
Applicationobjects in the Argo CD namespace (oftenargocd). - 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.
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=trueFlow
Advanced Sync Patterns
| Pattern | Description | LynqForm Template Hints |
|---|---|---|
| Environment Branching | Target different Git branches per region or plan (targetRevision: "{{ ternary \"main\" \"staging\" (eq .planId \"enterprise\") }}"). | Use extra value mappings for planId, region. |
| Dynamic Paths | Compose repo paths from UID segments (path: "nodes/{{ .region }}/{{ .uid }}"). | Use Sprig splitList, join, default. |
| App-of-Apps | Point each node to an Application that references node-specific sub-apps. | Render Application with path: nodes/{{ .uid }}/apps. |
| Multi-Cluster Delivery | Route nodes to dedicated clusters using Argo CD credentials (destination.server). | Map datasource columns to clusterServer, clusterName. |
| Progressive Rollouts | Annotate 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
extraValueMappingsfor cluster credentials. - LynqForm template creates:
- An Argo CD
ClusterSecret(with kubeconfig) in the Argo CD namespace. - An
Applicationtargeting that cluster secret.
- An Argo CD
- Enables dedicated clusters per enterprise node.
3. Canary and Blue/Green Releases
- Render two Applications per node (
node-app-canary,node-app-stable) with differenttargetRevision. - Use
creationPolicy: Onceon the stable Application andWhenNeededon the canary for rapid rollback. - Combine with Argo Rollouts by templating
analysisand promotion hooks.
Verification Commands
After deploying, verify the integration works correctly:
# 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 -20Monitor Both Systems:
# 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.
# 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
# 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 listApplication 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
ApplicationCR lives in theargocdnamespace, not the LynqNode namespace. The operator ClusterRole must includeargoproj.ioAPI group with verbscreate,update,patch,delete,get,list,watch. - Deletion cascade: When a LynqNode is deleted, Lynq deletes the
ApplicationCR. Argo CD then prunes the downstream workloads (only ifprune: true). UsedeletionPolicy: Retainon theargocd-appmanifest entry to keep the Application for post-mortem inspection. - Application name length: Argo CD Application names must be ≤ 63 characters. Always use
trunc63innameTemplate. - Cross-namespace tracking: Because the
Applicationlives inargocd(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.
