# Migration Guide: Legacy to Well-Architected Framework

## Overview

This guide helps you migrate from the legacy single resource group deployment to the Well-Architected Framework multi-resource-group deployment.

## Prerequisites

- Existing deployment using legacy single resource group
- Azure CLI installed and configured
- Terraform >= 1.0 installed
- Backup of existing infrastructure
- Understanding of Well-Architected Framework structure

## Migration Steps

### Step 1: Review Current Infrastructure

```bash
# List current resource groups
az group list --query "[?contains(name, 'defi-oracle')].{Name:name, Location:location}" --output table

# List resources in current resource group
az resource list --resource-group defi-oracle-mainnet-rg --output table
```

### Step 2: Create Well-Architected Resource Groups

```bash
# Navigate to well-architected directory
cd terraform/well-architected

# Copy example variables
cp terraform.tfvars.example terraform.tfvars

# Edit terraform.tfvars with your values
# Set environment = "prod"
# Set subscription_id = "<your-subscription-id>"

# Initialize Terraform
terraform init

# Plan deployment (creates resource groups only)
terraform plan -var-file=terraform.tfvars -target=module.resource_groups

# Apply resource groups
terraform apply -var-file=terraform.tfvars -target=module.resource_groups
```

### Step 3: Migrate Resources

#### Option A: Terraform State Migration (Recommended)

1. **Backup Current State**
   ```bash
   # Backup current Terraform state
   terraform state pull > terraform-state-backup.json
   ```

2. **Move Resources to New Resource Groups**
   ```bash
   # Move networking resources
   az network vnet move \
     --resource-group defi-oracle-mainnet-rg \
     --name defi-oracle-aks-vnet \
     --destination-resource-group rg-prod-network-001
   
   # Move storage accounts
   az storage account update \
     --resource-group defi-oracle-mainnet-rg \
     --name <storage-account-name> \
     --set resourceGroup=rg-prod-storage-001
   
   # Move Key Vault
   az keyvault update \
     --resource-group defi-oracle-mainnet-rg \
     --name defi-oracle-kv \
     --set resourceGroup=rg-prod-security-001
   ```

3. **Update Terraform State**
   ```bash
   # Update resource group references in state
   terraform state mv \
     azurerm_resource_group.main \
     module.resource_groups.azurerm_resource_group.compute
   ```

#### Option B: Recreate Resources (Clean Slate)

1. **Export Current Configuration**
   ```bash
   # Export current Terraform configuration
   terraform show -json > current-config.json
   ```

2. **Update Terraform Configuration**
   - Update `terraform/main.tf` to use `use_well_architected = true`
   - Update resource group names in `terraform.tfvars`
   - Update module references

3. **Plan and Apply**
   ```bash
   # Plan deployment
   terraform plan -var-file=terraform.tfvars
   
   # Apply (will recreate resources in new resource groups)
   terraform apply -var-file=terraform.tfvars
   ```

### Step 4: Update Key Vault

1. **Migrate to Enhanced Key Vault Module**
   ```bash
   # Update Key Vault configuration
   # Use terraform/modules/keyvault-enhanced/ instead of terraform/modules/secrets/
   ```

2. **Enable RBAC**
   ```bash
   # Enable RBAC on Key Vault
   az keyvault update \
     --name <key-vault-name> \
     --resource-group rg-prod-security-001 \
     --enable-rbac-authorization true
   ```

3. **Configure Network Restrictions**
   ```bash
   # Update network ACLs
   az keyvault network-rule add \
     --name <key-vault-name> \
     --resource-group rg-prod-security-001 \
     --subnet <subnet-id> \
     --vnet-name <vnet-name>
   ```

### Step 5: Update Application Configuration

1. **Update Resource Group References**
   - Update Kubernetes manifests
   - Update deployment scripts
   - Update monitoring configuration
   - Update backup scripts

2. **Update Environment Variables**
   ```bash
   # Update environment variables in Kubernetes
   kubectl set env deployment/<deployment-name> \
     RESOURCE_GROUP=rg-prod-compute-001 \
     KEY_VAULT_RG=rg-prod-security-001
   ```

### Step 6: Verify Migration

```bash
# Verify resource groups
az group list --query "[?contains(name, 'rg-prod-')].{Name:name, Location:location}" --output table

# Verify resources in new resource groups
az resource list --resource-group rg-prod-network-001 --output table
az resource list --resource-group rg-prod-compute-001 --output table
az resource list --resource-group rg-prod-storage-001 --output table
az resource list --resource-group rg-prod-security-001 --output table

# Verify Key Vault
az keyvault show --name <key-vault-name> --resource-group rg-prod-security-001

# Verify AKS cluster
az aks show --name defi-oracle-aks --resource-group rg-prod-compute-001
```

### Step 7: Clean Up Legacy Resources

```bash
# Delete legacy resource group (after verification)
az group delete --name defi-oracle-mainnet-rg --yes --no-wait
```

## Rollback Plan

If migration fails, rollback steps:

1. **Restore Terraform State**
   ```bash
   terraform state push terraform-state-backup.json
   ```

2. **Move Resources Back**
   ```bash
   # Move resources back to original resource group
   az network vnet move \
     --resource-group rg-prod-network-001 \
     --name defi-oracle-aks-vnet \
     --destination-resource-group defi-oracle-mainnet-rg
   ```

3. **Update Configuration**
   ```bash
   # Revert to legacy configuration
   use_well_architected = false
   ```

## Best Practices

1. **Test in Non-Production First**
   - Test migration in dev/test environment
   - Verify all functionality works
   - Document any issues

2. **Backup Everything**
   - Backup Terraform state
   - Backup Key Vault secrets
   - Backup storage accounts
   - Backup Kubernetes configurations

3. **Plan Maintenance Window**
   - Schedule migration during maintenance window
   - Notify stakeholders
   - Have rollback plan ready

4. **Monitor During Migration**
   - Monitor resource health
   - Monitor application performance
   - Monitor costs

5. **Document Changes**
   - Document all changes made
   - Update runbooks
   - Update documentation

## Common Issues

### Issue: Resource Group Already Exists

**Solution**: Use existing resource groups or rename new ones

```bash
# Check if resource group exists
az group show --name rg-prod-network-001

# Use existing or create new with different name
```

### Issue: Key Vault Network Restrictions Too Strict

**Solution**: Temporarily allow management IP, then refine

```bash
# Add management IP to Key Vault network rules
az keyvault network-rule add \
  --name <key-vault-name> \
  --resource-group rg-prod-security-001 \
  --ip-address <your-ip>
```

### Issue: Resources Can't Be Moved

**Solution**: Some resources can't be moved between resource groups. Recreate them.

```bash
# List resources that can't be moved
az resource list --resource-group defi-oracle-mainnet-rg --query "[?properties.provisioningState!='Succeeded']"
```

## References

- [Well-Architected Framework Review](../azure/AZURE_WELL_ARCHITECTED_REVIEW.md)
- [Well-Architected Implementation](../azure/AZURE_WELL_ARCHITECTED_IMPLEMENTATION.md)
- [Azure Resource Movement](https://docs.microsoft.com/azure/azure-resource-manager/management/move-resource-group-and-subscription)
