Deploy applications using Helm charts with intelligent validation and rollback
Deploy applications to Kubernetes using Helm charts with comprehensive validation, health checks, and automatic rollback on failure. Use this when you need to safely deploy or upgrade services with pre-flight checks and post-deployment verification.
/plugin marketplace add kcns008/cluster-code/plugin install kcns008-gitops-plugins-gitops@kcns008/cluster-codeDeploy applications to Kubernetes using Helm charts with comprehensive validation, health checks, and intelligent rollback capabilities.
You are a Helm deployment specialist focused on:
Verify Helm installation:
helm version --short || {
echo "❌ Helm not installed"
echo "Install: https://helm.sh/docs/intro/install/"
exit 1
}
Verify kubectl connectivity:
kubectl cluster-info || {
echo "❌ Not connected to a Kubernetes cluster"
exit 1
}
Check namespace:
if ! kubectl get namespace $NAMESPACE &>/dev/null; then
if [[ "$CREATE_NAMESPACE" == "true" ]]; then
kubectl create namespace $NAMESPACE
echo "✅ Created namespace: $NAMESPACE"
else
echo "❌ Namespace '$NAMESPACE' does not exist"
echo "Use --create-namespace to create it automatically"
exit 1
fi
fi
Determine chart type:
Local chart (path starts with . or /):
if [[ -f "$CHART/Chart.yaml" ]]; then
CHART_TYPE="local"
CHART_PATH="$CHART"
else
echo "❌ Chart.yaml not found in $CHART"
exit 1
fi
Repository chart (format: repo/chart):
if [[ "$CHART" == *"/"* ]]; then
CHART_TYPE="repository"
REPO_NAME="${CHART%%/*}"
CHART_NAME="${CHART##*/}"
# Update repository
helm repo update $REPO_NAME 2>/dev/null || {
echo "⚠️ Repository '$REPO_NAME' not found"
echo "Add repository first: helm repo add <name> <url>"
exit 1
}
fi
Chart name only (search in added repos):
if [[ "$CHART" != *"/"* && ! -d "$CHART" ]]; then
CHART_TYPE="search"
# Search for chart in repositories
SEARCH_RESULTS=$(helm search repo $CHART --output json)
if [[ $(echo "$SEARCH_RESULTS" | jq 'length') -eq 0 ]]; then
echo "❌ Chart '$CHART' not found in any repository"
echo "Search all repositories: helm search repo $CHART"
exit 1
fi
# Use first result
CHART_FULL=$(echo "$SEARCH_RESULTS" | jq -r '.[0].name')
echo "📦 Found chart: $CHART_FULL"
fi
Display chart information:
helm show chart $CHART_PATH 2>/dev/null || helm show chart $CHART_FULL
# Extract key information
CHART_VERSION=$(helm show chart $CHART | yq eval '.version' -)
APP_VERSION=$(helm show chart $CHART | yq eval '.appVersion' -)
DESCRIPTION=$(helm show chart $CHART | yq eval '.description' -)
echo ""
echo "📋 Chart Details:"
echo " Name: $CHART"
echo " Version: $CHART_VERSION"
echo " App Version: $APP_VERSION"
echo " Description: $DESCRIPTION"
Load values files:
VALUES_ARGS=""
if [[ -n "$VALUES_FILE" ]]; then
if [[ ! -f "$VALUES_FILE" ]]; then
echo "❌ Values file not found: $VALUES_FILE"
exit 1
fi
VALUES_ARGS="-f $VALUES_FILE"
echo "📄 Using values file: $VALUES_FILE"
fi
Process --set arguments:
SET_ARGS=""
if [[ ${#SET_VALUES[@]} -gt 0 ]]; then
for kv in "${SET_VALUES[@]}"; do
SET_ARGS="$SET_ARGS --set $kv"
done
echo "⚙️ Overriding values: ${SET_VALUES[*]}"
fi
Show merged values (if requested):
if [[ "$SHOW_VALUES" == "true" ]]; then
echo ""
echo "📋 Final Values (after merging):"
helm template $RELEASE $CHART $VALUES_ARGS $SET_ARGS --namespace $NAMESPACE | \
helm get values $RELEASE --all 2>/dev/null || \
helm show values $CHART
fi
Template validation (dry-run):
echo ""
echo "🔍 Validating chart templates..."
TEMPLATE_OUTPUT=$(helm template $RELEASE $CHART \
$VALUES_ARGS $SET_ARGS \
--namespace $NAMESPACE \
--validate 2>&1)
if [[ $? -ne 0 ]]; then
echo "❌ Template validation failed:"
echo "$TEMPLATE_OUTPUT"
exit 1
fi
echo "✅ Chart templates are valid"
Resource validation:
# Count resources to be created
RESOURCE_COUNT=$(echo "$TEMPLATE_OUTPUT" | grep -c "^kind:")
echo "📊 Resources to be deployed: $RESOURCE_COUNT"
echo ""
echo "Resource Types:"
echo "$TEMPLATE_OUTPUT" | grep "^kind:" | sort | uniq -c | \
awk '{printf " - %s: %d\n", $2, $1}'
Check for existing release:
if helm list -n $NAMESPACE | grep -q "^$RELEASE"; then
EXISTING_VERSION=$(helm list -n $NAMESPACE -o json | \
jq -r ".[] | select(.name==\"$RELEASE\") | .chart")
echo ""
echo "⚠️ Release '$RELEASE' already exists (version: $EXISTING_VERSION)"
echo ""
read -p "Upgrade existing release? [y/N]: " UPGRADE
if [[ ! "$UPGRADE" =~ ^[Yy]$ ]]; then
echo "❌ Deployment cancelled"
echo "Use helm-upgrade command to upgrade existing releases"
exit 0
fi
OPERATION="upgrade"
else
OPERATION="install"
fi
Execute Helm deployment:
For new installation:
if [[ "$DRY_RUN" == "true" ]]; then
echo "🧪 DRY RUN MODE - No changes will be applied"
echo ""
helm install $RELEASE $CHART \
--namespace $NAMESPACE \
$VALUES_ARGS $SET_ARGS \
--dry-run --debug
else
echo "🚀 Deploying release '$RELEASE'..."
echo ""
helm install $RELEASE $CHART \
--namespace $NAMESPACE \
$VALUES_ARGS $SET_ARGS \
${CREATE_NAMESPACE:+--create-namespace} \
${WAIT:+--wait --timeout $TIMEOUT} \
--output json | tee /tmp/helm-install-$RELEASE.json
if [[ $? -eq 0 ]]; then
echo ""
echo "✅ Release '$RELEASE' deployed successfully!"
else
echo ""
echo "❌ Deployment failed"
exit 1
fi
fi
For upgrade:
if [[ "$DRY_RUN" == "true" ]]; then
echo "🧪 DRY RUN MODE - No changes will be applied"
echo ""
helm upgrade $RELEASE $CHART \
--namespace $NAMESPACE \
$VALUES_ARGS $SET_ARGS \
--dry-run --debug
else
echo "⬆️ Upgrading release '$RELEASE'..."
echo ""
helm upgrade $RELEASE $CHART \
--namespace $NAMESPACE \
$VALUES_ARGS $SET_ARGS \
${WAIT:+--wait --timeout $TIMEOUT} \
--output json | tee /tmp/helm-upgrade-$RELEASE.json
if [[ $? -eq 0 ]]; then
echo ""
echo "✅ Release '$RELEASE' upgraded successfully!"
else
echo ""
echo "❌ Upgrade failed"
echo "Rollback: helm rollback $RELEASE -n $NAMESPACE"
exit 1
fi
fi
Show release status:
echo ""
echo "📊 Release Status:"
helm status $RELEASE -n $NAMESPACE
Check deployed resources:
echo ""
echo "🔍 Deployed Resources:"
# Get all resources from release
helm get manifest $RELEASE -n $NAMESPACE | \
kubectl get -f - --show-kind --show-labels -o wide 2>/dev/null || \
echo "⚠️ Some resources may not be ready yet"
Health checks:
echo ""
echo "🏥 Health Checks:"
# Check pods
PODS=$(kubectl get pods -n $NAMESPACE -l "app.kubernetes.io/instance=$RELEASE" \
--no-headers 2>/dev/null)
if [[ -n "$PODS" ]]; then
TOTAL_PODS=$(echo "$PODS" | wc -l)
READY_PODS=$(echo "$PODS" | grep "Running" | grep -E "([0-9]+)/\1" | wc -l)
echo " Pods: $READY_PODS/$TOTAL_PODS ready"
if [[ $READY_PODS -lt $TOTAL_PODS ]]; then
echo ""
echo "⚠️ Not all pods are ready:"
echo "$PODS" | while read POD STATUS READY AGE; do
if [[ "$STATUS" != "Running" ]] || [[ ! "$READY" =~ ([0-9]+)/\1 ]]; then
echo " - $POD: $STATUS (Ready: $READY)"
fi
done
fi
fi
# Check services
SERVICES=$(kubectl get services -n $NAMESPACE -l "app.kubernetes.io/instance=$RELEASE" \
--no-headers 2>/dev/null)
if [[ -n "$SERVICES" ]]; then
SERVICE_COUNT=$(echo "$SERVICES" | wc -l)
echo " Services: $SERVICE_COUNT deployed"
fi
# Check ingresses/routes
INGRESSES=$(kubectl get ingress -n $NAMESPACE -l "app.kubernetes.io/instance=$RELEASE" \
--no-headers 2>/dev/null)
if [[ -n "$INGRESSES" ]]; then
INGRESS_COUNT=$(echo "$INGRESSES" | wc -l)
echo " Ingresses: $INGRESS_COUNT deployed"
echo ""
echo "🌐 External Access:"
echo "$INGRESSES" | while read NAME CLASS HOSTS ADDRESS PORTS AGE; do
echo " - https://$HOSTS"
done
fi
Show notes:
echo ""
echo "📝 Release Notes:"
helm get notes $RELEASE -n $NAMESPACE
Provide monitoring commands:
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
📋 Next Steps
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Monitor deployment:
kubectl get pods -n <namespace> -l app.kubernetes.io/instance=<release> --watch
View logs:
kubectl logs -n <namespace> -l app.kubernetes.io/instance=<release> --tail=100 -f
Check release history:
helm history <release> -n <namespace>
Upgrade release:
helm-upgrade --release <release> --namespace <namespace>
Rollback if needed:
helm rollback <release> -n <namespace>
Uninstall release:
helm uninstall <release> -n <namespace>
Set up monitoring (if monitoring enabled):
# Create ServiceMonitor for Prometheus (if Prometheus Operator is installed)
if kubectl get crd servicemonitors.monitoring.coreos.com &>/dev/null; then
echo ""
echo "💡 Prometheus Operator detected. You can create a ServiceMonitor:"
cat <<EOF
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
name: $RELEASE
namespace: $NAMESPACE
spec:
selector:
matchLabels:
app.kubernetes.io/instance: $RELEASE
endpoints:
- port: metrics
interval: 30s
EOF
fi
Chart not found:
❌ Chart '<chart>' not found
Search for charts:
helm search repo <keyword>
helm search hub <keyword>
Add a repository:
helm repo add bitnami https://charts.bitnami.com/bitnami
helm repo add stable https://charts.helm.sh/stable
Template rendering errors:
❌ Failed to render chart templates
Common causes:
- Invalid values in values.yaml
- Missing required values
- Syntax errors in templates
Debug:
helm template <release> <chart> --debug
helm lint <chart>
Deployment timeout:
⏱️ Deployment timed out after <timeout>
Check pod status:
kubectl get pods -n <namespace> -l app.kubernetes.io/instance=<release>
View pod logs:
kubectl logs -n <namespace> <pod-name>
Increase timeout:
helm-deploy --chart <chart> --release <release> --timeout 10m
Resource conflicts:
❌ Resource already exists
This usually happens when:
- A previous installation wasn't fully removed
- Resources are managed by multiple Helm releases
Solutions:
1. Delete conflicting resources manually
2. Use different release name
3. Change namespace
Version Control:
Values Management:
Security:
Deployment Strategy: