Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

🏠 Back to Blog

Interacting with ArgoCD

Ways to interact with ArgoCD:

  • UI
  • CLI
  • API
  • Declarative (configmaps/secrets applied straight to the cluster)

UI: Exposing it with an Ingress

  • kubectl port-forward is fine for testing, not for long term use
  • Ingress exposes services outside the cluster. Needs an Ingress Controller to map requests to the backend service
  • Using NGINX ingress controller on a kind cluster

kind cluster with port mappings

cat <<EOF | kind create cluster --config=-
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
nodes:
- role: control-plane
  kubeadmConfigPatches:
  - |
    kind: InitConfiguration
    nodeRegistration:
      kubeletExtraArgs:
        node-labels: "ingress-ready=true"
  extraPortMappings:
  - containerPort: 80
    hostPort: 80
    protocol: TCP
  - containerPort: 443
    hostPort: 443
    protocol: TCP
EOF
  • Can also put this in a file and use --config <file>
  • ingress-ready=true label + port mappings forward 80/443 from the host to the kind node

Deploy NGINX

kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/main/deploy/static/provider/kind/deploy.yaml

kubectl wait --namespace ingress-nginx \
  --for=condition=ready pod \
  --selector=app.kubernetes.io/component=controller \
  --timeout=90s

Verify:

curl http://127.0.0.1
  • A 404 Not Found from nginx is good. No Ingress exists yet, but the controller responded

Hostname

  • NGINX is an L7 load balancer. It routes based on the Host header, matches against Ingress resources
  • Need a hostname for ArgoCD that isn’t in public DNS. Two options:
    • edit /etc/hosts
    • use a wildcard DNS service like nip.io (adds an external dependency)
  • Using /etc/hosts:
127.0.0.1 argocd.upandrunning.local

Helm values

values-argocd-ingress.yaml:

---
server:
  ingress:
    enabled: true
    hostname: argocd.upandrunning.local
    ingressClassName: nginx
  extraArgs:
    - --insecure
helm upgrade -i argo-cd argo/argo-cd --namespace argocd --create-namespace -f values-argocd-ingress.yaml
kubectl get ingress -n argocd
  • Browse to http://argocd.upandrunning.local
  • https:// works too, but the cert warning is now for the ingress controller. The Helm chart terminates TLS at the ingress, not at ArgoCD
  • --insecure makes argocd-server serve plain http so the ingress can handle TLS
  • Same admin login via argocd-initial-admin-secret

UI: Overview

  • Landing page = list of Applications and their status
    • An Application is a source of GitOps content that targets a destination environment. Main focus for end users
    • UI can create/manage/sync them
  • Settings page = managing the ArgoCD server itself
SettingDescription
Repositoriesremote locations with resources that get turned into k8s manifests
Certificatestransport mechanisms for secure connectivity to remote repos
GnuPG keyskey mgmt to verify source control content
Clustersk8s environments that content gets applied to
Projectslogical groups of Applications w/ common config and permissions
Accountslocal accounts stored in ArgoCD
Appearancelook and feel of the UI
  • User Info page shows the current user’s identity details. Useful when setting up RBAC
  • Some properties are read only or can’t be managed in the UI at all. That’s when to use the CLI

CLI

  • argocd. Uses the API, same as the UI. More capabilities than the UI
  • Prebuilt binaries for most OSes. Also a container image with it included
  • Most commands need a connection to ArgoCD first:
argocd login --insecure --grpc-web argocd.upandrunning.local
  • --grpc-web uses the gRPC-web protocol so it can go through the ingress controller. Native gRPC needs extra config
  • Login writes a config file to $HOMEDIR/.config/argocd/config (user, k8s context, connection data)
    • $HOMEDIR resolves from ARGOCD_CONFIG_DIR, HOME, or XDG_CONFIG_HOME, whichever is found first

Change the admin password

  • Do this first. Secrets are only base64 encoded, not encrypted, so anyone who can read the secret has the default password
  • Can’t be done in the UI
argocd account update-password
argocd logout <context>   # list contexts with: argocd context
argocd login ...          # confirm the new password works

API

  • UI and CLI both use the REST API. You can call it directly with no limits from what the UI/CLI expose
  • ArgoCD ships an OpenAPI (Swagger) spec:
    • /swagger.json: the raw spec (huge)
    • /swagger-ui: visual browser for the API
  • Flow: get a session token, then call endpoints with it
curl -k https://argocd.upandrunning.local/api/v1/session -d '{"username":"admin","password":"<PASSWORD>"}'
# {"token":"<TOKEN>"}
  • -k disables TLS validation (self signed cert)
curl -k -H "Authorization: Bearer <TOKEN>" https://argocd.upandrunning.local/api/v1/settings
  • /api/v1/settings returns a lot more than the CLI or UI do. Handy during initial config
    • ex: appLabelKey, resourceOverrides, kustomizeOptions, passwordPattern, controllerNamespace
  • Endpoints can be updated, not just queried

Declarative

  • Don’t need the UI, CLI or API. Apply the config directly to the cluster
  • ArgoCD watches its CRs (Application, AppProject) and the ConfigMaps/Secrets that configure the platform
  • Everything lives in the namespace ArgoCD is deployed in
  • The settings API endpoint above just reads argocd-cm

ConfigMaps (well known names)

NameDescription
argocd-cmgeneral ArgoCD config
argocd-cmd-paramsenv var style configs
argocd-rbac-cmRBAC config
argocd-ssh-known-hosts-cmSSH known-host data

Secrets

  • No standard names. Identified by the label argocd.argoproj.io/secret-type
  • This lets you have one Secret per repo/cluster and ArgoCD correlates them by label
Label valueDescription
clusterdefinition, config and credentials for a remote cluster
repositoryconsolidated config + credentials for a remote repo
repo-configconfig for a remote repo (not widely used)
repo-credscredentials for talking to a remote repo