Skip to content

Install via ArgoCD

To leverage the GitOps features of ArgoCD to deploy a chart, follow the procedure below.

0. Requirements

  • A running OpenShift cluster with appropriate permissions
  • OpenShift client installed: sudo yum install openshift-client
  • Connected to your cluster: oc login <cluster_api_url>

1. Deploy ArgoCD project

If GitOps is not enabled in your cluster, deploy it with:

echo "begin deploying argocd project"
oc process -f https://gitlab.com/sxcm/cli/-/raw/main/src/resources/argocd-project.yml | oc apply -f -
echo "switching to openshift-gitops namespace"
oc project openshift-gitops
echo "deploying secrets links for gitops deployments"
oc secrets link argocd-application-controller startx-registrycreds-docker --for=pull -n openshift-gitops
oc secrets link argocd-dex-server startx-registrycreds-docker --for=pull -n openshift-gitops
oc secrets link argocd-operator startx-registrycreds-docker --for=pull -n openshift-gitops
oc secrets link argocd-redis-ha startx-registrycreds-docker --for=pull -n openshift-gitops
oc secrets link argocd-server startx-registrycreds-docker --for=pull -n openshift-gitops
oc secrets link default startx-registrycreds-docker --for=pull -n openshift-gitops
oc secrets link deployer startx-registrycreds-docker --for=pull -n openshift-gitops
oc secrets link openshift-gitops-application-controller startx-registrycreds-docker --for=pull -n openshift-gitops
oc secrets link openshift-gitops-dex-server startx-registrycreds-docker --for=pull -n openshift-gitops
oc secrets link openshift-gitops-redis-ha startx-registrycreds-docker --for=pull -n openshift-gitops
oc secrets link openshift-gitops-server startx-registrycreds-docker --for=pull -n openshift-gitops
echo "pause deploying argocd project"
sleep 60
echo "end deploying argocd project"

2. Deploy ArgoCD control-plane

If GitOps is not enabled in your cluster, run the following after the previous step:

echo "begin deploying argocd control-plane"
oc process -f https://gitlab.com/sxcm/cli/-/raw/main/src/resources/argocd-deploy-small.yml | oc apply -f -
echo "pause deploying argocd control-plane"
sleep 90
echo "end deploying argocd control-plane"

3. Check ArgoCD deployments

Wait for all pods in the gitops namespace to be ready:

oc get pod -n openshift-gitops -w

4. Deploy cluster-services

We use the Crunchy PostgreSQL operator (cluster-crunchy) as a complete example of the standard pattern.

Every cluster-* chart is split into three Applications with explicit sync-waves to enforce a safe creation and deletion order:

Application Wave Role
cluster-crunchy-project 1 Creates the namespace — created first, deleted last
cluster-crunchy-operator 2 Installs the operator — deleted after the database instance is gone
cluster-crunchy-app 3 Deploys the PostgresCluster CR — deleted first so the operator is still alive to process finalizers

Deletion order matters. Always delete -app first and wait for completion before deleting -operator, then -project. Deleting the operator before its CRs orphans the CR finalizers and leaves the namespace stuck in Terminating indefinitely.

4.0. Create the AppProject

An AppProject scopes the Applications to specific source repos and destination namespaces.

cat <<EOF | oc apply -f -
apiVersion: argoproj.io/v1alpha1
kind: AppProject
metadata:
  name: cluster-crunchy
  namespace: openshift-gitops
spec:
  description: Configure Crunchy PostgreSQL operator
  sourceRepos:
    - http://sx-helm-repository-prod.s3-website.eu-west-3.amazonaws.com/stable
  destinations:
    - namespace: openshift-gitops
      server: https://kubernetes.default.svc
    - namespace: openshift-crunchy-pgo
      server: https://kubernetes.default.svc
    - namespace: startx-crunchy
      server: https://kubernetes.default.svc
  clusterResourceWhitelist:
    - group: '*'
      kind: '*'
  namespaceResourceWhitelist:
    - group: '*'
      kind: '*'
