How to Set Up ArgoCD for GitOps on RHEL 7

GitOps is an operational model in which the desired state of your infrastructure and applications is stored declaratively in a Git repository, and an automated agent continuously reconciles that desired state with the actual running state in your Kubernetes cluster. ArgoCD is the leading open-source GitOps controller for Kubernetes, providing a powerful web UI, CLI, and API for managing deployments. On RHEL 7 — a common OS for enterprise Kubernetes nodes and management hosts — ArgoCD enables engineering teams to turn Git merges into deployments without manual kubectl apply commands. This tutorial covers installing ArgoCD into Kubernetes, connecting Git repositories, defining Application manifests, using sync wave annotations, configuring automated sync policies, the app-of-apps pattern, and operating ArgoCD from the command line.

Prerequisites

  • RHEL 7 host with kubectl configured to reach a Kubernetes cluster (v1.19+)
  • Sufficient cluster permissions to create namespaces, CRDs, RBAC resources, and deployments
  • A Git repository (GitHub, GitLab, Bitbucket, or self-hosted Gitea) accessible from the cluster
  • curl installed on the RHEL 7 host for downloading the ArgoCD CLI
  • Optional: an Ingress controller or LoadBalancer to expose the ArgoCD UI externally

Step 1: Installing ArgoCD into Kubernetes

ArgoCD is deployed as a set of Kubernetes workloads inside its own namespace. The project provides an official installation manifest that creates all required CRDs, RBAC, services, and deployments in a single apply:

# Create the ArgoCD namespace
kubectl create namespace argocd

# Apply the official installation manifest
kubectl apply -n argocd -f 
  https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml

# Wait until all pods are running
kubectl rollout status deployment argocd-server -n argocd --timeout=300s
kubectl get pods -n argocd

Expected pods once installation is complete:

argocd-application-controller-0
argocd-applicationset-controller-xxxxxxxxx
argocd-dex-server-xxxxxxxxx
argocd-notifications-controller-xxxxxxxxx
argocd-redis-xxxxxxxxx
argocd-repo-server-xxxxxxxxx
argocd-server-xxxxxxxxx

Step 2: Accessing the ArgoCD API Server

By default the argocd-server service is of type ClusterIP. You have several options to expose it:

# Option 1: Port-forward for local testing
kubectl port-forward svc/argocd-server -n argocd 8080:443

# Option 2: Change service type to LoadBalancer
kubectl patch svc argocd-server -n argocd 
  -p '{"spec": {"type": "LoadBalancer"}}'

# Option 3: Create an Ingress resource (requires ingress controller)
cat >>/tmp/argocd-ingress.yaml <<'EOF'
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: argocd-server-ingress
  namespace: argocd
  annotations:
    nginx.ingress.kubernetes.io/ssl-passthrough: "true"
    nginx.ingress.kubernetes.io/backend-protocol: "HTTPS"
spec:
  ingressClassName: nginx
  rules:
    - host: argocd.example.com
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: argocd-server
                port:
                  number: 443
EOF
kubectl apply -f /tmp/argocd-ingress.yaml

Retrieve the initial admin password (it is stored as a Kubernetes secret and must be rotated after first login):

kubectl -n argocd get secret argocd-initial-admin-secret 
  -o jsonpath="{.data.password}" | base64 -d; echo

Step 3: Installing the ArgoCD CLI on RHEL 7

# Download the latest stable ArgoCD CLI binary
ARGOCD_VERSION=$(curl -s https://api.github.com/repos/argoproj/argo-cd/releases/latest 
  | grep tag_name | cut -d '"' -f 4)

curl -sSL -o /usr/local/bin/argocd 
  "https://github.com/argoproj/argo-cd/releases/download/${ARGOCD_VERSION}/argocd-linux-amd64"

chmod +x /usr/local/bin/argocd
argocd version --client

Log in to the ArgoCD server (replace the address with your actual endpoint):

# If using port-forward, the server is localhost:8080
argocd login localhost:8080 
  --username admin 
  --password "$(kubectl -n argocd get secret argocd-initial-admin-secret 
      -o jsonpath='{.data.password}' | base64 -d)" 
  --insecure

# Update the admin password immediately
argocd account update-password

Step 4: Connecting a Git Repository

ArgoCD needs read access to your Git repository. For public repositories no credentials are required. For private repositories you must provide either HTTPS credentials or an SSH key.

Option A: HTTPS with username/token

argocd repo add https://github.com/your-org/your-app-config.git 
  --username your-github-username 
  --password your-personal-access-token

Option B: SSH key authentication

# Generate an SSH key pair (do NOT set a passphrase for automation)
ssh-keygen -t ed25519 -C "argocd@cluster" -f ~/.ssh/argocd_deploy_key -N ""

# Add the public key as a deploy key in your Git repository UI
cat ~/.ssh/argocd_deploy_key.pub

# Register the private key with ArgoCD
argocd repo add [email protected]:your-org/your-app-config.git 
  --ssh-private-key-path ~/.ssh/argocd_deploy_key

Verify the repository shows as Successful:

argocd repo list

Step 5: Creating an Application Manifest

