This guide explains how to configure cluster-bootstrap when your Kubernetes manifests are located in a subdirectory of your Git repository (e.g., /k8s/, /infrastructure/, etc.).
By default, cluster-bootstrap expects the repository structure to be at the root:
repo/
├── apps/
├── components/
├── cli/
└── ...
If your structure is instead:
repo/
└── k8s/
├── apps/
├── components/
└── ...
ArgoCD will fail with errors like:
ComparisonError: Failed to load target state: failed to generate manifest for source 1 of 1:
rpc error: code = Unknown desc = failed to list refs: repository not found
This happens because ArgoCD tries to access paths like components/argocd when they're actually at k8s/components/argocd.
You need to configure three things to make it work:
Add the basePath field to tell ArgoCD where the components are located:
environment: dev
repo:
url: git@github.com:yourorg/yourrepo.git
targetRevision: main
basePath: "k8s" # 👈 Add this line with your subdirectory name
components:
argocd:
enabled: true
namespace: argocd
syncWave: "0"
syncOptions:
- ServerSideApply=true
# ... rest of your componentsWhen running CLI commands, use the --base-dir flag to point to your subdirectory:
./cluster-bootstrap-cli/cluster-bootstrap-cli --base-dir ./k8s bootstrap devThis tells the CLI where to find:
- Chart.yaml files
- Values files
- Secrets files
- Component definitions
For bootstrap, specify the full path to the apps directory:
./cluster-bootstrap-cli/cluster-bootstrap-cli --base-dir ./k8s bootstrap dev --app-path k8s/appsHere's a complete example for a repository with manifests in the k8s/ subdirectory:
my-repo/
├── README.md
├── src/ # Your application code
└── k8s/ # Kubernetes manifests
├── apps/
│ ├── Chart.yaml
│ ├── values.yaml
│ ├── values/
│ │ ├── dev.yaml
│ │ ├── staging.yaml
│ │ └── prod.yaml
│ └── templates/
│ └── application.yaml
├── components/
│ ├── argocd/
│ ├── vault/
│ └── ...
└── secrets.dev.enc.yaml
Edit k8s/apps/values.yaml:
environment: dev
repo:
url: git@github.com:myorg/my-repo.git
targetRevision: main
basePath: "k8s" # 👈 Add this
components:
argocd:
enabled: true
namespace: argocd
syncWave: "0"
syncOptions:
- ServerSideApply=true
vault:
enabled: true
namespace: vault
syncWave: "1"
external-secrets:
enabled: true
namespace: external-secrets
syncWave: "1"
syncOptions:
- ServerSideApply=true
# ... other components./cluster-bootstrap-cli/cluster-bootstrap-cli --base-dir ./k8s init --provider sopsThis creates k8s/secrets.dev.enc.yaml with the template.
# Edit the secrets file
sops k8s/secrets.dev.enc.yaml
# Add your Git repository SSH key and other secretsThe CLI automatically detects if you're running from a subdirectory and adjusts paths accordingly. You can use either method:
cd /path/to/my-repo
./k8s/cli/cluster-bootstrap --base-dir ./k8s bootstrap dev \
--app-path k8s/apps \
--wait-for-health -vcd /path/to/my-repo/k8s
./cluster-bootstrap-cli/cluster-bootstrap-cli bootstrap dev \
--app-path apps \
--wait-for-health -vcd /path/to/my-repo/k8s
./cluster-bootstrap-cli/cluster-bootstrap-cli bootstrap dev \
--app-path k8s/apps \
--wait-for-health -vAll three work! The CLI is smart enough to:
- Detect you're in a Git subdirectory (
k8s/) - Strip the prefix when needed for local validation
- Always pass the correct full path to ArgoCD
The CLI will automatically find:
./age-key.txt(or use--age-key-fileto specify)./secrets.dev.enc.yaml(or use--secrets-fileto specify)./apps/and./components/
After bootstrap, verify that ArgoCD applications have the correct paths:
# Check app-of-apps
kubectl get application app-of-apps -n argocd -o yaml | grep path:
# Should show: path: k8s/apps
# Check individual component applications
kubectl get applications -n argocd -o custom-columns=NAME:.metadata.name,PATH:.spec.source.path
# Should show paths like:
# argocd k8s/components/argocd
# vault k8s/components/vault
# external-secrets k8s/components/external-secretsThe basePath field is used in the Helm template (apps/templates/application.yaml) to construct the correct path:
# Without basePath (default):
path: components/{{ $name }}
# Result: components/argocd
# With basePath: "k8s":
path: {{ if $.Values.repo.basePath }}{{ $.Values.repo.basePath }}/{{ end }}components/{{ $name }}
# Result: k8s/components/argocdSymptom: ArgoCD applications show ComparisonError with "repository not found"
Solution:
- Verify
basePathis set inapps/values.yaml - Ensure you used
--base-dirflag when bootstrapping - Force refresh ArgoCD applications:
kubectl patch application app-of-apps -n argocd --type merge \ -p '{"metadata":{"annotations":{"argocd.argoproj.io/refresh":"hard"}}}'
Symptom: CLI can't find secrets file
Solution:
Use the --base-dir flag:
./cluster-bootstrap-cli/cluster-bootstrap-cli --base-dir ./k8s bootstrap devSymptom: app-path does not exist: stat <path>: no such file or directory
Solution:
The CLI now auto-detects Git subdirectories. Make sure you're using the correct relative path:
# ✅ From subdirectory - use relative path
cd /path/to/repo/k8s
./cluster-bootstrap-cli/cluster-bootstrap-cli bootstrap dev --app-path apps
# ✅ From root with --base-dir - use full path
cd /path/to/repo
./k8s/cli/cluster-bootstrap --base-dir ./k8s bootstrap dev --app-path k8s/appsHow auto-detection works:
- When you run from
k8s/and specify--app-path apps - The CLI detects you're in a Git subdirectory
- Automatically converts to
k8s/appsfor ArgoCD - Validates locally using
./apps
Symptom: Updated basePath but ArgoCD still uses old paths
Solution: The app-of-apps needs to be refreshed/synced:
# Option 1: Hard refresh via annotation
kubectl patch application app-of-apps -n argocd --type merge \
-p '{"metadata":{"annotations":{"argocd.argoproj.io/refresh":"hard"}}}'
# Option 2: Re-run bootstrap (idempotent)
./cluster-bootstrap-cli/cluster-bootstrap-cli --base-dir ./k8s bootstrap dev --app-path k8s/apps
# Option 3: Use ArgoCD UI
# Navigate to app-of-apps → Click "Refresh" → Select "Hard Refresh"To use cluster-bootstrap with manifests in a subdirectory:
- ✅ Add
repo.basePath: "subdirectory"toapps/values.yaml - ✅ Run from anywhere - the CLI auto-detects your location
- ✅ Use
--app-pathrelative to where you're running - ✅ Verify paths in ArgoCD applications after deployment
# ✅ Option 1: From repository root with --base-dir
cd /path/to/repo
./k8s/cli/cluster-bootstrap --base-dir ./k8s bootstrap dev --app-path k8s/apps
# ✅ Option 2: From subdirectory (auto-detected)
cd /path/to/repo/k8s
./cluster-bootstrap-cli/cluster-bootstrap-cli bootstrap dev --app-path appsThe CLI is smart enough to detect your location:
- Finds Git root: Walks up directories looking for
.git - Calculates relative path: Determines your position in the repo (e.g.,
k8s/) - Auto-adjusts paths: Converts
apps→k8s/appsfor ArgoCD automatically - Validates locally: Checks files exist relative to your current location
No more path confusion! Just use paths relative to where you are.
This configuration ensures ArgoCD can correctly locate all components in your repository subdirectory.