DEV Community

Ježek
Ježek

Posted on

Getting started with Argo CD using the CLI

Argo CD is a declarative, GitOps-based continuous delivery (CD) tool for Kubernetes. It automates the deployment and lifecycle management of applications in a cluster by using Git repositories as the single source of truth for the desired state of the infrastructure.

This article explains how to set up Argo CD and deploy an application in a Kubernetes cluster using the command line and manifests.


Prerequisites:


Kubernetes Cluster

#  kind-cluster.yaml

kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
networking:
  apiServerPort: 6443
nodes:
- role: control-plane
- role: worker
- role: worker
- role: worker
Enter fullscreen mode Exit fullscreen mode
$ kind create cluster --config kind-cluster.yaml
Creating cluster "kind" ...
 • Ensuring node image (kindest/node:v1.33.1) 🖼  ...
 ✓ Ensuring node image (kindest/node:v1.33.1) 🖼
 • Preparing nodes 📦 📦 📦 📦   ...
 ✓ Preparing nodes 📦 📦 📦 📦
 • Writing configuration 📜  ...
 ✓ Writing configuration 📜
 • Starting control-plane 🕹️  ...
 ✓ Starting control-plane 🕹️
 • Installing CNI 🔌  ...
 ✓ Installing CNI 🔌
 • Installing StorageClass 💾  ...
 ✓ Installing StorageClass 💾
 • Joining worker nodes 🚜  ...
 ✓ Joining worker nodes 🚜
Set kubectl context to "kind-kind"
You can now use your cluster with:

kubectl cluster-info --context kind-kind

Have a nice day! 👋
Enter fullscreen mode Exit fullscreen mode
$ kubectl get nodes
NAME                 STATUS   ROLES           AGE     VERSION
kind-control-plane   Ready    control-plane   7m2s    v1.33.1
kind-worker          Ready    <none>          6m53s   v1.33.1
kind-worker2         Ready    <none>          6m53s   v1.33.1
kind-worker3         Ready    <none>          6m53s   v1.33.1
Enter fullscreen mode Exit fullscreen mode

Argo CD

Setup the Argo CD

$ kubectl create namespace argocd
namespace/argocd created

$ kubectl get namespaces
NAME                 STATUS   AGE
argocd               Active   9s
default              Active   15m
kube-node-lease      Active   15m
kube-public          Active   15m
kube-system          Active   15m
local-path-storage   Active   15m
Enter fullscreen mode Exit fullscreen mode
$ kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml
customresourcedefinition.apiextensions.k8s.io/applications.argoproj.io created
customresourcedefinition.apiextensions.k8s.io/applicationsets.argoproj.io created
customresourcedefinition.apiextensions.k8s.io/appprojects.argoproj.io created
serviceaccount/argocd-application-controller created
serviceaccount/argocd-applicationset-controller created
serviceaccount/argocd-dex-server created
serviceaccount/argocd-notifications-controller created
serviceaccount/argocd-redis created
serviceaccount/argocd-repo-server created
serviceaccount/argocd-server created
role.rbac.authorization.k8s.io/argocd-application-controller created
role.rbac.authorization.k8s.io/argocd-applicationset-controller created
role.rbac.authorization.k8s.io/argocd-dex-server created
role.rbac.authorization.k8s.io/argocd-notifications-controller created
role.rbac.authorization.k8s.io/argocd-redis created
role.rbac.authorization.k8s.io/argocd-server created
clusterrole.rbac.authorization.k8s.io/argocd-application-controller created
clusterrole.rbac.authorization.k8s.io/argocd-applicationset-controller created
clusterrole.rbac.authorization.k8s.io/argocd-server created
rolebinding.rbac.authorization.k8s.io/argocd-application-controller created
rolebinding.rbac.authorization.k8s.io/argocd-applicationset-controller created
rolebinding.rbac.authorization.k8s.io/argocd-dex-server created
rolebinding.rbac.authorization.k8s.io/argocd-notifications-controller created
rolebinding.rbac.authorization.k8s.io/argocd-redis created
rolebinding.rbac.authorization.k8s.io/argocd-server created
clusterrolebinding.rbac.authorization.k8s.io/argocd-application-controller created
clusterrolebinding.rbac.authorization.k8s.io/argocd-applicationset-controller created
clusterrolebinding.rbac.authorization.k8s.io/argocd-server created
configmap/argocd-cm created
configmap/argocd-cmd-params-cm created
configmap/argocd-gpg-keys-cm created
configmap/argocd-notifications-cm created
configmap/argocd-rbac-cm created
configmap/argocd-ssh-known-hosts-cm created
configmap/argocd-tls-certs-cm created
secret/argocd-notifications-secret created
secret/argocd-secret created
service/argocd-applicationset-controller created
service/argocd-dex-server created
service/argocd-metrics created
service/argocd-notifications-controller-metrics created
service/argocd-redis created
service/argocd-repo-server created
service/argocd-server created
service/argocd-server-metrics created
deployment.apps/argocd-applicationset-controller created
deployment.apps/argocd-dex-server created
deployment.apps/argocd-notifications-controller created
deployment.apps/argocd-redis created
deployment.apps/argocd-repo-server created
deployment.apps/argocd-server created
statefulset.apps/argocd-application-controller created
networkpolicy.networking.k8s.io/argocd-application-controller-network-policy created
networkpolicy.networking.k8s.io/argocd-applicationset-controller-network-policy created
networkpolicy.networking.k8s.io/argocd-dex-server-network-policy created
networkpolicy.networking.k8s.io/argocd-notifications-controller-network-policy created
networkpolicy.networking.k8s.io/argocd-redis-network-policy created
networkpolicy.networking.k8s.io/argocd-repo-server-network-policy created
networkpolicy.networking.k8s.io/argocd-server-network-policy created
Enter fullscreen mode Exit fullscreen mode
$ kubectl get all -n argocd
NAME                                                   READY   STATUS    RESTARTS        AGE
pod/argocd-application-controller-0                    1/1     Running   0               4m14s
pod/argocd-applicationset-controller-fc5545556-xwf5k   1/1     Running   0               4m15s
pod/argocd-dex-server-f59c65cff-rn6m5                  1/1     Running   1 (3m10s ago)   4m15s
pod/argocd-notifications-controller-59f6949d7-qmw9h    1/1     Running   0               4m15s
pod/argocd-redis-75c946f559-r7hw9                      1/1     Running   0               4m15s
pod/argocd-repo-server-6959c47c44-zcgvw                1/1     Running   0               4m15s
pod/argocd-server-65544f4864-d8bdg                     1/1     Running   0               4m15s

