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

Create Partial Environment
  1. Navigate to Environment Manager Web UI

  2. Click "Create" tab

  3. 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)

  4. Select services to deploy

  5. For each service, choose:

    • Harbor: Select existing tag from dropdown

    • Branch: Enter Git branch name (will trigger build)

  6. Click "Create Environment"

  7. Wait for build completion (if branch selected) - 5-10 minutes per service

  8. Environment deploys automatically via ArgoCD

Create Full Environment
  1. Navigate to Environment Manager Web UI

  2. Click "Create" tab

  3. Fill in:

    • Environment Name: lowercase letters, numbers, hyphens only

    • Environment Type: Full

    • Database Type: MySQL or Oracle

  4. All services are auto-selected (cannot uncheck)

  5. Configure image source for each service

  6. Click "Create Environment"

  7. Full deployment takes 15-30 minutes (includes database initialization)

Via Shell Script

# Create feature environment with MySQL
./scripts/create-feature-env.sh TICKET-123 mysql

# Create feature environment with Oracle
./scripts/create-feature-env.sh TICKET-123 oracle

# Verify creation
kubectl get namespace feature-ticket-123
kubectl get pods -n feature-ticket-123

Deleting an Environment

Via Environment Manager

  1. Navigate to "List" tab

  2. Find the dynamic environment to delete

  3. Click "Delete" button (trash icon)

  4. Confirm deletion in modal

  5. 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
  1. Navigate to "Manage Services" tab

  2. Select environment from dropdown

  3. 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")

  4. Review "Pending Changes" summary at bottom

  5. Click "Save Changes" to commit to Git

  6. ArgoCD will sync automatically

Trigger Build for Branch
  1. In Services Manager, select Branch for the service

  2. Select or search for the branch name

  3. Click "Build" button next to the service

  4. Confirm build in dialog

  5. Wait for GitHub Actions to complete (5-10 minutes)

  6. Save changes to update environment

Viewing Environment Details

Via Environment Info Modal

  1. Navigate to "List" tab

  2. Click the "Info" button (ℹ️ icon) for any environment

  3. 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

Via Environment Manager

  1. Navigate to "List" tab

  2. Find the environment

  3. Click "Sync" button (circular arrows icon)

  4. Wait for sync to complete

  5. Status should change to "Synced"

Via ArgoCD CLI

# Sync specific application
argocd app sync feature-ticket-123

# Force sync with prune
argocd app sync feature-ticket-123 --prune

# Hard refresh (clear cache)
argocd app get feature-ticket-123 --hard-refresh

Troubleshooting

Environment Shows "OutOfSync"

Diagnosis
# 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
  1. Git changes not pushed - Commit and push pending changes

  2. Helm render error - Check values file syntax

  3. Resource conflict - Delete conflicting resource manually

  4. Force sync: argocd app sync feature-ticket-123 --force

Environment Shows "Degraded"

Diagnosis
# 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
Table 1. Common Causes and Solutions
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

Diagnosis
# Check GitHub Actions
# Navigate to: https://github.com/{owner}/{repo}/actions

# Check backend logs
docker-compose logs backend | grep -i build
Table 2. Common Causes
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

Causes
  1. Environment with same name already exists

  2. Files exist in Git from failed previous creation

  3. ArgoCD Application exists but not in Git

Resolution
# 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

Automated Cleanup Script
#!/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