EOF

4.1. Create the namespace (project)

Wave 1 — no resources-finalizer: the namespace cleans up naturally once its contents are removed by the other two Applications.

cat <<EOF | oc apply -f -
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: cluster-crunchy-project
  namespace: openshift-gitops
  annotations:
    argocd.argoproj.io/sync-wave: "1"
spec:
  project: cluster-crunchy
  source:
    repoURL: http://sx-helm-repository-prod.s3-website.eu-west-3.amazonaws.com/stable
    chart: cluster-crunchy
    targetRevision: 21.3.27
    helm:
      valueFiles:
        - values-startx_noinfra.yaml
      values: |
        project:
          enabled: true
        operator:
          enabled: false
  destination:
    server: https://kubernetes.default.svc
    namespace: openshift-gitops
  syncPolicy:
    automated:
      prune: true
      selfHeal: true
EOF

4.2. Deploy the operator

Wave 2 — with resources-finalizer so ArgoCD cascade-deletes the operator subscription and CSV on removal.

cat <<EOF | oc apply -f -
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: cluster-crunchy-operator
  namespace: openshift-gitops
  annotations:
    argocd.argoproj.io/sync-wave: "2"
  finalizers:
    - resources-finalizer.argocd.argoproj.io
spec:
  project: cluster-crunchy
  source:
    repoURL: http://sx-helm-repository-prod.s3-website.eu-west-3.amazonaws.com/stable
    chart: cluster-crunchy
    targetRevision: 21.3.27
    helm:
      valueFiles:
        - values-startx_noinfra.yaml
      values: |
        operator:
          enabled: true
  destination:
    server: https://kubernetes.default.svc
    namespace: openshift-gitops
  syncPolicy:
    automated:
      prune: true
      selfHeal: true
EOF

4.3. Deploy the PostgresCluster instance

Wave 3 — with resources-finalizer and ignoreDifferences on metadata.finalizers. The Crunchy operator adds its own finalizers to the PostgresCluster CR after creation; ignoring that field prevents permanent OutOfSync.

cat <<EOF | oc apply -f -
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: cluster-crunchy-app
  namespace: openshift-gitops
  annotations:
    argocd.argoproj.io/sync-wave: "3"
  finalizers:
    - resources-finalizer.argocd.argoproj.io
spec:
  project: cluster-crunchy
  source:
    repoURL: http://sx-helm-repository-prod.s3-website.eu-west-3.amazonaws.com/stable
    chart: cluster-crunchy
    targetRevision: 21.3.27
    helm:
      valueFiles:
        - values-startx_noinfra.yaml
      values: |
        crunchy:
          enabled: true
        operator:
          enabled: false
  destination:
    server: https://kubernetes.default.svc
    namespace: openshift-gitops
  ignoreDifferences:
    - group: postgres-operator.crunchydata.com
      kind: PostgresCluster
      jsonPointers:
        - /metadata/finalizers
  syncPolicy:
    automated:
      prune: true
      selfHeal: true
EOF

5. Verify sync

oc get applications -n openshift-gitops | grep cluster-crunchy

All three Applications should reach Synced / Healthy.

6. Safe teardown

Delete in reverse wave order and wait between each step:

# Delete app first (operator is still running — can process PostgresCluster finalizers)
oc delete application cluster-crunchy-app -n openshift-gitops
oc wait --for=delete application/cluster-crunchy-app -n openshift-gitops --timeout=300s

# Then operator
oc delete application cluster-crunchy-operator -n openshift-gitops
oc wait --for=delete application/cluster-crunchy-operator -n openshift-gitops --timeout=120s

# Finally project (namespace empties naturally)
oc delete application cluster-crunchy-project -n openshift-gitops

If a namespace gets stuck Terminating (operator deleted before its CR): patch the CR to remove the orphaned finalizer, then patch the Application to remove resources-finalizer.argocd.argoproj.io. See the CLAUDE.md emergency cleanup section for the exact commands.