NAME                                              TYPE           CLUSTER-IP      EXTERNAL-IP   PORT(S)                      AGE
service/argocd-applicationset-controller          ClusterIP      10.96.198.72    <none>        7000/TCP,8080/TCP            4m15s
service/argocd-dex-server                         ClusterIP      10.96.130.197   <none>        5556/TCP,5557/TCP,5558/TCP   4m15s
service/argocd-metrics                            ClusterIP      10.96.76.149    <none>        8082/TCP                     4m15s
service/argocd-notifications-controller-metrics   ClusterIP      10.96.212.160   <none>        9001/TCP                     4m15s
service/argocd-redis                              ClusterIP      10.96.87.147    <none>        6379/TCP                     4m15s
service/argocd-repo-server                        ClusterIP      10.96.249.213   <none>        8081/TCP,8084/TCP            4m15s
service/argocd-server                             ClusterIP      10.96.182.198   <none>        80:31808/TCP,443:32242/TCP   4m15s
service/argocd-server-metrics                     ClusterIP      10.96.205.52    <none>        8083/TCP                     4m15s

NAME                                               READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/argocd-applicationset-controller   1/1     1            1           4m15s
deployment.apps/argocd-dex-server                  1/1     1            1           4m15s
deployment.apps/argocd-notifications-controller    1/1     1            1           4m15s
deployment.apps/argocd-redis                       1/1     1            1           4m15s
deployment.apps/argocd-repo-server                 1/1     1            1           4m15s
deployment.apps/argocd-server                      1/1     1            1           4m15s

NAME                                                         DESIRED   CURRENT   READY   AGE
replicaset.apps/argocd-applicationset-controller-fc5545556   1         1         1       4m15s
replicaset.apps/argocd-dex-server-f59c65cff                  1         1         1       4m15s
replicaset.apps/argocd-notifications-controller-59f6949d7    1         1         1       4m15s
replicaset.apps/argocd-redis-75c946f559                      1         1         1       4m15s
replicaset.apps/argocd-repo-server-6959c47c44                1         1         1       4m15s
replicaset.apps/argocd-server-65544f4864                     1         1         1       4m15s

