ArgoCD + CloudTaser Quickstart¶
Deploy CloudTaser into a Kubernetes cluster managed by ArgoCD in under 10 minutes. This guide covers deploying the operator via an ArgoCD Application, annotating workloads for secret injection, and handling common ArgoCD-specific considerations.
For the full integration reference including migration paths and comparison tables, see ArgoCD and GitOps Integration.
Prerequisites¶
- An ArgoCD instance managing your target cluster
- An EU-hosted Vault/OpenBao instance with Kubernetes auth configured
kubectlandargocdCLI tools
Step 1: Deploy CloudTaser via ArgoCD Application¶
Create an ArgoCD Application that deploys CloudTaser from its Helm chart.
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: cloudtaser
namespace: argocd
spec:
project: default
source:
chart: cloudtaser
repoURL: https://charts.cloudtaser.io
targetRevision: "0.5.14"
helm:
values: |
namespace: cloudtaser-system
operator:
ha: true
replicaCount: 2
leaderElect: true
vaultAddress: "https://vault.eu.example.com"
image:
repository: europe-west4-docker.pkg.dev/skipopsmain/cloudtaser/cloudtaser-operator
tag: "v0.5.14-amd64"
ebpf:
enabled: true
enforceMode: true
destination:
server: https://kubernetes.default.svc
namespace: cloudtaser-system
syncPolicy:
automated:
prune: true
selfHeal: true
syncOptions:
- CreateNamespace=true
Apply it:
Or via the ArgoCD CLI:
argocd app create cloudtaser \
--repo https://charts.cloudtaser.io \
--helm-chart cloudtaser \
--revision 0.5.14 \
--dest-server https://kubernetes.default.svc \
--dest-namespace cloudtaser-system \
--sync-policy automated \
--auto-prune \
--self-heal \
--sync-option CreateNamespace=true
Pin the chart version
Always use a specific targetRevision in production instead of "*" to prevent unexpected upgrades during automatic syncs.
Step 2: Verify the Operator Is Running¶
Wait for ArgoCD to sync the application:
Expected status: Synced and Healthy.
Verify the operator pods:
Expected: pods in Running state.
Verify the webhook is registered:
Step 3: Annotate a Workload¶
Add CloudTaser annotations to your application's pod template. This is the only change needed in your Git repository -- no secret values, no encrypted files.
apiVersion: apps/v1
kind: Deployment
metadata:
name: myapp
spec:
replicas: 1
selector:
matchLabels:
app: myapp
template:
metadata:
annotations:
cloudtaser.io/inject: "true"
cloudtaser.io/vault-address: "https://vault.eu.example.com"
cloudtaser.io/vault-role: "cloudtaser"
cloudtaser.io/secret-paths: "secret/data/myapp/config"
cloudtaser.io/env-map: "db_password=PGPASSWORD,api_key=API_KEY"
spec:
containers:
- name: myapp
image: myorg/myapp:v1.2.3
Commit and push. ArgoCD syncs the manifest, Kubernetes creates the pod, and the CloudTaser webhook intercepts it to inject the wrapper.
Nothing secret in Git
The annotations contain only references to vault paths and environment variable names. No secret values are stored in Git, etcd, or Kubernetes Secrets.
Step 4: Verify Injection¶
After ArgoCD syncs the workload:
# Check that the wrapper is running as PID 1
kubectl exec myapp-<pod-id> -- cat /proc/1/cmdline | tr '\0' ' '
Expected output starts with /cloudtaser/wrapper.
# Check wrapper logs for successful secret fetch
kubectl logs myapp-<pod-id> -c myapp 2>&1 | grep "secrets loaded"
Expected: "msg":"secrets loaded, starting child process","secret_count":2.
Using CloudTaserConfig for Shared Configuration¶
Instead of repeating vault address and role in every Deployment, create a CloudTaserConfig CR:
apiVersion: cloudtaser.io/v1alpha1
kind: CloudTaserConfig
metadata:
name: production
namespace: default
spec:
vaultAddress: "https://vault.eu.example.com"
vaultRole: "cloudtaser"
rotation: restart
Then reference it from workloads:
annotations:
cloudtaser.io/inject: "true"
cloudtaser.io/config: "production"
cloudtaser.io/secret-paths: "secret/data/myapp/config"
cloudtaser.io/env-map: "db_password=PGPASSWORD"
Sync waves
Deploy CloudTaserConfig resources before the workloads that reference them. Use ArgoCD sync waves:
Helm Values for ArgoCD¶
Key Helm values relevant to ArgoCD deployments.
The unified cloudtaser chart exposes these value groups:
| Prefix | Description |
|---|---|
operator.* |
Operator deployment (replicas, image, webhook config) |
wrapper.* |
Default wrapper sidecar settings |
ebpf.* |
eBPF daemonset (enable/disable, enforce mode) |
s3proxy.* |
S3 encryption proxy defaults |
networkPolicy.* |
Auto-generated NetworkPolicy for vault egress |
pdb.* |
PodDisruptionBudget settings |
See the full Helm Values Reference for all available values.
Example: Production HA configuration¶
operator:
ha: true
replicaCount: 3
leaderElect: true
vaultAddress: "https://vault.eu.example.com"
webhook:
failurePolicy: Fail
timeoutSeconds: 10
resources:
requests:
cpu: 100m
memory: 128Mi
limits:
cpu: 500m
memory: 256Mi
ebpf:
enabled: true
enforceMode: true
reactiveKill: true
networkPolicy:
enabled: true
vaultCIDR: "10.0.0.0/8"
vaultPort: 8200
pdb:
enabled: true
operator:
minAvailable: 1
ArgoCD-Specific Considerations¶
Resource diff noise from injected containers¶
When CloudTaser injects the wrapper, ArgoCD sees a diff between the desired state (no wrapper) and the live state (wrapper injected by webhook). To prevent ArgoCD from showing these diffs as out-of-sync:
data:
resource.customizations.ignoreDifferences.all: |
jsonPointers:
- /spec/template/spec/initContainers
- /spec/template/spec/containers/0/command
- /spec/template/spec/containers/0/args
- /spec/template/spec/volumes
Webhook timeout during sync¶
If the operator is being deployed in the same sync as workloads, the webhook may not be ready when ArgoCD creates workload pods. Use sync waves to ensure the operator is deployed first:
App of Apps pattern¶
For multi-cluster deployments, use the ArgoCD App of Apps pattern with cluster-specific values:
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: cloudtaser
namespace: argocd
spec:
project: default
source:
chart: cloudtaser
repoURL: https://charts.cloudtaser.io
targetRevision: "0.5.14"
helm:
valueFiles:
- values-base.yaml
- values-{{ .Values.cluster }}.yaml
destination:
server: '{{ .Values.clusterServer }}'
namespace: cloudtaser-system
Troubleshooting¶
| Symptom | Cause | Fix |
|---|---|---|
ArgoCD shows Degraded for operator |
Webhook cert not yet generated | Wait 30 seconds for cert generation, then check operator logs |
| Pods fail to create after sync | Webhook not ready (failurePolicy: Fail) |
Use sync waves to deploy operator before workloads |
| ArgoCD shows out-of-sync on Deployments | Injected containers differ from desired state | Add ignoreDifferences to ArgoCD ConfigMap (see above) |
| Sync succeeds but secrets missing | Vault auth not configured for this cluster | Run cloudtaser validate --vault-address <url> |
For the full troubleshooting guide, see Troubleshooting Decision Trees.