Use Case: Legacy Application Modernization¶
Business Context¶
Legacy application modernization is critical for organizations looking to leverage modern cloud-native technologies while preserving existing business logic and data. This use case demonstrates a phased approach to modernizing legacy applications using the RH OVE ecosystem, enabling gradual transformation with minimal business disruption.
Technical Requirements¶
Infrastructure Requirements¶
- OpenShift 4.12+ with KubeVirt enabled
- Application migration tools (Migration Toolkit for Applications - MTA)
- Service mesh for hybrid connectivity (OpenShift Service Mesh/Istio)
- CI/CD pipelines (OpenShift Pipelines/Tekton)
- Container registry (Quay.io or OpenShift integrated registry)
Resource Requirements¶
- Compute: Sufficient resources for both legacy and modernized components during transition
- Storage: Persistent storage for data migration and synchronization
- Network: High-bandwidth connectivity for data replication and service communication
Architecture Overview¶
graph TD
subgraph "Legacy Environment"
LEGACY_APP["Legacy Application"]
LEGACY_DB["Legacy Database"]
LEGACY_FILES["File System"]
end
subgraph "Modernization Platform"
VM_LAYER["VM Layer (Lift & Shift)"]
CONTAINER_LAYER["Container Layer"]
MICROSERVICES["Microservices"]
MODERN_DB["Modern Database"]
end
subgraph "Integration Layer"
SERVICE_MESH["Service Mesh"]
API_GATEWAY["API Gateway"]
MESSAGE_QUEUE["Message Queue"]
end
LEGACY_APP --> VM_LAYER
VM_LAYER --> CONTAINER_LAYER
CONTAINER_LAYER --> MICROSERVICES
LEGACY_DB --> MODERN_DB
SERVICE_MESH --> VM_LAYER
SERVICE_MESH --> CONTAINER_LAYER
SERVICE_MESH --> MICROSERVICES
API_GATEWAY --> SERVICE_MESH
MESSAGE_QUEUE --> SERVICE_MESH
style LEGACY_APP fill:#faa,stroke:#333
style MICROSERVICES fill:#afa,stroke:#333
style SERVICE_MESH fill:#aaf,stroke:#333
Implementation Steps¶
Phase 1: Assessment and Planning¶
Application Discovery¶
# MTA Configuration for Application Analysis
apiVersion: tackle.konveyor.io/v1alpha1
kind: Application
metadata:
name: legacy-app-analysis
namespace: konveyor-tackle
spec:
name: "Legacy ERP System"
description: "Monolithic ERP application requiring modernization"
repository:
kind: git
url: "https://git.example.com/legacy-erp"
binary: "erp-application.war"
Migration Assessment¶
# Run application analysis using MTA CLI
konveyor-cli analyze \
--input /path/to/legacy-app \
--output /path/to/analysis-results \
--target cloud-readiness \
--target containers
Phase 2: Lift and Shift (VM Migration)¶
VM-based Legacy Application Deployment¶
apiVersion: kubevirt.io/v1
kind: VirtualMachine
metadata:
name: legacy-erp-vm
namespace: modernization
spec:
running: true
template:
metadata:
labels:
app: legacy-erp
tier: application
phase: lift-shift
spec:
domain:
cpu:
cores: 4
devices:
disks:
- disk:
bus: virtio
name: rootdisk
- disk:
bus: virtio
name: datadisk
interfaces:
- name: default
bridge: {}
memory:
guest: 8Gi
resources:
requests:
memory: 8Gi
cpu: 4
networks:
- name: default
pod: {}
volumes:
- dataVolume:
name: legacy-erp-root
name: rootdisk
- dataVolume:
name: legacy-erp-data
name: datadisk
---
apiVersion: cdi.kubevirt.io/v1beta1
kind: DataVolume
metadata:
name: legacy-erp-root
namespace: modernization
spec:
source:
http:
url: "https://vm-images.example.com/legacy-erp-root.img"
pvc:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 100Gi
---
apiVersion: cdi.kubevirt.io/v1beta1
kind: DataVolume
metadata:
name: legacy-erp-data
namespace: modernization
spec:
source:
http:
url: "https://vm-images.example.com/legacy-erp-data.img"
pvc:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 500Gi
Phase 3: Containerization¶
Legacy Application Container Deployment¶
apiVersion: apps/v1
kind: Deployment
metadata:
name: legacy-erp-container
namespace: modernization
spec:
replicas: 2
selector:
matchLabels:
app: legacy-erp
tier: application
phase: containerized
template:
metadata:
labels:
app: legacy-erp
tier: application
phase: containerized
spec:
containers:
- name: erp-app
image: quay.io/example/legacy-erp:containerized
ports:
- containerPort: 8080
name: http
- containerPort: 8443
name: https
env:
- name: DB_HOST
value: "legacy-database-service"
- name: DB_PORT
value: "5432"
- name: DB_NAME
valueFrom:
secretKeyRef:
name: db-credentials
key: database
- name: DB_USER
valueFrom:
secretKeyRef:
name: db-credentials
key: username
- name: DB_PASSWORD
valueFrom:
secretKeyRef:
name: db-credentials
key: password
volumeMounts:
- name: app-data
mountPath: /opt/erp/data
- name: app-config
mountPath: /opt/erp/config
volumes:
- name: app-data
persistentVolumeClaim:
claimName: erp-data-pvc
- name: app-config
configMap:
name: erp-config
Phase 4: Service Decomposition¶
Extract User Management Service¶
apiVersion: apps/v1
kind: Deployment
metadata:
name: user-management-service
namespace: modernization
spec:
replicas: 3
selector:
matchLabels:
app: user-management
tier: microservice
template:
metadata:
labels:
app: user-management
tier: microservice
version: v1
spec:
containers:
- name: user-management
image: quay.io/example/user-management:v1.0.0
ports:
- containerPort: 8080
name: http
env:
- name: DATABASE_URL
valueFrom:
secretKeyRef:
name: user-db-credentials
key: url
- name: REDIS_URL
valueFrom:
secretKeyRef:
name: redis-credentials
key: url
livenessProbe:
httpGet:
path: /health
port: 8080
initialDelaySeconds: 30
periodSeconds: 10
readinessProbe:
httpGet:
path: /ready
port: 8080
initialDelaySeconds: 5
periodSeconds: 5
---
apiVersion: v1
kind: Service
metadata:
name: user-management-service
namespace: modernization
spec:
selector:
app: user-management
ports:
- name: http
port: 80
targetPort: 8080
type: ClusterIP
Phase 5: Service Mesh Integration¶
Istio Service Mesh Configuration¶
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
name: legacy-erp-routing
namespace: modernization
spec:
hosts:
- erp.example.com
http:
- match:
- uri:
prefix: /api/users
route:
- destination:
host: user-management-service
port:
number: 80
weight: 100
- match:
- uri:
prefix: /
route:
- destination:
host: legacy-erp-container
port:
number: 8080
weight: 90
- destination:
host: legacy-erp-vm
port:
number: 8080
weight: 10
---
apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
metadata:
name: legacy-erp-destination
namespace: modernization
spec:
host: legacy-erp-container
trafficPolicy:
circuitBreaker:
consecutive5xxErrors: 3
interval: 30s
baseEjectionTime: 30s
Phase 6: Data Migration Strategy¶
Database Migration Pipeline¶
apiVersion: tekton.dev/v1beta1
kind: Pipeline
metadata:
name: data-migration-pipeline
namespace: modernization
spec:
params:
- name: source-db-url
description: Source database connection URL
- name: target-db-url
description: Target database connection URL
- name: migration-batch-size
default: "1000"
description: Number of records to migrate per batch
tasks:
- name: validate-source
taskRef:
name: database-validation
params:
- name: db-url
value: $(params.source-db-url)
- name: create-target-schema
taskRef:
name: schema-creation
params:
- name: db-url
value: $(params.target-db-url)
runAfter:
- validate-source
- name: migrate-data
taskRef:
name: data-migration
params:
- name: source-db-url
value: $(params.source-db-url)
- name: target-db-url
value: $(params.target-db-url)
- name: batch-size
value: $(params.migration-batch-size)
runAfter:
- create-target-schema
- name: validate-migration
taskRef:
name: migration-validation
params:
- name: source-db-url
value: $(params.source-db-url)
- name: target-db-url
value: $(params.target-db-url)
runAfter:
- migrate-data
Phase 7: Progressive Traffic Migration¶
Canary Deployment Strategy¶
apiVersion: argoproj.io/v1alpha1
kind: Rollout
metadata:
name: legacy-erp-rollout
namespace: modernization
spec:
replicas: 5
strategy:
canary:
steps:
- setWeight: 10
- pause: {duration: 300s}
- setWeight: 25
- pause: {duration: 300s}
- setWeight: 50
- pause: {duration: 300s}
- setWeight: 75
- pause: {duration: 300s}
canaryService: legacy-erp-canary
stableService: legacy-erp-stable
trafficRouting:
istio:
virtualService:
name: legacy-erp-routing
routes:
- primary
selector:
matchLabels:
app: legacy-erp
template:
metadata:
labels:
app: legacy-erp
spec:
containers:
- name: erp-app
image: quay.io/example/legacy-erp:modernized
ports:
- containerPort: 8080
Monitoring and Observability¶
Application Performance Monitoring¶
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
name: modernization-monitoring
namespace: modernization
spec:
selector:
matchLabels:
monitoring: enabled
endpoints:
- port: metrics
interval: 30s
path: /metrics
---
apiVersion: monitoring.coreos.com/v1
kind: PrometheusRule
metadata:
name: modernization-alerts
namespace: modernization
spec:
groups:
- name: modernization.alerts
rules:
- alert: LegacyAppHighErrorRate
expr: rate(http_requests_total{status=~"5.."}[5m]) > 0.1
for: 5m
labels:
severity: warning
annotations:
summary: "High error rate in legacy application"
- alert: MigrationDataInconsistency
expr: migration_data_consistency_check != 1
for: 1m
labels:
severity: critical
annotations:
summary: "Data inconsistency detected during migration"
Troubleshooting Guide¶
Common Issues and Solutions¶
Performance Degradation During Migration¶
- Issue: Application performance degrades during data migration
- Solution:
- Implement read replicas for database queries
- Use incremental migration strategies
- Schedule heavy migration tasks during off-peak hours
Service Communication Failures¶
- Issue: Communication failures between legacy and modern components
- Solution:
- Verify service mesh configuration
- Check network policies and firewall rules
- Implement circuit breakers and retry mechanisms
Data Consistency Issues¶
- Issue: Data inconsistencies between old and new systems
- Solution:
- Implement two-phase commit protocols
- Use event sourcing for critical operations
- Regular data validation and reconciliation
Best Practices¶
Migration Strategy¶
- Incremental Approach: Migrate functionality incrementally to reduce risk
- Feature Toggles: Use feature flags to control rollout of new functionality
- Rollback Plans: Always have rollback procedures for each migration phase
Testing and Validation¶
- Automated Testing: Implement comprehensive test suites for both legacy and modern components
- Performance Testing: Conduct load testing throughout the migration process
- Data Validation: Implement automated data consistency checks
Security Considerations¶
- Zero-Trust Architecture: Implement zero-trust principles across all components
- Secrets Management: Use proper secrets management for database credentials and API keys
- Network Segmentation: Implement proper network segmentation between components
Integration with RH OVE Ecosystem¶
GitOps Integration¶
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: legacy-modernization
namespace: argocd
spec:
project: modernization
source:
repoURL: https://git.example.com/legacy-modernization-config
targetRevision: HEAD
path: environments/production
destination:
server: https://kubernetes.default.svc
namespace: modernization
syncPolicy:
automated:
prune: false
selfHeal: true
syncOptions:
- CreateNamespace=true
Multi-Cluster Deployment¶
- Staging Environment: Use separate clusters for testing and validation
- Production Rollout: Implement blue-green deployment across clusters
- Disaster Recovery: Maintain legacy systems as backup during transition
This comprehensive guide provides a structured approach to legacy application modernization within the RH OVE ecosystem, enabling organizations to gradually transform their applications while maintaining business continuity and reducing risk.