Installing Argo CD the GitOps Way: A More Stable and Maintainable Approach
I recently deployed Argo CD in my dev cloud and I’m already impressed with how much it improves my Kubernetes workflow. Instead of following the quick official installation method, I adapted the process for better version control, reproducibility, and long-term stability.
The Official Quick-Start Method
The fastest way to get Argo CD running is this one-liner:
kubectl create namespace argocd
kubectl apply -n argocd --server-side --force-conflicts -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml
This works great for testing or throwaway environments. For production or long-lived setups, however, I strongly recommend a more deliberate approach.
Why a GitOps-First Installation Is Better
Argo CD is almost entirely configured through Kubernetes ConfigMaps and other manifests. While you can tweak some settings in the web UI, most changes live in YAML files. Relying on ad-hoc kubectl commands makes it easy to lose track of changes, forget why something was modified, or end up with inconsistent configurations across team members.
Here’s the recommended workflow I followed:
- Create a dedicated Git repository for Argo CD configuration.
- Download the official manifests and commit them to your repo.
- Use a CI/CD pipeline to deploy the manifests (use --server-side --force-conflicts on the very first apply).
- After the initial deployment, you can let Argo CD manage its own configuration (self-management) or continue using the CI/CD pipeline. Both approaches work well.
The big advantages are clear version history, proper editing with your favorite tools, and a stable local copy that doesn’t change unexpectedly with every upstream update.
Note on --server-side --force-conflicts
This is required because some Argo CD Custom Resource Definitions (like ApplicationSet) exceed the size limit for client-side apply. Server-side apply avoids storing the large last-applied-configuration annotation. The force flag safely takes ownership of fields during fresh installs or upgrades.
Installing the Argo CD CLI (Optional but Handy)
The Argo CD CLI is useful for scripting, automation, and quick checks from your workstation or CI/CD pipelines.
On Linux, install it with:
curl -sSL -o argocd-linux-amd64 https://github.com/argoproj/argo-cd/releases/latest/download/argocd-linux-amd64
sudo install -m 555 argocd-linux-amd64 /usr/local/bin/argocd
rm argocd-linux-amd64
Adapting Argo CD for My Environment
Because I expose all services through an external HAProxy that handles TLS termination, I needed to run Argo CD in insecure mode (disabling its built-in TLS). Same is required when you use argocd cli.
apiVersion: v1
kind: ConfigMap
metadata:
labels:
app.kubernetes.io/name: argocd-cmd-params-cm
app.kubernetes.io/part-of: argocd
name: argocd-cmd-params-cm
data:
server.insecure: "true"
Exposing Argo CD via NodePort
The official docs don’t clearly document NodePort as an option, so I customized the Service:
apiVersion: v1
kind: Service
metadata:
labels:
app.kubernetes.io/component: server
app.kubernetes.io/name: argocd-server
app.kubernetes.io/part-of: argocd
name: argocd-server
spec:
ports:
- name: http
port: 80
protocol: TCP
targetPort: 8080
nodePort: 30080 # adjust to your needs
selector:
app.kubernetes.io/name: argocd-server
type: NodePort
Since HAProxy forwards everything to HTTP on port 80, the HTTPS port isn’t needed. The --insecure flag prevents redirect loops.
Setting Up OIDC Authentication with Keycloak
For centralized authentication, I configured Argo CD to use my existing Keycloak instance via OIDC, which his why I needed the service to be accessible from outside Kubernetes in first place:
First, create a client in Keycloak, then add this to the argocd-cm ConfigMap:
apiVersion: v1
kind: ConfigMap
metadata:
name: argocd-cm
data:
url: https://argocd.yourdomain.com
oidc.config: |
name: Keycloak
issuer: https://keycloak.yourdomain.com/realms/your_realm
clientID: argocd
clientSecret: $oidc.keycloak.clientSecret
refreshTokenThreshold: 2m
requestedScopes: ["openid", "profile", "email", "groups"]
This gives me single sign-on with Keycloak, which is especially useful in company environments that already use centralized identity management.
Visualizing the GitOps Flow with Argo CD
Here’s how the GitOps loop looks when Argo CD manages applications — and even itself:
Keycloak OIDC Authentication Flow
And here’s the authentication flow once OIDC is configured:
Next Steps
At this point, Argo CD is up and running with a clean GitOps foundation, external load balancing, and centralized authentication. In the next post, I’ll cover how to add and manage your first applications declaratively.
If you’re setting up Argo CD in your own environment — especially with external TLS termination or OIDC — I hope these tweaks save you some time.
Have you tried managing Argo CD declaratively yet? Do you prefer the CLI or the UI for day-to-day operations? Share your thoughts in the comments!
Did you find this post helpful? You can support me.



Top comments (0)