NAME                                             READY   AGE
statefulset.apps/argocd-application-controller   1/1     4m15s
Enter fullscreen mode Exit fullscreen mode
$ kubectl patch svc argocd-server -n argocd -p '{"spec": {"type": "LoadBalancer"}}'
service/argocd-server patched

$ kubectl get svc argocd-server -n argocd -o=jsonpath='{.status.loadBalancer.ingress[0].ip}'
172.18.0.6

$ curl -sIL http://172.18.0.6:80 -k
HTTP/1.1 307 Temporary Redirect
Content-Type: text/html; charset=utf-8
Location: https://172.18.0.6/
Date: Fri, 28 Nov 2025 14:30:00 GMT

HTTP/1.1 200 OK
Accept-Ranges: bytes
Content-Length: 788
Content-Security-Policy: frame-ancestors 'self';
Content-Type: text/html; charset=utf-8
Vary: Accept-Encoding
X-Frame-Options: sameorigin
X-Xss-Protection: 1
Date: Fri, 28 Nov 2025 14:30:00 GMT
Enter fullscreen mode Exit fullscreen mode
$ argocd admin initial-password -n argocd
CH5hFPo5q1TcHi9-

 This password must be only used for first time login. We strongly recommend you update the password using `argocd account update-password`.

$ argocd login 172.18.0.6 --insecure --username admin
Password: CH5hFPo5q1TcHi9-
'admin:login' logged in successfully
Context '172.18.0.6' updated
Enter fullscreen mode Exit fullscreen mode
$ argocd account update-password
*** Enter password of currently logged in user (admin):
*** Enter new password for user admin:
*** Confirm new password for user admin:
Password updated
Context '172.18.0.6' updated

$ kubectl -n argocd delete secret argocd-initial-admin-secret
secret "argocd-initial-admin-secret" deleted
Enter fullscreen mode Exit fullscreen mode
$ argocd version
argocd: v3.2.0+66b2f30
  BuildDate: 2025-11-04T15:21:01Z
  GitCommit: 66b2f302d91a42cc151808da0eec0846bbe1062c
  GitTreeState: clean
  GoVersion: go1.25.0
  Compiler: gc
  Platform: windows/amd64
argocd-server: v3.2.0+66b2f30
  BuildDate: 2025-11-04T14:51:35Z
  GitCommit: 66b2f302d91a42cc151808da0eec0846bbe1062c
  GitTreeState: clean
  GoVersion: go1.25.0
  Compiler: gc
  Platform: linux/amd64
  Kustomize Version: v5.7.0 2025-06-28T07:00:07Z
  Helm Version: v3.18.4+gd80839c
  Kubectl Version: v0.34.0
Enter fullscreen mode Exit fullscreen mode

Setup a Repository

$ argocd repo add https://github.com/viastakhov/argocd-kustomize-demo.git
Repository 'https://github.com/viastakhov/argocd-kustomize-demo.git' added

$ argocd repo list
TYPE  NAME  REPO                                                     INSECURE  OCI    LFS    CREDS  STATUS      MESSAGE  PROJECT
git         https://github.com/viastakhov/argocd-kustomize-demo.git  false     false  false  false  Successful
Enter fullscreen mode Exit fullscreen mode

Create a Project

Projects provide a logical grouping of applications, which is useful when Argo CD is used by multiple teams.

# ./argo-cd/project.yaml 

apiVersion: argoproj.io/v1alpha1
kind: AppProject
metadata:
  name: nginx
spec:
  sourceRepos:
  - '*'
  destinations:
  - namespace: '*'
    server: '*'
  clusterResourceWhitelist:
  - group: '*'
    kind: '*'
Enter fullscreen mode Exit fullscreen mode
$ argocd proj create -f ./argo-cd/project.yaml

$ argocd proj list
NAME     DESCRIPTION  DESTINATIONS  SOURCES  CLUSTER-RESOURCE-WHITELIST  NAMESPACE-RESOURCE-BLACKLIST  SIGNATURE-KEYS  ORPHANED-RESOURCES  DESTINATION-SERVICE-ACCOUNTS
default               *,*           *        */*                         <none>                        <none>          disabled            <none>
nginx                 *,*           *        */*                         <none>                        <none>          disabled            <none>
Enter fullscreen mode Exit fullscreen mode

Create an Application

An Application is the Kubernetes resource object representing a deployed application instance in an environment.

# ./argo-cd/appset.yaml 

apiVersion: argoproj.io/v1alpha1
kind: ApplicationSet
metadata:
  name: nginx
  namespace: argocd
