Post Install Manifests
Table of contents
- Overview
- Configuration
- Configuration Format
- Examples
- Manifest Requirements
- Execution Order
- Important Notes
- Troubleshooting
- Wrong
- Correct
Overview
BeKind can automatically apply Kubernetes YAML manifests after the cluster is created and Helm charts are installed. This is useful for:
- Deploying applications
- Creating custom resources
- Setting up RBAC policies
- Configuring cluster-specific settings
Configuration
Add manifest paths under the postInstallManifests key:
postInstallManifests:
- "file:///home/user/k8s/app.yaml"
- "file:///home/user/k8s/service.yaml"
- "file:///home/user/k8s/ingress.yaml"
Configuration Format
Supported URL Formats
BeKind supports multiple ways to specify manifest locations:
- Local files:
file://URLs with absolute paths - HTTP(S) URLs: Direct links to manifests served as
text/plain
You can mix and match both types in the same configuration.
File URLs
Local files must be specified as file:// URLs with absolute paths:
postInstallManifests:
- "file:///home/user/manifests/deployment.yaml"
- "file:///home/user/manifests/service.yaml"
Relative paths are not supported. Always use absolute paths with the file:// prefix.
Linux/macOS:
postInstallManifests:
- "file:///home/username/k8s/app.yaml"
- "file:///Users/username/projects/k8s/service.yaml"
Windows:
postInstallManifests:
- "file:///C:/Users/username/k8s/app.yaml"
HTTP(S) URLs
Manifests can be fetched from remote URLs:
postInstallManifests:
- "https://yoursite.example.org/manifests/deployment.yaml"
- "http://internal-server.local/configs/service.yaml"
Remote manifests must be served with the text/plain or application/yaml content type.
Mixed Configuration
You can combine local files and remote URLs:
postInstallManifests:
- "file:///home/user/local/namespace.yaml"
- "https://example.com/shared/rbac.yaml"
- "file:///home/user/local/deployment.yaml"
- "https://example.com/configs/service.yaml"
Examples
Single Application
postInstallManifests:
- "file:///home/user/apps/my-app/deployment.yaml"
- "file:///home/user/apps/my-app/service.yaml"
- "file:///home/user/apps/my-app/configmap.yaml"
Multiple Applications
postInstallManifests:
- "file:///home/user/apps/frontend/all.yaml"
- "file:///home/user/apps/backend/all.yaml"
- "file:///home/user/apps/database/all.yaml"
- "file:///home/user/networking/ingress.yaml"
Remote Manifests
postInstallManifests:
- "https://raw.githubusercontent.com/user/repo/main/manifests/app.yaml"
- "https://gist.githubusercontent.com/user/abc123/raw/deployment.yaml"
- "https://yoursite.example.org/configs/service.yaml"
Mixed Local and Remote
postInstallManifests:
- "file:///home/user/k8s/namespace.yaml"
- "https://example.com/configs/base-config.yaml"
- "file:///home/user/k8s/secrets.yaml"
- "https://example.com/configs/monitoring.yaml"
With Argo CD Applications
helmCharts:
- url: "https://argoproj.github.io/argo-helm"
repo: "argo"
chart: "argo-cd"
release: "argocd"
namespace: "argocd"
wait: true
postInstallManifests:
- "file:///home/user/argocd/app-of-apps.yaml"
- "file:///home/user/argocd/projects.yaml"
Manifest Requirements
YAML Format
Manifests must be valid Kubernetes YAML files. They can contain:
- Single resources
- Multiple resources separated by
--- - Any valid Kubernetes resource type
Single resource:
apiVersion: v1
kind: ConfigMap
metadata:
name: my-config
namespace: default
data:
key: value
Multiple resources:
apiVersion: v1
kind: Namespace
metadata:
name: my-app
---
apiVersion: v1
kind: ConfigMap
metadata:
name: my-config
namespace: my-app
data:
key: value
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-app
namespace: my-app
spec:
replicas: 2
selector:
matchLabels:
app: my-app
template:
metadata:
labels:
app: my-app
spec:
containers:
- name: app
image: my-app:latest
Local File Accessibility
Ensure BeKind can read the manifest files:
# Check file exists
ls -l /home/user/k8s/app.yaml
# Check file permissions
chmod 644 /home/user/k8s/app.yaml
Remote URL Accessibility
For HTTP(S) URLs, ensure:
- The URL is accessible from where BeKind is running
- The server returns
text/plainorapplication/yamlcontent type - No authentication is required, or use a URL with embedded credentials (not recommended for production)
- HTTPS certificates are valid (or use HTTP for internal/trusted networks)
Test URL accessibility:
# Test with curl
curl -I https://example.com/manifests/app.yaml
# Should return 200 OK with text/plain or application/yaml content type
Execution Order
Manifests are applied in the order they appear in your configuration:
postInstallManifests:
- "file:///path/to/namespace.yaml" # Applied first
- "file:///path/to/configmap.yaml" # Applied second
- "file:///path/to/deployment.yaml" # Applied third
If resources have dependencies, list them in the correct order. For example, create namespaces before resources that use them.
Full Execution Flow
- KIND cluster is created
- Docker images are loaded (if configured)
- Helm charts are installed (if configured)
- Post-install manifests are applied ← You are here
- Post-install actions are performed (if configured)
Important Notes
Error Handling
“Garbage in/garbage out” - BeKind applies manifests directly using kubectl apply. Any errors come from the Kubernetes API server. There is no validation before application.
If a manifest fails to apply:
- BeKind will display the error
- Subsequent manifests will still be attempted
- The cluster will be in a partial state
Validation Before Use
Always validate your manifests before using them with BeKind:
# Dry-run validation
kubectl apply -f manifest.yaml --dry-run=client
# Server-side validation
kubectl apply -f manifest.yaml --dry-run=server
Supported Formats
Currently, only YAML files are supported. JSON manifests are not supported.
Troubleshooting
File Not Found
If BeKind can’t find a manifest:
For local files:
- Check the path is absolute: ```yaml
Wrong
postInstallManifests:
- ”./manifests/app.yaml”
Correct
postInstallManifests:
- “file:///home/user/project/manifests/app.yaml” ```
- Verify the file exists:
ls -l /home/user/project/manifests/app.yaml - Check file permissions:
chmod 644 /home/user/project/manifests/app.yaml
For remote URLs:
- Test URL accessibility:
curl -v https://example.com/manifests/app.yaml - Check content type:
curl -I https://example.com/manifests/app.yaml # Should see: Content-Type: text/plain or application/yaml - Verify network connectivity:
- Can you reach the server from your machine?
- Are there firewall rules blocking access?
- Is the URL correct (check for typos)?
Application Failures
If kubectl apply fails:
- Validate YAML syntax:
yamllint manifest.yaml - Check Kubernetes API version:
kubectl api-versions - Verify resource definitions:
kubectl explain Deployment.spec - Test manually:
kubectl apply -f manifest.yaml
Namespace Issues
If resources fail because namespaces don’t exist:
- Create namespace first: ```yaml postInstallManifests:
- “file:///path/to/namespace.yaml”
- “file:///path/to/app.yaml” ```
- Or include namespace in manifest:
apiVersion: v1 kind: Namespace metadata: name: my-app --- apiVersion: v1 kind: ConfigMap metadata: name: config namespace: my-app
Dependency Ordering
If resources depend on each other:
- List dependencies first: ```yaml postInstallManifests:
- “file:///path/to/crd.yaml” # Custom Resource Definition first
- “file:///path/to/resource.yaml” # Custom Resource second ```
- Use
waitwith Helm charts: If manifests depend on Helm-installed resources: ```yaml helmCharts:- url: “…” wait: true # Wait for chart to be ready
postInstallManifests:
- “file:///path/to/dependent-resource.yaml” ```
Best Practices
Use Remote Manifests for Shared Configurations
Store common manifests in a central location:
postInstallManifests:
# Shared base configuration
- "https://config.company.com/k8s/base/namespace.yaml"
- "https://config.company.com/k8s/base/rbac.yaml"
# Local overrides
- "file:///home/user/local/secrets.yaml"
- "file:///home/user/local/app.yaml"
Organize by Environment
.bekind/
├── profiles/
│ ├── dev/
│ │ ├── config.yaml
│ │ └── manifests/
│ │ ├── namespace.yaml
│ │ └── apps.yaml
│ └── staging/
│ ├── config.yaml
│ └── manifests/
│ └── apps.yaml
Reference in config:
postInstallManifests:
- "file://${HOME}/.bekind/profiles/dev/manifests/namespace.yaml"
- "file://${HOME}/.bekind/profiles/dev/manifests/apps.yaml"
Or use remote URLs for consistency:
postInstallManifests:
- "https://github.com/company/k8s-configs/raw/main/dev/namespace.yaml"
- "https://github.com/company/k8s-configs/raw/main/dev/apps.yaml"
Combine Related Resources
Group related resources in single files:
# app.yaml - everything for one application
apiVersion: v1
kind: ConfigMap
metadata:
name: app-config
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: app
---
apiVersion: v1
kind: Service
metadata:
name: app
Use with Post-Install Actions
Combine manifests with actions for complete setup:
postInstallManifests:
- "file:///home/user/k8s/app.yaml"
postInstallActions:
- action: restart
kind: Deployment
name: app
namespace: default