Reference
ArgoCD Configuration¶
Complete technical reference for the ArgoCD Application manifest that deploys GitLab BDA.
ArgoCD Application Manifest¶
The ArgoCD Application CR (Custom Resource) that manages GitLab BDA deployment:
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: gitlab-bda
namespace: argocd
labels:
app.kubernetes.io/name: gitlab-bda
app.kubernetes.io/part-of: gitlab-platform
annotations:
argocd.argoproj.io/sync-wave: "0"
spec:
# Project: RBAC boundary for this application
project: default
# Source: Git repository containing manifests
source:
repoURL: https://git.bluedynamics.eu/kup6s/dp/dp-infra.git
targetRevision: main
path: gitlabbda/manifests
# Destination: Where to deploy resources
destination:
server: https://kubernetes.default.svc
namespace: gitlabbda
# Sync Policy: Automation and behavior
syncPolicy:
automated:
prune: true
selfHeal: true
syncOptions:
- CreateNamespace=true
- ApplyOutOfSyncOnly=true
# Ignore differences in certain fields
ignoreDifferences:
- group: apps
kind: Deployment
jsonPointers:
- /spec/replicas # Ignore HPA-managed replicas
# Info: Additional metadata displayed in UI
info:
- name: Environment
value: staging
- name: Documentation
value: https://git.bluedynamics.eu/kup6s/dp/dp-infra/-/tree/main/documentation
Field Reference¶
metadata¶
Field |
Type |
Required |
Description |
|---|---|---|---|
|
string |
✅ Yes |
Application name (shown in ArgoCD UI) |
|
string |
✅ Yes |
Must be |
|
map |
⚠️ Optional |
Labels for grouping/filtering applications |
|
map |
⚠️ Optional |
Annotations (rarely needed) |
Example:
metadata:
name: gitlab-bda
namespace: argocd
labels:
environment: staging
team: platform
spec.project¶
Field |
Type |
Required |
Description |
|---|---|---|---|
|
string |
✅ Yes |
AppProject name (RBAC boundary) |
Values:
default- Default project (no restrictions)Custom project name - Enforces allowed sources, destinations, resources
Example:
spec:
project: default # Most common
Custom project example:
# Create AppProject first
apiVersion: argoproj.io/v1alpha1
kind: AppProject
metadata:
name: gitlab-platform
namespace: argocd
spec:
sourceRepos:
- https://git.bluedynamics.eu/kup6s/dp/*
destinations:
- namespace: gitlabbda
server: https://kubernetes.default.svc
clusterResourceWhitelist:
- group: '*'
kind: '*'
# Then reference in Application
spec:
project: gitlab-platform
spec.source¶
Field |
Type |
Required |
Description |
|---|---|---|---|
|
string |
✅ Yes |
Git repository URL |
|
string |
✅ Yes |
Branch, tag, or commit SHA |
|
string |
✅ Yes |
Path within repo to manifests |
Example:
spec:
source:
repoURL: https://git.bluedynamics.eu/kup6s/dp/dp-infra.git
targetRevision: main # Or: v1.0.0, abc123
path: gitlabbda/manifests # Directory containing YAML files
Multiple sources (ArgoCD 2.6+):
spec:
sources:
- repoURL: https://git.bluedynamics.eu/kup6s/dp/dp-infra.git
targetRevision: main
path: gitlabbda/manifests
- repoURL: https://helm-repo.example.com
chart: gitlab
targetRevision: 18.5.1
spec.destination¶
Field |
Type |
Required |
Description |
|---|---|---|---|
|
string |
✅ Yes* |
Kubernetes API server URL |
|
string |
✅ Yes* |
Cluster name (alternative to server) |
|
string |
✅ Yes |
Target namespace |
*One of server or name required.
Example:
spec:
destination:
server: https://kubernetes.default.svc # Deploy to same cluster as ArgoCD
namespace: gitlabbda
Remote cluster example:
spec:
destination:
name: production-cluster # Cluster registered in ArgoCD
namespace: gitlabbda
spec.syncPolicy¶
Field |
Type |
Required |
Description |
|---|---|---|---|
|
object |
⚠️ Optional |
Auto-sync configuration |
|
list |
⚠️ Optional |
Sync behavior options |
|
object |
⚠️ Optional |
Retry failed syncs |
automated¶
Field |
Type |
Default |
Description |
|---|---|---|---|
|
bool |
|
Delete resources removed from git |
|
bool |
|
Revert manual changes to cluster |
|
bool |
|
Allow syncing to empty git directory |
Example:
spec:
syncPolicy:
automated:
prune: true # Delete resources not in git
selfHeal: true # Revert kubectl edits
allowEmpty: false # Prevent accidental deletion
Prune behavior:
# Scenario: Delete ConfigMap from git
git rm manifests/configmap.yaml
git commit -m "Remove unused ConfigMap"
git push
# With prune: true
# ArgoCD deletes ConfigMap from cluster
# With prune: false
# ConfigMap remains in cluster (drift)
SelfHeal behavior:
# Scenario: Manual kubectl edit
kubectl scale deployment/gitlab-webservice --replicas=5
# With selfHeal: true
# ArgoCD detects drift, scales back to git value (2)
# With selfHeal: false
# ArgoCD shows "OutOfSync" but doesn't fix
syncOptions¶
Option |
Description |
|---|---|
|
Create namespace if it doesn’t exist |
|
Only apply changed resources (faster) |
|
Wait for dependents before deleting |
|
Prune resources after new ones are healthy |
|
Use |
|
Use server-side apply (K8S 1.22+) |
|
Skip kubectl validation |
|
Honor ignoreDifferences during sync |
Example:
spec:
syncPolicy:
syncOptions:
- CreateNamespace=true
- ApplyOutOfSyncOnly=true
- PruneLast=true
Common combinations:
Standard deployment:
syncOptions:
- CreateNamespace=true
- ApplyOutOfSyncOnly=true
Database deployments (graceful shutdown):
syncOptions:
- PrunePropagationPolicy=foreground
- PruneLast=true
Large deployments (faster):
syncOptions:
- ApplyOutOfSyncOnly=true
- ServerSideApply=true
retry¶
Field |
Type |
Default |
Description |
|---|---|---|---|
|
int |
|
Maximum retry attempts |
|
string |
|
Initial backoff duration |
|
int |
|
Backoff multiplier |
|
string |
|
Maximum backoff duration |
Example:
spec:
syncPolicy:
retry:
limit: 5
backoff:
duration: 5s
factor: 2
maxDuration: 3m
Retry schedule: 5s, 10s, 20s, 40s, 80s (capped at 3m)
spec.ignoreDifferences¶
Ignore specific fields when detecting drift.
Structure:
spec:
ignoreDifferences:
- group: <apiGroup>
kind: <Kind>
name: <resourceName> # Optional: specific resource
namespace: <namespace> # Optional: specific namespace
jsonPointers:
- /path/to/field
jqPathExpressions:
- .path.to.field
Common use cases:
HPA-managed replicas:
ignoreDifferences:
- group: apps
kind: Deployment
jsonPointers:
- /spec/replicas # HPA modifies this
Cluster-managed secrets:
ignoreDifferences:
- group: ""
kind: Secret
name: gitlab-postgres-app # CNPG-managed
jsonPointers:
- /data # Don't track data changes
Status fields:
ignoreDifferences:
- group: postgresql.cnpg.io
kind: Cluster
jsonPointers:
- /status # Status constantly changes
Annotations added by operators:
ignoreDifferences:
- group: apps
kind: Deployment
jqPathExpressions:
- .metadata.annotations."deployment.kubernetes.io/revision"
Sync Waves¶
Control resource creation order using annotations.
Annotation Syntax¶
metadata:
annotations:
argocd.argoproj.io/sync-wave: "<number>"
Wave order: -5, -4, …, -1, 0 (default), 1, 2, 3, …
Rules:
Resources applied in ascending wave order
Resources in same wave applied in parallel
ArgoCD waits for wave N to be healthy before starting wave N+1
GitLab BDA Sync Waves¶
Wave 1: Infrastructure
# Namespace (must exist first)
apiVersion: v1
kind: Namespace
metadata:
name: gitlabbda
annotations:
argocd.argoproj.io/sync-wave: "1"
# RBAC (needed for service accounts)
apiVersion: v1
kind: ServiceAccount
metadata:
name: gitlab
annotations:
argocd.argoproj.io/sync-wave: "1"
# Crossplane ProviderConfig (needed for buckets)
apiVersion: aws.upbound.io/v1beta1
kind: ProviderConfig
metadata:
name: hetzner-s3
annotations:
argocd.argoproj.io/sync-wave: "1"
# S3 Buckets (Crossplane resources)
apiVersion: s3.aws.upbound.io/v1beta2
kind: Bucket
metadata:
name: artifacts-gitlabbda-kup6s
annotations:
argocd.argoproj.io/sync-wave: "1"
Wave 2: Secrets
# ClusterSecretStore (ESO needs this)
apiVersion: external-secrets.io/v1beta1
kind: ClusterSecretStore
metadata:
name: gitlabbda-app-secrets-store
annotations:
argocd.argoproj.io/sync-wave: "2"
# ExternalSecrets (wait for store)
apiVersion: external-secrets.io/v1beta1
kind: ExternalSecret
metadata:
name: gitlab-secrets
annotations:
argocd.argoproj.io/sync-wave: "2"
spec:
refreshInterval: 1h
secretStoreRef:
name: gitlabbda-app-secrets-store
kind: ClusterSecretStore
target:
name: gitlab-secrets
Wave 3: Applications
# PostgreSQL (needs secrets)
apiVersion: postgresql.cnpg.io/v1
kind: Cluster
metadata:
name: gitlab-postgres
annotations:
argocd.argoproj.io/sync-wave: "3"
# Redis (needs namespace)
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: redis
annotations:
argocd.argoproj.io/sync-wave: "3"
# GitLab (needs database, Redis, secrets)
apiVersion: apps/v1
kind: Deployment
metadata:
name: gitlab-webservice
annotations:
argocd.argoproj.io/sync-wave: "3"
Adding Sync Waves in CDK8S¶
// charts/constructs/database.ts
export class DatabaseConstruct extends Construct {
constructor(scope: Construct, id: string, config: AppConfig) {
super(scope, id);
const cluster = new cnpg.Cluster(this, 'postgres', {
metadata: {
namespace: config.namespace,
annotations: {
'argocd.argoproj.io/sync-wave': '3', // After secrets (wave 2)
},
},
// ... cluster config ...
});
}
}
ArgoCD-Specific Annotations¶
Sync Annotations¶
Annotation |
Values |
Description |
|---|---|---|
|
number |
Sync order (see above) |
|
string |
Resource-level sync options |
Example:
metadata:
annotations:
argocd.argoproj.io/sync-wave: "2"
argocd.argoproj.io/sync-options: "Prune=false" # Don't prune this resource
Hook Annotations¶
Annotation |
Values |
Description |
|---|---|---|
|
|
When to execute |
|
|
When to delete hook resource |
Example: Database migration job
apiVersion: batch/v1
kind: Job
metadata:
name: gitlab-migrations
annotations:
argocd.argoproj.io/hook: PreSync # Run before main sync
argocd.argoproj.io/hook-delete-policy: HookSucceeded # Delete after success
argocd.argoproj.io/sync-wave: "3"
spec:
template:
spec:
containers:
- name: migrate
image: gitlab/gitlab-ce:18.5.1
command: ["/bin/sh", "-c", "gitlab-rake db:migrate"]
Note: GitLab BDA doesn’t currently use hooks (migrations handled by GitLab Helm chart).
Repository Credentials¶
For private repositories, configure credentials in ArgoCD.
GitLab Deploy Token¶
1. Create deploy token in GitLab:
Settings → Repository → Deploy Tokens
Scopes:
read_repositorySave token (shown once!)
2. Create ArgoCD repository secret:
kubectl create secret generic gitlab-repo-creds \
-n argocd \
--from-literal=type=git \
--from-literal=url=https://git.bluedynamics.eu/kup6s/dp/dp-infra.git \
--from-literal=username=gitlab+deploy-token-123 \
--from-literal=password=<deploy-token>
kubectl label secret gitlab-repo-creds \
-n argocd \
argocd.argoproj.io/secret-type=repository
3. Verify:
# Check repository is connected
argocd repo list
# Should show:
# URL: https://git.bluedynamics.eu/kup6s/dp/dp-infra.git
# STATUS: Successful
SSH Key (Alternative)¶
1. Generate SSH key:
ssh-keygen -t ed25519 -C "argocd-gitlab-bda" -f ~/.ssh/argocd-gitlab
2. Add public key to GitLab:
Settings → Repository → Deploy Keys
Paste public key (
~/.ssh/argocd-gitlab.pub)
3. Create ArgoCD secret:
kubectl create secret generic gitlab-repo-ssh \
-n argocd \
--from-literal=type=git \
--from-literal=url=git@git.bluedynamics.eu:kup6s/dp/gitlab.git \
--from-file=sshPrivateKey=$HOME/.ssh/argocd-gitlab
kubectl label secret gitlab-repo-ssh \
-n argocd \
argocd.argoproj.io/secret-type=repository
Health Assessment¶
ArgoCD assesses resource health using built-in rules.
Standard Health Checks¶
Healthy resources:
Deployment: All replicas ready
StatefulSet: All replicas ready
DaemonSet: All pods ready
Service: Always healthy (unless type=LoadBalancer pending)
Job: Completed successfully
PVC: Bound
Progressing:
Deployment: Waiting for replicas
Job: Running
Degraded:
Deployment: CrashLoopBackOff, ImagePullBackOff
Job: Failed
Custom Health Checks¶
Define custom health for CRDs:
# argocd-cm ConfigMap
apiVersion: v1
kind: ConfigMap
metadata:
name: argocd-cm
namespace: argocd
data:
resource.customizations.health.postgresql.cnpg.io_Cluster: |
hs = {}
if obj.status ~= nil then
if obj.status.phase == "Cluster in healthy state" then
hs.status = "Healthy"
hs.message = "PostgreSQL cluster is healthy"
elseif obj.status.phase == "Applying configuration" then
hs.status = "Progressing"
hs.message = "Applying configuration changes"
else
hs.status = "Degraded"
hs.message = obj.status.phase or "Unknown status"
end
else
hs.status = "Progressing"
hs.message = "Waiting for status"
end
return hs
Note: Most CRDs (CNPG, Crossplane, ESO) have built-in health checks.
CLI Commands¶
Get Application Status¶
# List all applications
argocd app list
# Get specific application
argocd app get gitlab-bda
# Show application tree (resources)
argocd app get gitlab-bda --show-operation
Manual Sync¶
# Sync application
argocd app sync gitlab-bda
# Sync specific resource
argocd app sync gitlab-bda --resource apps:Deployment:gitlab-webservice
# Dry-run sync
argocd app sync gitlab-bda --dry-run
Check Diff¶
# Compare git vs cluster
argocd app diff gitlab-bda
# Shows:
# - Resources in git but not cluster
# - Resources in cluster but not git
# - Field differences
History and Rollback¶
# Show sync history
argocd app history gitlab-bda
# Rollback to previous revision
argocd app rollback gitlab-bda <revision>
# Example:
argocd app rollback gitlab-bda 42
Force Refresh¶
# Force git repository refresh (don't wait 3 minutes)
argocd app get gitlab-bda --refresh
# Hard refresh (clear cache)
argocd app get gitlab-bda --hard-refresh