spec:
  goTemplate: true
  goTemplateOptions: ["missingkey=error"]
  generators:
  - git:
      repoURL: https://github.com/viastakhov/argocd-kustomize-demo.git
      revision: HEAD
      directories:
      - path: kustomize/overlays/*  
  template:
    metadata:
      name: 'nginx-{{index .path.segments 2}}'
      finalizers:
      - resources-finalizer.argocd.argoproj.io
    spec:
      project: nginx
      source:
        repoURL: https://github.com/viastakhov/argocd-kustomize-demo.git
        targetRevision: HEAD
        path: '{{.path.path}}'   
      destination:
        server: https://kubernetes.default.svc
        namespace: '{{index .path.segments 2}}'
      syncPolicy:
        syncOptions:
        - CreateNamespace=false  
        automated:
          enabled: true
          prune: false
          selfHeal: false
          allowEmpty: false
Enter fullscreen mode Exit fullscreen mode
$ argocd appset create ./argo-cd/appset.yaml
ApplicationSet 'nginx' created
Name:               argocd/nginx
Project:            nginx
Server:             https://kubernetes.default.svc
Namespace:          {{index .path.segments 2}}
Source:
- Repo:             https://github.com/viastakhov/argocd-kustomize-demo.git
  Target:           HEAD
  Path:             {{.path.path}}
SyncPolicy:         Automated

$ argocd appset list
NAME          PROJECT  SYNCPOLICY  CONDITIONS                                                                                                                                                                                                                                                             REPO                                                     PATH            TARGET
argocd/nginx  nginx    nil         [{ParametersGenerated Successfully generated parameters for all Applications 2025-12-04 03:04:54 +0300 MSK True ParametersGenerated} {ResourcesUpToDate All applications have been generated successfully 2025-12-04 03:04:54 +0300 MSK True ApplicationSetUpToDate}]  https://github.com/viastakhov/argocd-kustomize-demo.git  {{.path.path}}  HEAD
Enter fullscreen mode Exit fullscreen mode
$ argocd app list
NAME               CLUSTER                         NAMESPACE  PROJECT  STATUS  HEALTH   SYNCPOLICY  CONDITIONS  REPO                                                     PATH                     TARGET
argocd/nginx-dev   https://kubernetes.default.svc  dev        nginx    Synced  Healthy  Auto        <none>      https://github.com/viastakhov/argocd-kustomize-demo.git  kustomize/overlays/dev   HEAD
argocd/nginx-prod  https://kubernetes.default.svc  prod       nginx    Synced  Healthy  Auto        <none>      https://github.com/viastakhov/argocd-kustomize-demo.git  kustomize/overlays/prod  HEAD
Enter fullscreen mode Exit fullscreen mode
$ argocd app resources nginx-prod
GROUP  KIND        NAMESPACE   NAME                   ORPHANED
       ConfigMap   production  nginx-conf-c6752d2t6f  No
       Namespace               production             No
       Service     production  nginx-svc              No
apps   Deployment  production  nginx-app              No
Enter fullscreen mode Exit fullscreen mode
$ argocd app get nginx-prod
Name:               argocd/nginx-prod
Project:            nginx
Server:             https://kubernetes.default.svc
Namespace:          prod
URL:                https://172.18.0.6/applications/nginx-prod
Source:
- Repo:             https://github.com/viastakhov/argocd-kustomize-demo.git
  Target:           HEAD
  Path:             kustomize/overlays/prod
SyncWindow:         Sync Allowed
Sync Policy:        Automated
Sync Status:        Synced to HEAD (d70b25e)
Health Status:      Healthy

GROUP  KIND        NAMESPACE   NAME                   STATUS   HEALTH   HOOK  MESSAGE
       Namespace   prod        production             Running  Synced         namespace/production created
       ConfigMap   production  nginx-conf-c6752d2t6f  Synced                  configmap/nginx-conf-c6752d2t6f created
       Service     production  nginx-svc              Synced   Healthy        service/nginx-svc created
apps   Deployment  production  nginx-app              Synced   Healthy        deployment.apps/nginx-app created
       Namespace               production             Synced
Enter fullscreen mode Exit fullscreen mode

Cleanup

$ argocd appset delete nginx
Are you sure you want to delete 'nginx' and all its Applications? [y/n] y
applicationset 'nginx' deleted

$ argocd appset list
NAME  PROJECT  SYNCPOLICY  CONDITIONS  REPO  PATH  TARGET

$ argocd app list
NAME  CLUSTER  NAMESPACE  PROJECT  STATUS  HEALTH  SYNCPOLICY  CONDITIONS  REPO  PATH  TARGET
Enter fullscreen mode Exit fullscreen mode

Bonus

Applications In Any Namespace

Since version 2.5, Argo CD supports managing Application resources in namespaces other than the namespace of the control plane (usually argocd), but this feature has to be explicitly enabled and configured accordingly.

# ./argo-cd/project.yaml 

apiVersion: argoproj.io/v1alpha1
kind: AppProject
metadata:
  name: nginx
spec:
  sourceNamespaces:
  - '*'
  sourceRepos:
  - '*'
  destinations:
  - namespace: '*'
    server: '*'
  clusterResourceWhitelist:
  - group: '*'
    kind: '*'
Enter fullscreen mode Exit fullscreen mode
$ argocd proj create -f ./argo-cd/project.yaml

Enter fullscreen mode Exit fullscreen mode
$ kubectl patch cm/argocd-cmd-params-cm -n argocd -p '{"data": {"application.namespaces": "'*'"}}'
configmap/argocd-cmd-params-cm patched

$ kubectl rollout restart -n argocd deployment argocd-server
deployment.apps/argocd-server restarted

$ kubectl rollout restart -n argocd statefulset argocd-application-controller
statefulset.apps/argocd-application-controller restarted
Enter fullscreen mode Exit fullscreen mode
$ kubectl patch clusterrole argocd-server --type='json' -p='[{"op": "replace", "path": "/rules/3/resources", "value": ["applications", "applicationsets", "appprojects"]}]'
clusterrole.rbac.authorization.k8s.io/argocd-server patched

$ kubectl patch clusterrole argocd-server --type='json' -p='[{"op": "replace", "path": "/rules/3/verbs", "value": ["get", "watch", "list", "create", "update", "delete", "patch"]}]'
clusterrole.rbac.authorization.k8s.io/argocd-server patched
Enter fullscreen mode Exit fullscreen mode
$ kubectl create ns development
namespace/development created

$ kubectl create ns production
namespace/production created
Enter fullscreen mode Exit fullscreen mode
$ argocd app create nginx \
  --repo https://github.com/viastakhov/argocd-kustomize-demo.git \
  --path kustomize/overlays/dev \
  --dest-server https://kubernetes.default.svc \
  --dest-namespace development \
  --sync-policy auto \
  --project nginx \
  --app-namespace development \
  --set-finalizer
application 'nginx' created

$ argocd app create nginx \
  --repo https://github.com/viastakhov/argocd-kustomize-demo.git \
  --path kustomize/overlays/prod \
  --dest-server https://kubernetes.default.svc \
  --dest-namespace production \
  --sync-policy auto \
  --project nginx \
  --app-namespace production \
  --set-finalizer
application 'nginx' created
Enter fullscreen mode Exit fullscreen mode
$ argocd app list
NAME               CLUSTER                         NAMESPACE    PROJECT  STATUS  HEALTH   SYNCPOLICY  CONDITIONS  REPO                                                     PATH                     TARGET
development/nginx  https://kubernetes.default.svc  development  nginx    Synced  Healthy  Auto        <none>      https://github.com/viastakhov/argocd-kustomize-demo.git  kustomize/overlays/dev
production/nginx   https://kubernetes.default.svc  production   nginx    Synced  Healthy  Auto        <none>      https://github.com/viastakhov/argocd-kustomize-demo.git  kustomize/overlays/prod

$ kubectl get applications -n development -o wide
NAME    SYNC STATUS   HEALTH STATUS   REVISION                                   PROJECT
nginx   Synced        Healthy         2550d54636eee62d843f4c56b27b7bdcf351d34a   nginx

$ kubectl get applications -n production -o wide
NAME    SYNC STATUS   HEALTH STATUS   REVISION                                   PROJECT
nginx   Synced        Healthy         2550d54636eee62d843f4c56b27b7bdcf351d34a   nginx
Enter fullscreen mode Exit fullscreen mode

Applications

$ kubectl delete ns development
namespace "development" deleted

$ kubectl delete ns production
namespace "production" deleted

$ argocd app list
NAME  CLUSTER  NAMESPACE  PROJECT  STATUS  HEALTH  SYNCPOLICY  CONDITIONS  REPO  PATH  TARGET
Enter fullscreen mode Exit fullscreen mode

Top comments (0)