An ArgoCD Application is a Kubernetes custom resource that tells ArgoCD where to find source manifests (Git) and where to deploy them (Kubernetes cluster and namespace). Create the manifest file:

cat > /tmp/my-app.yaml <<'EOF'
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: my-app
  namespace: argocd
  labels:
    app.kubernetes.io/name: my-app
    environment: production
spec:
  project: default
  source:
    repoURL: https://github.com/your-org/your-app-config.git
    targetRevision: main
    path: apps/my-app
  destination:
    server: https://kubernetes.default.svc
    namespace: production
  syncPolicy:
    syncOptions:
      - CreateNamespace=true
EOF

kubectl apply -f /tmp/my-app.yaml

Key fields in the Application spec:

  • source.repoURL — the Git repository URL
  • source.targetRevision — branch, tag, or commit SHA to track
  • source.path — directory within the repository containing Kubernetes manifests
  • destination.server — Kubernetes API server URL (https://kubernetes.default.svc for in-cluster)
  • destination.namespace — target namespace for deployed resources

Step 6: Using Sync Wave Annotations

When an Application contains multiple resources, ArgoCD applies them concurrently by default. Sync waves let you control the order, ensuring, for example, that a database is ready before the application that depends on it:

# database.yaml — deploy in wave 0 (first)
apiVersion: apps/v1
kind: Deployment
metadata:
  name: postgres
  annotations:
    argocd.argoproj.io/sync-wave: "0"
spec:
  # ...

---
# migration-job.yaml — run migrations in wave 1 (after DB is up)
apiVersion: batch/v1
kind: Job
metadata:
  name: db-migrate
  annotations:
    argocd.argoproj.io/sync-wave: "1"
spec:
  # ...

---
# app.yaml — deploy the application in wave 2 (after migrations)
apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-app
  annotations:
    argocd.argoproj.io/sync-wave: "2"
spec:
  # ...

Resources within the same wave are applied together. ArgoCD waits for all resources in wave N to be healthy before moving to wave N+1.

Step 7: Configuring Automated Sync Policy

By default ArgoCD detects drift (differences between Git and live state) but does not automatically apply changes. Enable automated sync for fully hands-off GitOps deployments:

cat > /tmp/my-app-autosync.yaml <<'EOF'
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: my-app
  namespace: argocd
spec:
  project: default
  source:
    repoURL: https://github.com/your-org/your-app-config.git
    targetRevision: main
    path: apps/my-app
  destination:
    server: https://kubernetes.default.svc
    namespace: production
  syncPolicy:
    automated:
      prune: true        # Delete resources removed from Git
      selfHeal: true     # Re-apply if someone manually changes the cluster
    syncOptions:
      - CreateNamespace=true
      - PrunePropagationPolicy=foreground
      - ApplyOutOfSyncOnly=true
EOF

kubectl apply -f /tmp/my-app-autosync.yaml

With prune: true and selfHeal: true, ArgoCD becomes the single source of truth: any manual cluster change will be reverted, and any Git deletion will be propagated to the cluster.

Step 8: The App-of-Apps Pattern

For managing many applications at scale, the app-of-apps pattern uses a parent ArgoCD Application whose source repository contains child Application manifests. A single sync of the parent bootstraps the entire platform:

# Repository structure:
# platform/
# ├── Chart.yaml (optional, if using Helm)
# ├── apps/
# │   ├── nginx-ingress.yaml    (Application CRD)
# │   ├── cert-manager.yaml     (Application CRD)
# │   ├── prometheus.yaml       (Application CRD)
# │   └── my-app.yaml           (Application CRD)

# Parent application pointing at the apps/ directory
cat > /tmp/platform-app.yaml <<'EOF'
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: platform
  namespace: argocd
spec:
  project: default
  source:
    repoURL: https://github.com/your-org/platform-config.git
    targetRevision: main
    path: apps
  destination:
    server: https://kubernetes.default.svc
    namespace: argocd
  syncPolicy:
    automated:
      prune: true
      selfHeal: true
EOF

kubectl apply -f /tmp/platform-app.yaml

Step 9: Operating ArgoCD with the CLI

# List all applications
argocd app list

# Get detailed status of a specific app
argocd app get my-app

# Manually trigger a sync
argocd app sync my-app

# Sync and wait for completion
argocd app sync my-app --timeout 300

# View live resource tree
argocd app resources my-app

# Show diff between Git desired state and live state
argocd app diff my-app

# Hard refresh (bypass cache and re-query Git)
argocd app get my-app --hard-refresh

# Rollback to a previous revision
argocd app history my-app
argocd app rollback my-app 3

ArgoCD transforms Kubernetes operations on RHEL 7 from a manual, error-prone process into a reliable, auditable, Git-driven workflow. By storing every application configuration in version control and letting ArgoCD reconcile live state against that source of truth, teams gain an automatic audit trail, easy rollback, environment promotion via branch or tag targeting, and the confidence that what you see in Git is exactly what is running in your cluster. Combined with the app-of-apps pattern and sync waves, ArgoCD scales from managing a handful of microservices to governing an entire enterprise platform from a single Git repository.