Environment Operations Runbook
This runbook provides step-by-step procedures for common environment operations including creation, troubleshooting, and cleanup.
Prerequisites
-
Access to Environment Manager Web UI (
http://localhost:8080) -
ArgoCD access for manual interventions
-
kubectl access for emergency operations
Creating a New Environment
Via Environment Manager (Recommended)
Create Partial Environment
-
Navigate to Environment Manager Web UI
-
Click "Create" tab
-
Fill in:
-
Environment Name: lowercase letters, numbers, hyphens only (e.g.,
feature-user-123) -
Environment Type: Partial
-
Parent Environment: Select database parent (dev-mysql, dev-oracle, latest-mysql, latest-oracle)
-
-
Select services to deploy
-
For each service, choose:
-
Harbor: Select existing tag from dropdown
-
Branch: Enter Git branch name (will trigger build)
-
-
Click "Create Environment"
-
Wait for build completion (if branch selected) - 5-10 minutes per service
-
Environment deploys automatically via ArgoCD
Create Full Environment
-
Navigate to Environment Manager Web UI
-
Click "Create" tab
-
Fill in:
-
Environment Name: lowercase letters, numbers, hyphens only
-
Environment Type: Full
-
Database Type: MySQL or Oracle
-
-
All services are auto-selected (cannot uncheck)
-
Configure image source for each service
-
Click "Create Environment"
-
Full deployment takes 15-30 minutes (includes database initialization)
Deleting an Environment
Via Environment Manager
-
Navigate to "List" tab
-
Find the dynamic environment to delete
-
Click "Delete" button (trash icon)
-
Confirm deletion in modal
-
Backend will:
-
Delete ArgoCD Application
-
Delete Helm values file from Git
-
Delete Application YAML from Git
-
Commit and push changes
-
Delete Harbor images (optional)
-
Manual Deletion
# Delete ArgoCD Application
argocd app delete feature-ticket-123 --cascade
# Delete namespace (if not cascaded)
kubectl delete namespace feature-ticket-123
# Remove files from Git
rm helm/ft-services/values-dynamic-feature-ticket-123.yaml
rm argocd/applications/dynamic/feature-ticket-123.yaml
git add -A && git commit -m "Remove feature-ticket-123 environment"
git push
Managing Service Tags
Via Services Manager Tab
Update Service Tags/Branches
-
Navigate to "Manage Services" tab
-
Select environment from dropdown
-
For each service you want to update:
-
Toggle between Harbor (existing tags) or Branch (Git branches)
-
Select from dropdown:
-
Harbor: Shows available tags with count (e.g., "15 tags")
-
Branch: Searchable dropdown with count (e.g., "42 branches")
-
-
-
Review "Pending Changes" summary at bottom
-
Click "Save Changes" to commit to Git
-
ArgoCD will sync automatically
Trigger Build for Branch
-
In Services Manager, select Branch for the service
-
Select or search for the branch name
-
Click "Build" button next to the service
-
Confirm build in dialog
-
Wait for GitHub Actions to complete (5-10 minutes)
-
Save changes to update environment
Viewing Environment Details
Via Environment Info Modal
-
Navigate to "List" tab
-
Click the "Info" button (ℹ️ icon) for any environment
-
View:
-
Service URLs - Direct links to all enabled services
-
Parent URLs - Services inherited from parent (partial environments)
-
Database Ports - External ports for MySQL/Oracle/ClickHouse
-
Infrastructure Ports - Hazelcast, ActiveMQ ports
-
Device Ports - MQTT, USP, CoAP connection ports
-
Debug Ports - Remote debugging ports (when debug enabled)
-
Port format shows external (internal). External ports include envIndex offset.
|
Syncing an Environment
Troubleshooting
Environment Shows "OutOfSync"
# Check sync status details
argocd app get feature-ticket-123
# View diff
argocd app diff feature-ticket-123
# Check ArgoCD logs
kubectl logs -n argocd -l app.kubernetes.io/name=argocd-application-controller
Resolution
-
Git changes not pushed - Commit and push pending changes
-
Helm render error - Check values file syntax
-
Resource conflict - Delete conflicting resource manually
-
Force sync:
argocd app sync feature-ticket-123 --force
Environment Shows "Degraded"
# Check pod status
kubectl get pods -n feature-ticket-123
# Check events
kubectl get events -n feature-ticket-123 --sort-by='.lastTimestamp'
# Check specific pod
kubectl describe pod <pod-name> -n feature-ticket-123
kubectl logs <pod-name> -n feature-ticket-123
| Cause | Solution |
|---|---|
Image pull error |
Check Harbor credentials, verify image exists |
Resource limits |
Increase memory/CPU in values file |
Database connection |
Verify parent environment DB is running |
Init container failure |
Check ft-config-job logs |
Liveness probe failure |
Check application logs, extend probe timeout |
Build Failed
# Check GitHub Actions
# Navigate to: https://github.com/{owner}/{repo}/actions
# Check backend logs
docker-compose logs backend | grep -i build
| Cause | Solution |
|---|---|
Branch not found |
Verify branch name exists in Git |
Build error |
Check GitHub Actions workflow logs |
Timeout |
Retry build, check for large dependencies |
Rate limit |
Wait and retry, check GitHub API limits |
Duplicate Name Error
-
Environment with same name already exists
-
Files exist in Git from failed previous creation
-
ArgoCD Application exists but not in Git
# Check for existing files
ls helm/ft-services/values-dynamic-*.yaml | grep <name>
ls argocd/applications/dynamic/*.yaml | grep <name>
# Check ArgoCD
argocd app get <name>
# Clean up orphaned resources
argocd app delete <name> --cascade
rm helm/ft-services/values-dynamic-<name>.yaml
rm argocd/applications/dynamic/<name>.yaml
git add -A && git commit -m "Clean up orphaned environment"
git push
Recovery Procedures
Environment Stuck in Creating
# Check backend logs
docker-compose logs backend
# Check if git commit happened
git log --oneline -5
# Check ft-root sync
argocd app get ft-root
# Manual intervention: sync ft-root
argocd app sync ft-root
# Check if application was created
argocd app list | grep <env-name>
Database Connection Issues (Partial Env)
# Verify parent environment is running
kubectl get pods -n dev-mysql | grep mysql
# Check MySQL is accepting connections
kubectl exec -it -n dev-mysql mysql-0 -- mysql -u root -p -e "SELECT 1"
# Check service DNS resolution from new env
kubectl run -it --rm debug --image=busybox -n feature-ticket-123 -- nslookup mysql.dev-mysql.svc.cluster.local
# Update parent reference in values file if needed
Harbor Image Not Found After Build
# Verify image in Harbor
curl -u "$HARBOR_USERNAME:$HARBOR_PASSWORD" \
"https://$HARBOR_HOST/api/v2.0/projects/$HARBOR_PROJECT/repositories/<service>/tags"
# Check GitHub Actions completed
# View workflow run at: https://github.com/{owner}/{repo}/actions
# Retry build via Environment Manager or manually
Maintenance Tasks
Clean Up Old Feature Environments
#!/bin/bash
# Delete feature environments older than 7 days
THRESHOLD_DAYS=7
for app in $(argocd app list -o name | grep "^feature-"); do
CREATED=$(argocd app get $app -o json | jq -r '.metadata.creationTimestamp')
AGE_DAYS=$(( ($(date +%s) - $(date -d "$CREATED" +%s)) / 86400 ))
if [ $AGE_DAYS -gt $THRESHOLD_DAYS ]; then
echo "Deleting $app (age: $AGE_DAYS days)"
argocd app delete $app --cascade -y
fi
done
Refresh All Environments
# Refresh all dynamic environments
for app in $(argocd app list -o name | grep "^feature-"); do
echo "Refreshing $app"
argocd app get $app --refresh
done
Verify Environment Health
#!/bin/bash
# Check all environments
echo "Environment Status Report"
echo "========================="
for ns in $(kubectl get ns -o name | grep -E "^namespace/(dev|feature)" | cut -d/ -f2); do
PODS=$(kubectl get pods -n $ns --no-headers 2>/dev/null | wc -l)
RUNNING=$(kubectl get pods -n $ns --field-selector=status.phase=Running --no-headers 2>/dev/null | wc -l)
echo "$ns: $RUNNING/$PODS pods running"
done