feat: comprehensive project structure improvements and Cloud for Sovereignty landing zone
- Add Cloud for Sovereignty landing zone architecture and deployment - Implement complete legal document management system - Reorganize documentation with improved navigation - Add infrastructure improvements (Dockerfiles, K8s, monitoring) - Add operational improvements (graceful shutdown, rate limiting, caching) - Create comprehensive project structure documentation - Add Azure deployment automation scripts - Improve repository navigation and organization
This commit is contained in:
100
docs/deployment/README.md
Normal file
100
docs/deployment/README.md
Normal file
@@ -0,0 +1,100 @@
|
||||
# Deployment Documentation
|
||||
|
||||
**Last Updated**: 2025-01-27
|
||||
**Purpose**: Complete deployment guide index
|
||||
|
||||
## Overview
|
||||
|
||||
This directory contains comprehensive deployment guides for The Order platform, covering infrastructure setup, service deployment, and operational procedures.
|
||||
|
||||
## Quick Links
|
||||
|
||||
### Azure Deployment
|
||||
- [Environment Setup](azure/ENVIRONMENT_SETUP.md) - Azure configuration and setup
|
||||
- [Dotenv Configuration](azure/DOTENV_SETUP.md) - Using .env file for deployments
|
||||
- [Sovereignty Landing Zone](azure/SOVEREIGNTY_LANDING_ZONE_DEPLOYMENT.md) - Multi-region deployment
|
||||
- [CDN Setup](azure/cdn-setup.md) - Azure CDN configuration
|
||||
- [Entra VerifiedID](azure/entra-verifiedid.md) - Entra VerifiedID setup
|
||||
|
||||
### Kubernetes Deployment
|
||||
- [Kubernetes Guide](../../infra/k8s/README.md) - K8s deployment guide
|
||||
- [Service Manifests](../../infra/k8s/base/) - Base Kubernetes manifests
|
||||
|
||||
### Infrastructure
|
||||
- [Infrastructure Overview](../../infra/README.md) - Infrastructure documentation
|
||||
- [Terraform Guide](../../infra/terraform/README.md) - Terraform documentation
|
||||
|
||||
## Deployment Guides by Scenario
|
||||
|
||||
### Initial Setup
|
||||
1. [Azure Environment Setup](azure/ENVIRONMENT_SETUP.md)
|
||||
2. [Dotenv Configuration](azure/DOTENV_SETUP.md)
|
||||
3. [Infrastructure Deployment](../../infra/README.md)
|
||||
|
||||
### Multi-Region Deployment
|
||||
1. [Sovereignty Landing Zone Deployment](azure/SOVEREIGNTY_LANDING_ZONE_DEPLOYMENT.md)
|
||||
2. [Cloud for Sovereignty Architecture](../../docs/architecture/CLOUD_FOR_SOVEREIGNTY_LANDING_ZONE.md)
|
||||
|
||||
### Service Deployment
|
||||
1. [Kubernetes Deployment](../../infra/k8s/README.md)
|
||||
2. Service-specific READMEs in `services/*/README.md`
|
||||
|
||||
### Integration Setup
|
||||
1. [Entra VerifiedID](azure/entra-verifiedid.md)
|
||||
2. [CDN Configuration](azure/cdn-setup.md)
|
||||
3. [Integration Guides](../integrations/)
|
||||
|
||||
## Deployment Workflows
|
||||
|
||||
### Complete Azure Deployment
|
||||
|
||||
```bash
|
||||
# 1. Load environment
|
||||
source infra/scripts/azure-load-env.sh
|
||||
|
||||
# 2. Validate configuration
|
||||
./infra/scripts/azure-validate-current-env.sh
|
||||
|
||||
# 3. Deploy infrastructure
|
||||
./infra/scripts/azure-deploy.sh
|
||||
|
||||
# 4. Deploy sovereignty landing zone
|
||||
./infra/scripts/deploy-sovereignty-landing-zone.sh
|
||||
```
|
||||
|
||||
### Kubernetes Deployment
|
||||
|
||||
```bash
|
||||
# 1. Apply base configuration
|
||||
kubectl apply -k infra/k8s/base
|
||||
|
||||
# 2. Apply environment overlay
|
||||
kubectl apply -k infra/k8s/overlays/dev
|
||||
|
||||
# 3. Verify deployment
|
||||
kubectl get pods -n the-order
|
||||
```
|
||||
|
||||
## Documentation Structure
|
||||
|
||||
```
|
||||
deployment/
|
||||
├── README.md # This file
|
||||
└── azure/ # Azure-specific guides
|
||||
├── ENVIRONMENT_SETUP.md
|
||||
├── DOTENV_SETUP.md
|
||||
├── SOVEREIGNTY_LANDING_ZONE_DEPLOYMENT.md
|
||||
├── cdn-setup.md
|
||||
└── entra-verifiedid.md
|
||||
```
|
||||
|
||||
## Related Documentation
|
||||
|
||||
- [Architecture Documentation](../architecture/)
|
||||
- [Infrastructure Documentation](../../infra/)
|
||||
- [Service Documentation](../../services/)
|
||||
- [Integration Documentation](../integrations/)
|
||||
|
||||
---
|
||||
|
||||
**Last Updated**: 2025-01-27
|
||||
221
docs/deployment/azure/DOTENV_SETUP.md
Normal file
221
docs/deployment/azure/DOTENV_SETUP.md
Normal file
@@ -0,0 +1,221 @@
|
||||
# Using .env File for Azure Deployments
|
||||
|
||||
**Last Updated**: 2025-01-27
|
||||
**Status**: Complete Guide
|
||||
|
||||
## Overview
|
||||
|
||||
This guide explains how to use the `.env` file in the project root to configure all Azure deployments, ensuring consistent configuration across Terraform, Kubernetes, and application services.
|
||||
|
||||
## Setup
|
||||
|
||||
### Step 1: Create/Update .env File
|
||||
|
||||
The `.env` file should be in the project root (`/home/intlc/projects/the_order/.env`).
|
||||
|
||||
Required variables:
|
||||
```bash
|
||||
# Azure Authentication
|
||||
ARM_SUBSCRIPTION_ID="your-subscription-id"
|
||||
ARM_TENANT_ID="your-tenant-id"
|
||||
|
||||
# Optional: Service Principal (if not using Azure CLI)
|
||||
ARM_CLIENT_ID="your-client-id"
|
||||
ARM_CLIENT_SECRET="your-client-secret"
|
||||
|
||||
# Azure Configuration
|
||||
ARM_LOCATION="westeurope" # No US regions
|
||||
TF_VAR_environment="dev" # dev, stage, or prod
|
||||
```
|
||||
|
||||
### Step 2: Validate Environment
|
||||
|
||||
```bash
|
||||
# Validate all required variables are set
|
||||
source infra/scripts/azure-validate-env.sh
|
||||
```
|
||||
|
||||
This script will:
|
||||
- ✅ Check for required variables
|
||||
- ✅ Set defaults for optional variables
|
||||
- ✅ Verify Azure CLI authentication
|
||||
- ✅ Export Terraform variables
|
||||
|
||||
### Step 3: Sync to Terraform
|
||||
|
||||
```bash
|
||||
# Generate terraform.tfvars from .env
|
||||
./infra/scripts/azure-sync-env-to-terraform.sh
|
||||
```
|
||||
|
||||
This creates `infra/terraform/terraform.tfvars` with all values from `.env`.
|
||||
|
||||
### Step 4: Deploy Infrastructure
|
||||
|
||||
```bash
|
||||
# Complete deployment using .env values
|
||||
./infra/scripts/azure-deploy.sh
|
||||
```
|
||||
|
||||
## How It Works
|
||||
|
||||
### Environment Variable Flow
|
||||
|
||||
```
|
||||
.env file
|
||||
↓
|
||||
azure-validate-env.sh (validates & exports)
|
||||
↓
|
||||
azure-sync-env-to-terraform.sh (creates terraform.tfvars)
|
||||
↓
|
||||
Terraform (creates Azure resources)
|
||||
↓
|
||||
Terraform outputs (Key Vault URI, Storage Account, etc.)
|
||||
↓
|
||||
azure-update-k8s-secrets.sh (updates Kubernetes configs)
|
||||
↓
|
||||
Kubernetes External Secrets (syncs from Key Vault)
|
||||
```
|
||||
|
||||
### Variable Mapping
|
||||
|
||||
| .env Variable | Terraform Variable | Kubernetes Config |
|
||||
|--------------|-------------------|-------------------|
|
||||
| `ARM_SUBSCRIPTION_ID` | `TF_VAR_subscription_id` | Via Key Vault |
|
||||
| `ARM_TENANT_ID` | `TF_VAR_tenant_id` | External Secrets |
|
||||
| `ARM_LOCATION` | `TF_VAR_azure_region` | ConfigMap |
|
||||
| `TF_VAR_environment` | `TF_VAR_environment` | ConfigMap |
|
||||
| `TF_VAR_resource_group_name` | `TF_VAR_resource_group_name` | ConfigMap |
|
||||
| `TF_VAR_storage_account_name` | `TF_VAR_storage_account_name` | External Secrets |
|
||||
| `TF_VAR_key_vault_name` | `TF_VAR_key_vault_name` | External Secrets |
|
||||
|
||||
## Resource Naming
|
||||
|
||||
Resources are named using values from `.env`:
|
||||
|
||||
- **Resource Group**: `TF_VAR_resource_group_name` or `the-order-rg-{environment}`
|
||||
- **Storage Account**: `TF_VAR_storage_account_name` or auto-generated
|
||||
- **Key Vault**: `TF_VAR_key_vault_name` or `the-order-kv-{environment}`
|
||||
- **AKS Cluster**: `TF_VAR_aks_cluster_name` or `the-order-aks-{environment}`
|
||||
|
||||
## Secrets Management
|
||||
|
||||
### Storing Secrets
|
||||
|
||||
Secrets are stored in Azure Key Vault and synced to Kubernetes:
|
||||
|
||||
1. **Store in Key Vault** (via Azure CLI or Terraform):
|
||||
```bash
|
||||
az keyvault secret set \
|
||||
--vault-name <key-vault-name> \
|
||||
--name "database-url" \
|
||||
--value "postgresql://..."
|
||||
```
|
||||
|
||||
2. **Sync to Kubernetes** (automatic via External Secrets Operator):
|
||||
- External Secrets Operator reads from Key Vault
|
||||
- Creates Kubernetes secrets automatically
|
||||
- Updates when Key Vault secrets change
|
||||
|
||||
### Accessing Secrets
|
||||
|
||||
Services access secrets via:
|
||||
- **Kubernetes Secrets**: Created by External Secrets Operator
|
||||
- **Environment Variables**: Injected into pods
|
||||
- **Key Vault Direct**: For services with managed identity
|
||||
|
||||
## Verification
|
||||
|
||||
### Check Terraform Variables
|
||||
|
||||
```bash
|
||||
cd infra/terraform
|
||||
terraform plan # Shows what will be created with current .env values
|
||||
```
|
||||
|
||||
### Check Kubernetes Config
|
||||
|
||||
```bash
|
||||
# View ConfigMap
|
||||
kubectl get configmap azure-config -n the-order -o yaml
|
||||
|
||||
# View External Secrets
|
||||
kubectl get externalsecret azure-secrets -n the-order -o yaml
|
||||
|
||||
# View synced secrets
|
||||
kubectl get secret the-order-secrets -n the-order -o yaml
|
||||
```
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Variables Not Found
|
||||
|
||||
```bash
|
||||
# Re-validate environment
|
||||
source infra/scripts/azure-validate-env.sh
|
||||
|
||||
# Check .env file exists
|
||||
ls -la .env
|
||||
|
||||
# Verify variables are set
|
||||
echo $ARM_SUBSCRIPTION_ID
|
||||
echo $ARM_TENANT_ID
|
||||
```
|
||||
|
||||
### Terraform Can't Find Variables
|
||||
|
||||
```bash
|
||||
# Re-sync to Terraform
|
||||
./infra/scripts/azure-sync-env-to-terraform.sh
|
||||
|
||||
# Check terraform.tfvars
|
||||
cat infra/terraform/terraform.tfvars
|
||||
```
|
||||
|
||||
### Kubernetes Secrets Not Syncing
|
||||
|
||||
```bash
|
||||
# Update Kubernetes configs
|
||||
./infra/scripts/azure-update-k8s-secrets.sh
|
||||
|
||||
# Check External Secrets Operator
|
||||
kubectl get pods -n external-secrets-system
|
||||
|
||||
# Check External Secret status
|
||||
kubectl describe externalsecret azure-secrets -n the-order
|
||||
```
|
||||
|
||||
## Best Practices
|
||||
|
||||
1. **Never commit .env file** - It's in `.gitignore`
|
||||
2. **Use different .env files** for different environments
|
||||
3. **Store sensitive values in Key Vault** - Not in .env
|
||||
4. **Validate before deploying** - Always run validation script
|
||||
5. **Keep .env.example updated** - Document all variables
|
||||
|
||||
## Example .env File
|
||||
|
||||
```bash
|
||||
# Azure Authentication
|
||||
ARM_SUBSCRIPTION_ID="12345678-1234-1234-1234-123456789012"
|
||||
ARM_TENANT_ID="87654321-4321-4321-4321-210987654321"
|
||||
|
||||
# Azure Configuration
|
||||
ARM_LOCATION="westeurope"
|
||||
TF_VAR_environment="dev"
|
||||
|
||||
# Resource Naming
|
||||
TF_VAR_resource_group_name="the-order-rg-dev"
|
||||
TF_VAR_storage_account_name="theorderdev12345"
|
||||
TF_VAR_key_vault_name="the-order-kv-dev"
|
||||
|
||||
# AKS Configuration
|
||||
TF_VAR_aks_cluster_name="the-order-aks-dev"
|
||||
TF_VAR_aks_node_count=2
|
||||
TF_VAR_aks_vm_size="Standard_B2s"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
**Last Updated**: 2025-01-27
|
||||
|
||||
247
docs/deployment/azure/ENVIRONMENT_SETUP.md
Normal file
247
docs/deployment/azure/ENVIRONMENT_SETUP.md
Normal file
@@ -0,0 +1,247 @@
|
||||
# Azure Environment Setup Guide
|
||||
|
||||
**Last Updated**: 2025-01-27
|
||||
**Status**: Complete Setup Guide
|
||||
|
||||
## Overview
|
||||
|
||||
This guide explains how to configure Azure deployments using environment variables from `.env` files.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
1. **Azure CLI installed and logged in**
|
||||
```bash
|
||||
az login
|
||||
az account list
|
||||
az account set --subscription <subscription-id>
|
||||
```
|
||||
|
||||
2. **Terraform installed** (>= 1.5.0)
|
||||
```bash
|
||||
terraform version
|
||||
```
|
||||
|
||||
3. **Environment file created**
|
||||
- Copy `infra/terraform/.env.example` to `.env` or `infra/terraform/.env`
|
||||
- Fill in your Azure credentials
|
||||
|
||||
## Environment Variables
|
||||
|
||||
### Required Variables
|
||||
|
||||
```bash
|
||||
# Azure Authentication
|
||||
ARM_SUBSCRIPTION_ID="your-subscription-id"
|
||||
ARM_TENANT_ID="your-tenant-id"
|
||||
|
||||
# Optional: Service Principal (if not using Azure CLI)
|
||||
ARM_CLIENT_ID="your-client-id"
|
||||
ARM_CLIENT_SECRET="your-client-secret"
|
||||
```
|
||||
|
||||
### Configuration Variables
|
||||
|
||||
```bash
|
||||
# Azure Region (no US regions)
|
||||
ARM_LOCATION="westeurope"
|
||||
|
||||
# Environment
|
||||
TF_VAR_environment="dev" # dev, stage, or prod
|
||||
|
||||
# Resource Names
|
||||
TF_VAR_resource_group_name="the-order-rg"
|
||||
TF_VAR_storage_account_name="theorderdev" # Must be globally unique
|
||||
TF_VAR_key_vault_name="the-order-kv-dev" # Must be globally unique
|
||||
```
|
||||
|
||||
## Setup Steps
|
||||
|
||||
### Step 1: Create Environment File
|
||||
|
||||
```bash
|
||||
# Copy example file
|
||||
cp infra/terraform/.env.example .env
|
||||
|
||||
# Or use Terraform-specific location
|
||||
cp infra/terraform/.env.example infra/terraform/.env
|
||||
|
||||
# Edit with your values
|
||||
nano .env # or your preferred editor
|
||||
```
|
||||
|
||||
### Step 2: Load Environment Variables
|
||||
|
||||
```bash
|
||||
# Load variables
|
||||
source infra/scripts/azure-load-env.sh
|
||||
|
||||
# Verify
|
||||
echo $ARM_SUBSCRIPTION_ID
|
||||
echo $ARM_TENANT_ID
|
||||
```
|
||||
|
||||
### Step 3: Deploy Infrastructure
|
||||
|
||||
```bash
|
||||
# Option 1: Use deployment script (recommended)
|
||||
./infra/scripts/azure-deploy.sh
|
||||
|
||||
# Option 2: Manual Terraform
|
||||
cd infra/terraform
|
||||
terraform init
|
||||
terraform plan
|
||||
terraform apply
|
||||
```
|
||||
|
||||
## Resource Configuration
|
||||
|
||||
### Resource Group
|
||||
- **Name**: `the-order-rg-{environment}`
|
||||
- **Location**: `westeurope` (or other non-US region)
|
||||
- **Tags**: Environment, Project, ManagedBy
|
||||
|
||||
### Storage Account
|
||||
- **Name**: Must be globally unique (lowercase, alphanumeric)
|
||||
- **Tier**: Standard
|
||||
- **Replication**: LRS (dev), GRS (prod)
|
||||
- **Purpose**: Document storage, CDN origin
|
||||
|
||||
### Key Vault
|
||||
- **Name**: Must be globally unique
|
||||
- **SKU**: Standard
|
||||
- **Soft Delete**: Enabled (7 days retention)
|
||||
- **Purge Protection**: Enabled for production
|
||||
|
||||
### AKS Cluster
|
||||
- **Name**: `the-order-aks-{environment}`
|
||||
- **Kubernetes Version**: 1.28+
|
||||
- **Node Count**: 2 (dev), auto-scaling (prod)
|
||||
- **VM Size**: Standard_B2s (dev), Standard_D2s_v3 (prod)
|
||||
|
||||
### CDN
|
||||
- **Profile**: `theorder-cdn-{environment}`
|
||||
- **Endpoint**: `theorder-cdn-endpoint-{environment}`
|
||||
- **SKU**: Standard_Microsoft
|
||||
|
||||
## Secrets Management
|
||||
|
||||
### Storing Secrets in Key Vault
|
||||
|
||||
```bash
|
||||
# Set secret in Key Vault
|
||||
az keyvault secret set \
|
||||
--vault-name <key-vault-name> \
|
||||
--name "database-url" \
|
||||
--value "postgresql://..."
|
||||
|
||||
# List secrets
|
||||
az keyvault secret list --vault-name <key-vault-name>
|
||||
```
|
||||
|
||||
### Using External Secrets Operator
|
||||
|
||||
Secrets are automatically synced from Key Vault to Kubernetes using External Secrets Operator. See `infra/k8s/base/external-secrets.yaml`.
|
||||
|
||||
## Verification
|
||||
|
||||
### Check Azure Resources
|
||||
|
||||
```bash
|
||||
# List resource groups
|
||||
az group list --query "[?contains(name, 'the-order')]"
|
||||
|
||||
# List storage accounts
|
||||
az storage account list --query "[?contains(name, 'theorder')]"
|
||||
|
||||
# List Key Vaults
|
||||
az keyvault list --query "[?contains(name, 'the-order')]"
|
||||
|
||||
# List AKS clusters
|
||||
az aks list --query "[?contains(name, 'the-order')]"
|
||||
```
|
||||
|
||||
### Check Kubernetes Access
|
||||
|
||||
```bash
|
||||
# Get kubeconfig
|
||||
az aks get-credentials \
|
||||
--resource-group <resource-group> \
|
||||
--name <aks-cluster-name>
|
||||
|
||||
# Verify access
|
||||
kubectl get nodes
|
||||
kubectl get namespaces
|
||||
```
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Authentication Issues
|
||||
|
||||
```bash
|
||||
# Re-authenticate with Azure CLI
|
||||
az login
|
||||
az account set --subscription <subscription-id>
|
||||
|
||||
# Verify current subscription
|
||||
az account show
|
||||
```
|
||||
|
||||
### Terraform Issues
|
||||
|
||||
```bash
|
||||
# Re-initialize Terraform
|
||||
cd infra/terraform
|
||||
terraform init -upgrade
|
||||
|
||||
# Validate configuration
|
||||
terraform validate
|
||||
|
||||
# Check state
|
||||
terraform state list
|
||||
```
|
||||
|
||||
### Resource Naming Conflicts
|
||||
|
||||
If you get "name already taken" errors:
|
||||
1. Choose a more unique name
|
||||
2. Use a different Azure region
|
||||
3. Delete the conflicting resource (if safe)
|
||||
|
||||
## Environment-Specific Configurations
|
||||
|
||||
### Development
|
||||
- **Replication**: LRS (lower cost)
|
||||
- **Node Count**: 2 (fixed)
|
||||
- **Retention**: 30 days
|
||||
- **Purge Protection**: Disabled
|
||||
|
||||
### Staging
|
||||
- **Replication**: GRS
|
||||
- **Node Count**: 2-5 (auto-scaling)
|
||||
- **Retention**: 60 days
|
||||
- **Purge Protection**: Enabled
|
||||
|
||||
### Production
|
||||
- **Replication**: GRS or ZRS
|
||||
- **Node Count**: 3-10 (auto-scaling)
|
||||
- **Retention**: 90 days
|
||||
- **Purge Protection**: Enabled
|
||||
- **Backup**: Enabled
|
||||
- **Monitoring**: Full observability
|
||||
|
||||
## Next Steps
|
||||
|
||||
After infrastructure is deployed:
|
||||
|
||||
1. **Configure Kubernetes secrets** (via External Secrets Operator)
|
||||
2. **Deploy services** to AKS
|
||||
3. **Set up monitoring** (Prometheus/Grafana)
|
||||
4. **Configure logging** (Fluentd/OpenSearch)
|
||||
5. **Set up CI/CD** pipelines
|
||||
|
||||
See other deployment guides for details.
|
||||
|
||||
---
|
||||
|
||||
**Last Updated**: 2025-01-27
|
||||
|
||||
123
docs/deployment/azure/ENV_FILE_ANALYSIS.md
Normal file
123
docs/deployment/azure/ENV_FILE_ANALYSIS.md
Normal file
@@ -0,0 +1,123 @@
|
||||
# .env File Analysis Report
|
||||
|
||||
**Date**: 2025-01-27
|
||||
**File**: `/home/intlc/projects/the_order/.env`
|
||||
**Status**: ✅ Valid for Azure Deployments
|
||||
|
||||
## Current Configuration (Lines 1-6)
|
||||
|
||||
```bash
|
||||
AZURE_SUBSCRIPTION_ID="70569bdd-de60-4dd1-838e-5fde7f91fe8d"
|
||||
AZURE_TENANT_ID="fb97e99d-3e94-4686-bfde-4bf4062e05f3"
|
||||
AZURE_MANAGEMENT_GROUP_ID="SOVEREIGN-ORDER-OF-HOSPITALLERS"
|
||||
AZURE_RESOURCE_GROUP=
|
||||
AZURE_LOCATION=westeurope
|
||||
```
|
||||
|
||||
## Analysis Results
|
||||
|
||||
### ✅ Required Variables - Present
|
||||
|
||||
1. **Subscription ID**: ✅ Valid UUID format
|
||||
- Value: `70569bdd-de60-4dd1-838e-5fde7f91fe8d`
|
||||
- Format: Valid UUID
|
||||
|
||||
2. **Tenant ID**: ✅ Valid UUID format
|
||||
- Value: `fb97e99d-3e94-4686-bfde-4bf4062e05f3`
|
||||
- Format: Valid UUID
|
||||
|
||||
3. **Location**: ✅ Valid non-US region
|
||||
- Value: `westeurope`
|
||||
- Compliant: Yes (non-US region as required)
|
||||
|
||||
### 📋 Optional Variables - Present
|
||||
|
||||
4. **Management Group ID**: ✅ Set
|
||||
- Value: `SOVEREIGN-ORDER-OF-HOSPITALLERS`
|
||||
- Status: Valid management group identifier
|
||||
|
||||
5. **Resource Group**: ⚠️ Empty
|
||||
- Status: Will use default naming convention from Terraform
|
||||
- Default: `az-we-rg-dev-main` (or based on environment)
|
||||
|
||||
### ⚠️ Missing Recommended Variables
|
||||
|
||||
- `TF_VAR_environment` - Will default to `dev`
|
||||
- `TF_VAR_resource_group_name` - Will use naming convention
|
||||
- `TF_VAR_storage_account_name` - Will use naming convention
|
||||
- `TF_VAR_key_vault_name` - Will use naming convention
|
||||
|
||||
## Terraform Compatibility
|
||||
|
||||
### Variable Mapping
|
||||
|
||||
The `.env` file uses `AZURE_*` prefix, but Terraform expects `ARM_*` prefix. Our scripts automatically map:
|
||||
|
||||
- `AZURE_SUBSCRIPTION_ID` → `ARM_SUBSCRIPTION_ID` ✅
|
||||
- `AZURE_TENANT_ID` → `ARM_TENANT_ID` ✅
|
||||
- `AZURE_LOCATION` → `ARM_LOCATION` ✅
|
||||
|
||||
### Recommendations
|
||||
|
||||
1. **Add ARM_* aliases** (optional but recommended):
|
||||
```bash
|
||||
ARM_SUBSCRIPTION_ID="$AZURE_SUBSCRIPTION_ID"
|
||||
ARM_TENANT_ID="$AZURE_TENANT_ID"
|
||||
ARM_LOCATION="$AZURE_LOCATION"
|
||||
```
|
||||
|
||||
2. **Add environment variable**:
|
||||
```bash
|
||||
TF_VAR_environment="dev" # or "stage" or "prod"
|
||||
```
|
||||
|
||||
3. **Add custom resource names** (optional):
|
||||
```bash
|
||||
TF_VAR_resource_group_name="the-order-rg-dev"
|
||||
TF_VAR_storage_account_name="theorderdev12345"
|
||||
TF_VAR_key_vault_name="the-order-kv-dev"
|
||||
```
|
||||
|
||||
## Validation Status
|
||||
|
||||
✅ **All required variables are present and valid**
|
||||
|
||||
The `.env` file is properly configured for Azure deployments. The validation script will:
|
||||
- Automatically map `AZURE_*` to `ARM_*` variables
|
||||
- Set defaults for missing optional variables
|
||||
- Export Terraform variables correctly
|
||||
|
||||
## Usage
|
||||
|
||||
### Validate Configuration
|
||||
```bash
|
||||
./infra/scripts/azure-validate-current-env.sh
|
||||
```
|
||||
|
||||
### Auto-fix Variable Mapping
|
||||
```bash
|
||||
./infra/scripts/azure-fix-env-mapping.sh
|
||||
```
|
||||
|
||||
### Load and Deploy
|
||||
```bash
|
||||
source infra/scripts/azure-load-env.sh
|
||||
./infra/scripts/azure-complete-setup.sh
|
||||
./infra/scripts/azure-deploy.sh
|
||||
```
|
||||
|
||||
## Summary
|
||||
|
||||
| Category | Status | Count |
|
||||
|----------|--------|-------|
|
||||
| Required Variables | ✅ Complete | 3/3 |
|
||||
| Optional Variables | ⚠️ Partial | 1/5 |
|
||||
| Format Validation | ✅ Valid | All |
|
||||
| Terraform Compatibility | ✅ Compatible | Yes |
|
||||
|
||||
**Overall Status**: ✅ **Ready for Azure Deployments**
|
||||
|
||||
---
|
||||
|
||||
**Last Updated**: 2025-01-27
|
||||
|
||||
350
docs/deployment/azure/SOVEREIGNTY_LANDING_ZONE_DEPLOYMENT.md
Normal file
350
docs/deployment/azure/SOVEREIGNTY_LANDING_ZONE_DEPLOYMENT.md
Normal file
@@ -0,0 +1,350 @@
|
||||
# Cloud for Sovereignty Landing Zone Deployment Guide
|
||||
|
||||
**Last Updated**: 2025-01-27
|
||||
**Management Group**: SOVEREIGN-ORDER-OF-HOSPITALLERS
|
||||
**Framework**: Azure Well-Architected Framework + Cloud for Sovereignty
|
||||
|
||||
## Overview
|
||||
|
||||
This guide walks through deploying a complete Cloud for Sovereignty landing zone across all non-US commercial Azure regions, using the Azure Well-Architected Framework principles.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
1. **Azure Subscription** with access to management group
|
||||
2. **Management Group**: `SOVEREIGN-ORDER-OF-HOSPITALLERS` must exist
|
||||
3. **Azure CLI** installed and authenticated
|
||||
4. **Terraform** >= 1.5.0 installed
|
||||
5. **Environment Variables** configured in `.env` file
|
||||
|
||||
## Architecture Overview
|
||||
|
||||
### Management Group Hierarchy
|
||||
|
||||
```
|
||||
SOVEREIGN-ORDER-OF-HOSPITALLERS (Root)
|
||||
├── Landing Zones
|
||||
│ ├── Platform
|
||||
│ ├── Sandbox
|
||||
│ └── Workloads
|
||||
├── Management
|
||||
│ ├── Identity
|
||||
│ ├── Security
|
||||
│ └── Monitoring
|
||||
└── Connectivity
|
||||
├── Hub Networks
|
||||
└── Spoke Networks
|
||||
```
|
||||
|
||||
### Regional Architecture
|
||||
|
||||
Each region (7 total) includes:
|
||||
- Hub Virtual Network (gateway, firewall, management)
|
||||
- Spoke Virtual Network (application, database, storage)
|
||||
- Azure Firewall
|
||||
- Key Vault with private endpoint
|
||||
- Log Analytics Workspace
|
||||
- Storage Account with private endpoint
|
||||
|
||||
## Deployment Steps
|
||||
|
||||
### Step 1: Validate Environment
|
||||
|
||||
```bash
|
||||
# Load and validate environment variables
|
||||
source infra/scripts/azure-load-env.sh
|
||||
|
||||
# Verify management group exists
|
||||
az account management-group show --name SOVEREIGN-ORDER-OF-HOSPITALLERS
|
||||
```
|
||||
|
||||
### Step 2: Deploy Management Group Hierarchy
|
||||
|
||||
```bash
|
||||
cd infra/terraform/management-groups
|
||||
|
||||
# Initialize Terraform
|
||||
terraform init
|
||||
|
||||
# Review plan
|
||||
terraform plan -var="management_group_id=SOVEREIGN-ORDER-OF-HOSPITALLERS"
|
||||
|
||||
# Apply
|
||||
terraform apply
|
||||
```
|
||||
|
||||
This creates:
|
||||
- Landing Zones management group
|
||||
- Platform, Sandbox, and Workloads groups
|
||||
- Management group (Identity, Security, Monitoring)
|
||||
- Connectivity group (Hub Networks, Spoke Networks)
|
||||
|
||||
### Step 3: Deploy Sovereignty Policies
|
||||
|
||||
```bash
|
||||
cd ../policies
|
||||
|
||||
# Initialize Terraform
|
||||
terraform init
|
||||
|
||||
# Review plan
|
||||
terraform plan -var="management_group_id=SOVEREIGN-ORDER-OF-HOSPITALLERS"
|
||||
|
||||
# Apply
|
||||
terraform apply
|
||||
```
|
||||
|
||||
This creates and assigns:
|
||||
- Allowed locations policy (non-US regions only)
|
||||
- Deny US regions policy
|
||||
- Require data residency tags
|
||||
- Require encryption at rest
|
||||
- Require resource tags
|
||||
- Policy initiative for sovereignty compliance
|
||||
|
||||
### Step 4: Deploy Multi-Region Landing Zones
|
||||
|
||||
```bash
|
||||
cd ../multi-region
|
||||
|
||||
# Initialize Terraform
|
||||
terraform init
|
||||
|
||||
# Review plan (all regions)
|
||||
terraform plan \
|
||||
-var="environment=dev" \
|
||||
-var="management_group_id=SOVEREIGN-ORDER-OF-HOSPITALLERS" \
|
||||
-var="deploy_all_regions=true"
|
||||
|
||||
# Apply
|
||||
terraform apply
|
||||
```
|
||||
|
||||
This deploys landing zones to:
|
||||
1. West Europe (Netherlands) - Primary
|
||||
2. North Europe (Ireland) - Secondary
|
||||
3. UK South (London)
|
||||
4. Switzerland North (Zurich)
|
||||
5. Norway East (Oslo)
|
||||
6. France Central (Paris)
|
||||
7. Germany West Central (Frankfurt)
|
||||
|
||||
### Step 5: Verify Deployment
|
||||
|
||||
```bash
|
||||
# Check resource groups
|
||||
az group list --query "[?contains(name, 'az-')]" --output table
|
||||
|
||||
# Check Key Vaults
|
||||
az keyvault list --query "[?contains(name, 'az-')]" --output table
|
||||
|
||||
# Check Virtual Networks
|
||||
az network vnet list --query "[?contains(name, 'az-')]" --output table
|
||||
|
||||
# Check policy compliance
|
||||
az policy state list --filter "complianceState eq 'NonCompliant'" --query "[].{Resource:resourceId, Policy:policyDefinitionName}" --output table
|
||||
```
|
||||
|
||||
## Automated Deployment
|
||||
|
||||
Use the deployment script for automated deployment:
|
||||
|
||||
```bash
|
||||
./infra/scripts/deploy-sovereignty-landing-zone.sh
|
||||
```
|
||||
|
||||
This script:
|
||||
1. Loads environment variables
|
||||
2. Deploys management group hierarchy
|
||||
3. Deploys sovereignty policies
|
||||
4. Deploys multi-region landing zones
|
||||
5. Provides deployment summary
|
||||
|
||||
## Regional Resources
|
||||
|
||||
### Per Region Resources
|
||||
|
||||
Each region deployment creates:
|
||||
|
||||
- **1 Resource Group**
|
||||
- **2 Virtual Networks** (Hub + Spoke)
|
||||
- **6 Subnets** (3 hub + 3 spoke)
|
||||
- **1 Azure Firewall**
|
||||
- **1 Public IP** (for firewall)
|
||||
- **2 VNet Peerings** (hub ↔ spoke)
|
||||
- **1 Key Vault** (with private endpoint)
|
||||
- **1 Log Analytics Workspace**
|
||||
- **1 Storage Account** (with private endpoint)
|
||||
- **2 Private Endpoints** (Key Vault + Storage)
|
||||
|
||||
### Total Resources (7 regions)
|
||||
|
||||
- **7 Resource Groups**
|
||||
- **14 Virtual Networks**
|
||||
- **42 Subnets**
|
||||
- **7 Azure Firewalls**
|
||||
- **7 Public IPs**
|
||||
- **14 VNet Peerings**
|
||||
- **7 Key Vaults**
|
||||
- **7 Log Analytics Workspaces**
|
||||
- **7 Storage Accounts**
|
||||
- **14 Private Endpoints**
|
||||
|
||||
## Network Architecture
|
||||
|
||||
### Hub Network
|
||||
|
||||
- **Gateway Subnet**: VPN/ExpressRoute connectivity
|
||||
- **Azure Firewall Subnet**: Centralized security
|
||||
- **Management Subnet**: Management and monitoring
|
||||
|
||||
### Spoke Network
|
||||
|
||||
- **Application Subnet**: Application workloads
|
||||
- **Database Subnet**: Database servers (with delegation)
|
||||
- **Storage Subnet**: Storage private endpoints
|
||||
|
||||
### Connectivity
|
||||
|
||||
- Hub and Spoke connected via VNet peering
|
||||
- Hub allows gateway transit
|
||||
- Spoke uses remote gateways
|
||||
|
||||
## Security Features
|
||||
|
||||
### Data Sovereignty
|
||||
|
||||
- **Private Endpoints**: All PaaS services use private endpoints
|
||||
- **Customer-Managed Keys**: Encryption with Key Vault
|
||||
- **Data Residency Tags**: All resources tagged with region
|
||||
- **Network Isolation**: Hub-and-spoke architecture
|
||||
|
||||
### Compliance
|
||||
|
||||
- **Azure Policies**: Enforce location and encryption
|
||||
- **Tagging**: Required tags for governance
|
||||
- **Audit Logging**: Log Analytics for all regions
|
||||
- **Access Control**: RBAC and management groups
|
||||
|
||||
## Cost Estimation
|
||||
|
||||
### Per Region (Monthly)
|
||||
|
||||
- Virtual Networks: ~$50
|
||||
- Azure Firewall: ~$1,200 (Standard SKU)
|
||||
- Key Vault: ~$15 (Premium SKU)
|
||||
- Log Analytics: ~$200-500 (data ingestion)
|
||||
- Storage Account: ~$50-200 (depending on usage)
|
||||
- Private Endpoints: ~$35 (2 endpoints)
|
||||
|
||||
**Total per region**: ~$1,550-2,000/month
|
||||
|
||||
### Multi-Region (7 regions)
|
||||
|
||||
- **Development**: ~$10,850-14,000/month
|
||||
- **Production**: ~$15,000-20,000/month (with higher usage)
|
||||
|
||||
## Monitoring
|
||||
|
||||
### Regional Monitoring
|
||||
|
||||
Each region has:
|
||||
- Log Analytics Workspace
|
||||
- Application Insights ready
|
||||
- Azure Monitor metrics
|
||||
- Network Watcher
|
||||
|
||||
### Centralized Monitoring
|
||||
|
||||
- Cross-region querying
|
||||
- Centralized dashboards
|
||||
- Alert rules per region
|
||||
- Cost tracking per region
|
||||
|
||||
## Disaster Recovery
|
||||
|
||||
### Regional Failover
|
||||
|
||||
- Primary: West Europe
|
||||
- Secondary: North Europe
|
||||
- Backup regions: Other 5 regions
|
||||
|
||||
### RTO/RPO
|
||||
|
||||
- **RTO**: 4 hours
|
||||
- **RPO**: 1 hour
|
||||
|
||||
### DR Strategy
|
||||
|
||||
1. Automated failover for critical services
|
||||
2. Manual failover for non-critical services
|
||||
3. Geo-replication for storage
|
||||
4. Cross-region backup
|
||||
|
||||
## Next Steps
|
||||
|
||||
After deployment:
|
||||
|
||||
1. **Configure Application Workloads**
|
||||
- Deploy AKS clusters per region
|
||||
- Configure application networking
|
||||
- Set up application monitoring
|
||||
|
||||
2. **Set Up Monitoring**
|
||||
- Create Grafana dashboards
|
||||
- Configure alert rules
|
||||
- Set up cost alerts
|
||||
|
||||
3. **Implement Security**
|
||||
- Configure Azure Firewall rules
|
||||
- Set up Microsoft Defender for Cloud
|
||||
- Configure Azure Sentinel
|
||||
|
||||
4. **Optimize Costs**
|
||||
- Review resource usage
|
||||
- Implement reserved instances
|
||||
- Optimize storage tiers
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Management Group Not Found
|
||||
|
||||
```bash
|
||||
# Verify management group exists
|
||||
az account management-group show --name SOVEREIGN-ORDER-OF-HOSPITALLERS
|
||||
|
||||
# Create if needed (requires appropriate permissions)
|
||||
az account management-group create --name SOVEREIGN-ORDER-OF-HOSPITALLERS
|
||||
```
|
||||
|
||||
### Policy Assignment Fails
|
||||
|
||||
```bash
|
||||
# Check policy assignment
|
||||
az policy assignment list --scope "/providers/Microsoft.Management/managementGroups/SOVEREIGN-ORDER-OF-HOSPITALLERS"
|
||||
|
||||
# Verify permissions
|
||||
az role assignment list --assignee <your-user-id>
|
||||
```
|
||||
|
||||
### Region Deployment Fails
|
||||
|
||||
```bash
|
||||
# Check resource provider registration
|
||||
az provider list --query "[?namespace=='Microsoft.Network']"
|
||||
az provider register --namespace Microsoft.Network
|
||||
|
||||
# Check quotas
|
||||
az vm list-usage --location westeurope --output table
|
||||
```
|
||||
|
||||
## References
|
||||
|
||||
- [Azure Well-Architected Framework](https://docs.microsoft.com/azure/architecture/framework/)
|
||||
- [Cloud for Sovereignty](https://azure.microsoft.com/solutions/sovereignty/)
|
||||
- [Azure Landing Zones](https://docs.microsoft.com/azure/cloud-adoption-framework/ready/landing-zone/)
|
||||
- [Management Groups](https://docs.microsoft.com/azure/governance/management-groups/)
|
||||
|
||||
---
|
||||
|
||||
**Last Updated**: 2025-01-27
|
||||
|
||||
209
docs/deployment/azure/cdn-setup.md
Normal file
209
docs/deployment/azure/cdn-setup.md
Normal file
@@ -0,0 +1,209 @@
|
||||
# Azure CDN Setup for Credential Seals
|
||||
|
||||
**Last Updated**: 2025-01-27
|
||||
**Status**: Complete and Operational
|
||||
|
||||
## Overview
|
||||
|
||||
Complete guide for setting up Azure CDN infrastructure for Order of St John credential seal images. This setup provides high-performance, globally distributed hosting for credential images used in Entra VerifiedID credentials.
|
||||
|
||||
## Quick Start
|
||||
|
||||
**One-Command Setup:**
|
||||
```bash
|
||||
./scripts/deploy/setup-azure-cdn-complete.sh
|
||||
```
|
||||
|
||||
This automates:
|
||||
1. ✅ Azure quota checking
|
||||
2. ✅ Infrastructure creation (Storage Account, Container, CDN Profile, Endpoint)
|
||||
3. ✅ File upload (all seal PNG files)
|
||||
4. ✅ Manifest URL updates
|
||||
|
||||
## Prerequisites
|
||||
|
||||
1. **Azure CLI installed**
|
||||
```bash
|
||||
# Install Azure CLI
|
||||
curl -sL https://aka.ms/InstallAzureCLIDeb | sudo bash
|
||||
```
|
||||
|
||||
2. **Logged in to Azure**
|
||||
```bash
|
||||
az login
|
||||
az account set --subscription <subscription-id>
|
||||
```
|
||||
|
||||
3. **Required Permissions**
|
||||
- Contributor or Owner role on subscription
|
||||
- Storage Account Contributor
|
||||
- CDN Contributor
|
||||
|
||||
## Architecture
|
||||
|
||||
```
|
||||
Azure Subscription
|
||||
├── Resource Group: theorder-rg-dev
|
||||
├── Storage Account: theordercdn12439 (or similar)
|
||||
│ └── Container: images (public blob access)
|
||||
├── CDN Profile: theorder-cdn-dev-profile
|
||||
│ └── CDN Endpoint: theorder-cdn-dev-endpoint
|
||||
│ └── Origin: Storage Account blob endpoint
|
||||
```
|
||||
|
||||
## Manual Setup Steps
|
||||
|
||||
### Step 1: Check Azure Quotas
|
||||
|
||||
```bash
|
||||
./infra/scripts/azure-check-cdn-quotas.sh
|
||||
```
|
||||
|
||||
This checks:
|
||||
- Storage accounts quota
|
||||
- CDN profiles quota
|
||||
- CDN endpoints quota
|
||||
- Resource group limits
|
||||
|
||||
### Step 2: Create Infrastructure
|
||||
|
||||
```bash
|
||||
./infra/scripts/azure-cdn-setup.sh
|
||||
```
|
||||
|
||||
This creates:
|
||||
- Storage account with public blob access
|
||||
- Storage container named "images"
|
||||
- CDN profile (Standard_Microsoft SKU)
|
||||
- CDN endpoint pointing to storage account
|
||||
|
||||
### Step 3: Upload Seal Images
|
||||
|
||||
```bash
|
||||
./scripts/deploy/upload-seals-to-azure.sh
|
||||
```
|
||||
|
||||
Uploads all PNG seal files to the storage container.
|
||||
|
||||
### Step 4: Update Manifest URLs
|
||||
|
||||
```bash
|
||||
./scripts/deploy/update-manifest-seal-urls.sh
|
||||
```
|
||||
|
||||
Updates all manifest templates with CDN URLs.
|
||||
|
||||
## Configuration
|
||||
|
||||
### Storage Account Settings
|
||||
|
||||
- **Account Tier**: Standard
|
||||
- **Replication**: LRS (dev/stage), GRS (production)
|
||||
- **Public Access**: Enabled (for CDN)
|
||||
- **TLS Version**: TLS 1.2 minimum
|
||||
|
||||
### CDN Settings
|
||||
|
||||
- **SKU**: Standard_Microsoft
|
||||
- **HTTPS**: Enabled
|
||||
- **Compression**: Enabled
|
||||
- **Caching**: Optimized for static content
|
||||
|
||||
### CORS Configuration
|
||||
|
||||
```bash
|
||||
az storage cors add \
|
||||
--services b \
|
||||
--methods GET HEAD \
|
||||
--origins "*" \
|
||||
--allowed-headers "*" \
|
||||
--exposed-headers "*" \
|
||||
--max-age 3600
|
||||
```
|
||||
|
||||
## URLs
|
||||
|
||||
### Direct Blob Storage URL
|
||||
```
|
||||
https://<storage-account>.blob.core.windows.net/images/<seal-file>.png
|
||||
```
|
||||
|
||||
### CDN URL (Recommended)
|
||||
```
|
||||
https://<cdn-endpoint>.azureedge.net/images/<seal-file>.png
|
||||
```
|
||||
|
||||
### Current Configuration
|
||||
- **Storage Account**: `theordercdn12439`
|
||||
- **CDN Endpoint**: `theordercdn12439.azureedge.net`
|
||||
- **Base URL**: `https://theordercdn12439.blob.core.windows.net/images/`
|
||||
|
||||
## Seal Files
|
||||
|
||||
### Available Seals
|
||||
1. `digital-bank-seal.png` - Digital Bank of International Settlements
|
||||
2. `iccc-seal.png` - International Criminal Court of Commerce
|
||||
3. `iccc-provost-marshals-seal.png` - ICCC Provost Marshals
|
||||
4. `diplomatic-security-seal.png` - Diplomatic Security Service
|
||||
5. `legal-office-seal.png` - Legal Office of the Master
|
||||
|
||||
### File Sizes
|
||||
- 200x200px: For credential logos (default)
|
||||
- 400x400px: High-resolution displays
|
||||
- 800x800px: Print/embossing
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### CDN Not Propagating
|
||||
- CDN propagation can take 10-60 minutes
|
||||
- Use direct blob URL as fallback
|
||||
- Check CDN endpoint status: `az cdn endpoint show`
|
||||
|
||||
### Access Denied
|
||||
- Verify container access type is "blob" (public)
|
||||
- Check storage account public access is enabled
|
||||
- Verify CORS configuration
|
||||
|
||||
### Quota Exceeded
|
||||
- Review quota report: `azure-cdn-quota-report.txt`
|
||||
- Request quota increase via Azure portal
|
||||
- Consider using existing storage account
|
||||
|
||||
## Maintenance
|
||||
|
||||
### Update Seal Images
|
||||
1. Convert new SVG to PNG: `./scripts/tools/convert-svg-to-png.sh`
|
||||
2. Upload to Azure: `./scripts/deploy/upload-seals-to-azure.sh`
|
||||
3. Update manifests: `./scripts/deploy/update-manifest-seal-urls.sh`
|
||||
|
||||
### Monitor Usage
|
||||
```bash
|
||||
az storage account show-usage \
|
||||
--name <storage-account> \
|
||||
--resource-group <resource-group>
|
||||
```
|
||||
|
||||
### Cost Optimization
|
||||
- Use LRS for dev/stage (lower cost)
|
||||
- Enable CDN compression
|
||||
- Set appropriate cache headers
|
||||
- Monitor and optimize file sizes
|
||||
|
||||
## Security
|
||||
|
||||
- ✅ HTTPS only (CDN enforces)
|
||||
- ✅ CORS configured
|
||||
- ✅ Public read-only access
|
||||
- ✅ No write access from public
|
||||
- ✅ Storage account firewall (optional)
|
||||
|
||||
## Related Documentation
|
||||
|
||||
- [Entra VerifiedID Setup](./entra-verifiedid.md)
|
||||
- [Deployment Overview](../overview.md)
|
||||
- [Seal Design Guide](../../design/ORDER_SEALS_DESIGN_GUIDE.md)
|
||||
|
||||
---
|
||||
|
||||
**Note**: This guide consolidates information from multiple Azure CDN setup files. Historical setup documents have been archived in `docs/archive/deployment/azure-cdn/`.
|
||||
|
||||
221
docs/deployment/azure/entra-verifiedid.md
Normal file
221
docs/deployment/azure/entra-verifiedid.md
Normal file
@@ -0,0 +1,221 @@
|
||||
# Entra VerifiedID Deployment Guide
|
||||
|
||||
**Last Updated**: 2025-01-27
|
||||
**Status**: Complete and Operational
|
||||
|
||||
## Overview
|
||||
|
||||
Complete deployment guide for Microsoft Entra VerifiedID integration, including credential issuance, verification, and webhook handling.
|
||||
|
||||
## Quick Start
|
||||
|
||||
**Automated Setup:**
|
||||
```bash
|
||||
./scripts/deploy/deploy-entra-verifiedid.sh
|
||||
```
|
||||
|
||||
## Prerequisites
|
||||
|
||||
### Azure Requirements
|
||||
1. **Azure Subscription** with active Entra ID tenant
|
||||
2. **Entra VerifiedID** service enabled
|
||||
3. **Azure Key Vault** for secret storage
|
||||
4. **Application Registration** in Entra ID
|
||||
|
||||
### Required Permissions
|
||||
- Global Administrator or Application Administrator
|
||||
- Key Vault Contributor
|
||||
- Entra ID Application Administrator
|
||||
|
||||
## Setup Steps
|
||||
|
||||
### Step 1: Enable Entra VerifiedID
|
||||
|
||||
1. Navigate to Azure Portal → Entra ID → Verified ID
|
||||
2. Enable the service
|
||||
3. Create a Verified ID credential issuer
|
||||
4. Note the **Tenant ID** and **Client ID**
|
||||
|
||||
### Step 2: Create Application Registration
|
||||
|
||||
1. Go to Azure Portal → Entra ID → App registrations
|
||||
2. Create new registration
|
||||
3. Generate **Client Secret**
|
||||
4. Grant API permissions:
|
||||
- `VerifiableCredential.Create.All`
|
||||
- `VerifiableCredential.Read.All`
|
||||
|
||||
### Step 3: Configure Key Vault
|
||||
|
||||
```bash
|
||||
az keyvault secret set \
|
||||
--vault-name <key-vault-name> \
|
||||
--name "entra-tenant-id" \
|
||||
--value "<tenant-id>"
|
||||
|
||||
az keyvault secret set \
|
||||
--vault-name <key-vault-name> \
|
||||
--name "entra-client-id" \
|
||||
--value "<client-id>"
|
||||
|
||||
az keyvault secret set \
|
||||
--vault-name <key-vault-name> \
|
||||
--name "entra-client-secret" \
|
||||
--value "<client-secret>"
|
||||
```
|
||||
|
||||
### Step 4: Create Credential Manifest
|
||||
|
||||
1. Use Azure Portal or API to create manifest
|
||||
2. Configure claims and display properties
|
||||
3. Note the **Manifest ID**
|
||||
|
||||
### Step 5: Configure Environment Variables
|
||||
|
||||
```bash
|
||||
export ENTRA_TENANT_ID="<tenant-id>"
|
||||
export ENTRA_CLIENT_ID="<client-id>"
|
||||
export ENTRA_CLIENT_SECRET="<client-secret>"
|
||||
export ENTRA_CREDENTIAL_MANIFEST_ID="<manifest-id>"
|
||||
export ENTRA_CREDENTIAL_LOGO_URI="https://theordercdn12439.blob.core.windows.net/images/digital-bank-seal.png"
|
||||
export ENTRA_CREDENTIAL_BG_COLOR="#1a1a1a"
|
||||
export ENTRA_CREDENTIAL_TEXT_COLOR="#ffffff"
|
||||
```
|
||||
|
||||
## Credential Issuance
|
||||
|
||||
### Single Manifest
|
||||
|
||||
```typescript
|
||||
import { EntraVerifiedIDClient } from '@the-order/auth';
|
||||
|
||||
const client = new EntraVerifiedIDClient({
|
||||
tenantId: process.env.ENTRA_TENANT_ID!,
|
||||
clientId: process.env.ENTRA_CLIENT_ID!,
|
||||
clientSecret: process.env.ENTRA_CLIENT_SECRET!,
|
||||
credentialManifestId: process.env.ENTRA_CREDENTIAL_MANIFEST_ID!,
|
||||
logoUri: process.env.ENTRA_CREDENTIAL_LOGO_URI,
|
||||
backgroundColor: process.env.ENTRA_CREDENTIAL_BG_COLOR,
|
||||
textColor: process.env.ENTRA_CREDENTIAL_TEXT_COLOR,
|
||||
});
|
||||
|
||||
const credential = await client.issueCredential({
|
||||
claims: {
|
||||
email: 'user@example.com',
|
||||
name: 'John Doe',
|
||||
role: 'member',
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
### Multi-Manifest Support
|
||||
|
||||
```typescript
|
||||
import { EnhancedEntraVerifiedIDClient } from '@the-order/auth';
|
||||
|
||||
const client = new EnhancedEntraVerifiedIDClient({
|
||||
tenantId: process.env.ENTRA_TENANT_ID!,
|
||||
clientId: process.env.ENTRA_CLIENT_ID!,
|
||||
clientSecret: process.env.ENTRA_CLIENT_SECRET!,
|
||||
manifests: {
|
||||
default: '<default-manifest-id>',
|
||||
financial: '<financial-manifest-id>',
|
||||
judicial: '<judicial-manifest-id>',
|
||||
diplomatic: '<diplomatic-manifest-id>',
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
## Webhook Configuration
|
||||
|
||||
### Setup Webhook Endpoint
|
||||
|
||||
1. Create webhook endpoint in your service
|
||||
2. Configure in Entra VerifiedID portal
|
||||
3. Set webhook URL: `https://your-service.com/api/webhooks/entra`
|
||||
|
||||
### Webhook Handler
|
||||
|
||||
```typescript
|
||||
app.post('/api/webhooks/entra', async (req, res) => {
|
||||
const event = req.body;
|
||||
|
||||
switch (event.type) {
|
||||
case 'credential.issued':
|
||||
// Handle credential issuance
|
||||
break;
|
||||
case 'credential.verified':
|
||||
// Handle credential verification
|
||||
break;
|
||||
}
|
||||
|
||||
res.status(200).send('OK');
|
||||
});
|
||||
```
|
||||
|
||||
## Best Practices
|
||||
|
||||
### Security
|
||||
- ✅ Store secrets in Azure Key Vault
|
||||
- ✅ Use managed identities where possible
|
||||
- ✅ Rotate client secrets regularly
|
||||
- ✅ Enable audit logging
|
||||
- ✅ Use HTTPS for all endpoints
|
||||
|
||||
### Performance
|
||||
- ✅ Implement retry logic with exponential backoff
|
||||
- ✅ Use connection pooling
|
||||
- ✅ Cache manifest configurations
|
||||
- ✅ Monitor API rate limits
|
||||
|
||||
### Reliability
|
||||
- ✅ Implement circuit breakers
|
||||
- ✅ Add health checks
|
||||
- ✅ Monitor webhook delivery
|
||||
- ✅ Handle webhook retries
|
||||
|
||||
## Monitoring
|
||||
|
||||
### Metrics
|
||||
- Credential issuance rate
|
||||
- Credential verification rate
|
||||
- API error rates
|
||||
- Webhook delivery success rate
|
||||
- Average issuance time
|
||||
|
||||
### Alerts
|
||||
- High error rates
|
||||
- Webhook delivery failures
|
||||
- API quota approaching limits
|
||||
- Authentication failures
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Common Issues
|
||||
|
||||
**Authentication Failures**
|
||||
- Verify tenant ID and client ID
|
||||
- Check client secret is correct
|
||||
- Ensure API permissions are granted
|
||||
|
||||
**Manifest Not Found**
|
||||
- Verify manifest ID is correct
|
||||
- Check manifest is active
|
||||
- Ensure proper permissions
|
||||
|
||||
**Webhook Not Receiving Events**
|
||||
- Verify webhook URL is accessible
|
||||
- Check webhook configuration in portal
|
||||
- Review webhook logs
|
||||
|
||||
## Related Documentation
|
||||
|
||||
- [Azure CDN Setup](./cdn-setup.md)
|
||||
- [Deployment Overview](../overview.md)
|
||||
- [Entra VerifiedID Integration](../../integrations/entra-verifiedid/README.md)
|
||||
- [Operations Runbook](../../operations/ENTRA_VERIFIEDID_RUNBOOK.md)
|
||||
|
||||
---
|
||||
|
||||
**Note**: This guide consolidates information from multiple Entra VerifiedID deployment files. Historical deployment documents have been archived in `docs/archive/deployment/entra/`.
|
||||
|
||||
100
docs/deployment/github-setup.md
Normal file
100
docs/deployment/github-setup.md
Normal file
@@ -0,0 +1,100 @@
|
||||
# GitHub Authentication Setup
|
||||
|
||||
## Current Status
|
||||
|
||||
✅ **Commit ready to push:** `2633de4 feat(eresidency): Complete eResidency service implementation`
|
||||
✅ **SSH key generated:** `~/.ssh/id_ed25519`
|
||||
✅ **Remote configured:** `git@github.com:Order-of-Hospitallers/the-order-monorepo.git`
|
||||
⚠️ **Push blocked:** SSH key needs to be added to GitHub
|
||||
|
||||
## Your SSH Public Key
|
||||
|
||||
```
|
||||
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIGb+gFevwMFw/Li1JLyIvpYZ4O6/f1KHutekqtPapY/l defi@defi-oracle.io
|
||||
```
|
||||
|
||||
## Quick Setup (SSH - Recommended)
|
||||
|
||||
1. **Copy your SSH public key:**
|
||||
|
||||
```bash
|
||||
cat ~/.ssh/id_ed25519.pub
|
||||
```
|
||||
|
||||
2. **Add to GitHub:**
|
||||
- Visit: https://github.com/settings/keys
|
||||
- Click "New SSH key"
|
||||
- Title: `WSL2 - the-order-monorepo`
|
||||
- Paste the public key
|
||||
- Click "Add SSH key"
|
||||
|
||||
3. **Test connection:**
|
||||
|
||||
```bash
|
||||
ssh -T git@github.com
|
||||
```
|
||||
|
||||
You should see: `Hi defiQUG! You've successfully authenticated...`
|
||||
|
||||
4. **Push your commit:**
|
||||
```bash
|
||||
git push
|
||||
```
|
||||
Or use the script:
|
||||
```bash
|
||||
./scripts/push-to-github.sh
|
||||
```
|
||||
|
||||
## Alternative: Personal Access Token (HTTPS)
|
||||
|
||||
If you prefer HTTPS:
|
||||
|
||||
1. **Create a Personal Access Token:**
|
||||
- Visit: https://github.com/settings/tokens
|
||||
- Click "Generate new token (classic)"
|
||||
- Select `repo` scope
|
||||
- Generate and copy the token
|
||||
|
||||
2. **Configure credential helper:**
|
||||
|
||||
```bash
|
||||
git config --global credential.helper store
|
||||
```
|
||||
|
||||
3. **Update remote URL:**
|
||||
|
||||
```bash
|
||||
git remote set-url origin https://github.com/Order-of-Hospitallers/the-order-monorepo.git
|
||||
```
|
||||
|
||||
4. **Push (enter token as password):**
|
||||
```bash
|
||||
git push
|
||||
Username: defiQUG
|
||||
Password: <paste-your-token-here>
|
||||
```
|
||||
|
||||
## Verification
|
||||
|
||||
After pushing, verify with:
|
||||
|
||||
```bash
|
||||
git log --oneline origin/main..HEAD
|
||||
```
|
||||
|
||||
Should show no commits (all pushed).
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
- **Permission denied:** Make sure SSH key is added to GitHub
|
||||
- **Key not found:** Run `ssh-add ~/.ssh/id_ed25519`
|
||||
- **Connection timeout:** Check your internet connection
|
||||
- **Wrong key:** Verify key fingerprint matches GitHub
|
||||
|
||||
## Next Steps
|
||||
|
||||
Once pushed, your changes will be available on GitHub and can be:
|
||||
|
||||
- Reviewed in pull requests
|
||||
- Deployed via CI/CD
|
||||
- Collaborated on with team members
|
||||
Reference in New Issue
Block a user