Best Practices Guide
This guide provides recommended best practices for deploying, configuring, and maintaining TenuVault in production environments. Following these guidelines will help you maximize reliability, security, and efficiency while minimizing costs and operational overhead.
Table of Contents
- Deployment Best Practices
- Backup Strategy
- Security Best Practices
- Storage Optimization
- Performance Optimization
- Monitoring and Alerting
- Change Management
- Disaster Recovery
- Cost Optimization
- Compliance and Governance
- Team Management
- Maintenance and Updates
Deployment Best Practices
Architecture Recommendations
Single-Tenant Deployment
Resource Group: rg-tenuvault-prod
├── App Service: asp-tenuvault-prod (B2 or higher)
├── Storage Account: sttenuvaultprod (LRS)
├── Automation Account: aa-tenuvault-prod
├── Key Vault: kv-tenuvault-prod
└── Application Insights: ai-tenuvault-prodMulti-Tenant Deployment
For MSPs or large enterprises:Resource Group: rg-tenuvault-shared
├── App Service: asp-tenuvault-shared (S2 or higher)
├── Storage Accounts (per tenant):
│ ├── sttenuvaultclient1
│ ├── sttenuvaultclient2
│ └── sttenuvaultclient3
├── Automation Account: aa-tenuvault-shared
├── Key Vault: kv-tenuvault-shared
└── Application Insights: ai-tenuvault-sharedResource Sizing Guidelines
Small Organization (< 500 devices)
- App Service Plan: B1 or B2
- Storage: Standard LRS, 100GB
- Automation: Basic tier
- Backup Frequency: Daily
- Retention: 30 days
Medium Organization (500-5000 devices)
- App Service Plan: S1 or S2
- Storage: Standard GRS, 500GB
- Automation: Basic tier
- Backup Frequency: Twice daily
- Retention: 90 days
Large Organization (> 5000 devices)
- App Service Plan: P1V2 or higher
- Storage: Premium ZRS, 1TB+
- Automation: Premium tier
- Backup Frequency: Every 6 hours
- Retention: 180 days
Network Architecture
Security Zones
Internet
│
├── WAF/CDN (Optional)
│
├── App Service (Public endpoint)
│
├── Private Endpoint
│ ├── Storage Account
│ ├── Key Vault
│ └── Automation Account
│
└── ExpressRoute/VPN (For hybrid)Private Endpoints
Configure private endpoints for enhanced security:# Create private endpoint for storage
$privateEndpointConnection = New-AzPrivateLinkServiceConnection `
-Name "pe-storage-connection" `
-PrivateLinkServiceId $storageAccount.Id `
-GroupId "blob"
New-AzPrivateEndpoint `
-ResourceGroupName "rg-tenuvault" `
-Name "pe-storage" `
-Location "eastus" `
-Subnet $subnet `
-PrivateLinkServiceConnection $privateEndpointConnectionBackup Strategy
Scheduling Best Practices
Optimal Backup Windows
Choose backup times based on your timezone and usage patterns:Production Environments
- Primary: 2:00 AM local time (low activity)
- Secondary: 2:00 PM local time (lunch hours)
- Avoid: 8-10 AM, 4-6 PM (peak hours)
Global Organizations
Americas: 02:00 EST
EMEA: 02:00 CET
APAC: 02:00 JSTFrequency Recommendations
| Environment Type | Frequency | Rationale |
| Production | Every 12 hours | Balance between data protection and resource usage |
| UAT/Staging | Daily | Less critical, still needs protection |
| Development | Weekly | Mainly for configuration templates |
| Pilot Programs | Every 6 hours | Rapid changes, need quick recovery |
| Static Configs | Monthly | Rarely change, archive purposes |
Backup Scope Optimization
Critical vs Non-Critical
Prioritize critical configurations:Tier 1 - Critical (Every backup)
- Compliance policies
- Security baselines
- Conditional Access
- Device restrictions
- Encryption policies
Tier 2 - Important (Daily)
- App protection policies
- Configuration profiles
- Autopilot profiles
- Update rings
Tier 3 - Standard (Weekly)
- Scripts and remediations
- App configurations
- Enrollment pages
- Terms and conditions
Incremental Backup Strategy
# Daily full backup
if ($DayOfWeek -eq "Sunday") {
Backup-IntuneConfiguration -Type Full
} else {
# Incremental on other days
Backup-IntuneConfiguration -Type Incremental -Since $LastBackup
}Retention Policies
Tiered Retention Model
Implement grandfather-father-son rotation:Daily Backups: Keep 7 days
Weekly Backups: Keep 4 weeks
Monthly Backups: Keep 12 months
Yearly Backups: Keep 7 yearsAutomated Lifecycle Management
Configure storage lifecycle policies:{
"rules": [
{
"name": "MoveToCooldocuments",
"type": "Lifecycle",
"definition": {
"actions": {
"baseBlob": {
"tierToCool": {
"daysAfterModificationGreaterThan": 30
},
"tierToArchive": {
"daysAfterModificationGreaterThan": 90
},
"delete": {
"daysAfterModificationGreaterThan": 2555
}
}
}
}
}
]
}Security Best Practices
Authentication and Authorization
Service Principal Management
Best practices for service principals:1. Separate Service Principals - One for portal authentication - One for backup operations - One for drift detection - Principle of least privilege
2. Secret Rotation
# Automate secret rotation every 90 days
$newSecret = New-AzADAppCredential `
-ObjectId $appObjectId `
-EndDate (Get-Date).AddDays(90)
# Update Key Vault
Set-AzKeyVaultSecret `
-VaultName "kv-tenuvault" `
-Name "ClientSecret" `
-SecretValue (ConvertTo-SecureString $newSecret.SecretText -AsPlainText -Force)
3. Certificate-Based Authentication Prefer certificates over secrets:
# Create self-signed certificate
$cert = New-SelfSignedCertificate `
-Subject "CN=TenuVault" `
-CertStoreLocation "Cert:\CurrentUser\My" `
-KeyExportPolicy Exportable `
-KeySpec Signature `
-KeyLength 2048 `
-KeyAlgorithm RSA `
-HashAlgorithm SHA256
Role-Based Access Control
Implement proper RBAC:
TenuVault Administrator
- Full portal access
- Backup/restore permissions
- Configuration management
- User management
TenuVault Operator
- View backups
- Trigger manual backups
- View reports
- No restore permissions
TenuVault Viewer
- Read-only access
- View reports
- No operational permissions
Data Protection
Encryption Standards
At Rest
- Storage Service Encryption (SSE)
- Customer-managed keys (CMK)
- Azure Disk Encryption for VMs
In Transit
- TLS 1.2 minimum
- Certificate pinning
- Perfect forward secrecy
Backup Encryption
# Encrypt backup before storage
$encryptedBackup = Protect-CmsMessage `
-To $certificateThumbprint `
-Content $backupJsonNetwork Security
Firewall Rules
Configure storage firewall:# Allow only specific IPs
Update-AzStorageAccountNetworkRuleSet `
-ResourceGroupName "rg-tenuvault" `
-Name "sttenuvault" `
-DefaultAction Deny `
-IPRule @{IPAddressOrRange="203.0.113.0/24"}Private Endpoints
Implement private endpoints for all services:- Storage accounts
- Key Vault
- SQL databases (if used)
- App Services
Storage Optimization
Compression Strategies
Compression Levels
| Level | Compression Ratio | Speed | Use Case |
| None | 1:1 | Fastest | Real-time access needed |
| Fast | 2:1 | Fast | Default for most |
| Normal | 3:1 | Moderate | Standard backups |
| Maximum | 4:1 | Slow | Long-term archives |
Implementation
# Compress before storage
$compressed = [System.IO.Compression.GZipStream]::new(
$outputStream,
[System.IO.Compression.CompressionLevel]::Optimal
)Deduplication
Policy-Level Deduplication
Store unique policies once:# Calculate hash for deduplication
$policyHash = Get-FileHash -InputStream ([System.IO.MemoryStream]::new([System.Text.Encoding]::UTF8.GetBytes($policyJson))) -Algorithm SHA256
# Check if already exists
if (-not (Test-BlobExists -Hash $policyHash)) {
Upload-Blob -Content $policyJson -Metadata @{Hash=$policyHash}
}Cross-Tenant Deduplication
For multi-tenant deployments:- Shared policy repository
- Reference counting
- Copy-on-write for modifications
Storage Tiers
Tier Selection Matrix
Age Access Frequency Recommended Tier Cost/GB
| 0-30 days | Daily | Hot | $0.0184 |
| 31-90 days | Weekly | Cool | $0.01 |
| 91-180 days | Monthly | Cool | $0.01 |
| 180+ days | Rarely | Archive | $0.00099 |
Automated Tiering
# Move to appropriate tier based on age
$blobs = Get-AzStorageBlob -Container "backups"
foreach ($blob in $blobs) {
$age = (Get-Date) - $blob.LastModified
if ($age.Days -gt 180) {
$blob.ICloudBlob.SetStandardBlobTier("Archive")
} elseif ($age.Days -gt 30) {
$blob.ICloudBlob.SetStandardBlobTier("Cool")
}
}Performance Optimization
API Optimization
Batch Operations
Minimize API calls:# Bad: Individual calls
foreach ($policy in $policies) {
Get-IntunePolicy -Id $policy.Id
}
# Good: Batch request
$batch = @{
requests = $policies | ForEach-Object {
@{
id = $_.Id
method = "GET"
url = "/deviceManagement/deviceConfigurations/$($_.Id)"
}
}
}
Invoke-MgGraphRequest -Method POST -Uri "https://graph.microsoft.com/v1.0/`$batch" -Body $batchPagination Handling
Efficient pagination:$allPolicies = @()
$nextLink = "https://graph.microsoft.com/v1.0/deviceManagement/deviceConfigurations"
while ($nextLink) {
$response = Invoke-MgGraphRequest -Uri $nextLink
$allPolicies += $response.value
$nextLink = $response.'@odata.nextLink'
}Caching Strategies
Redis Cache Implementation
For frequently accessed data:# Cache configuration
$redis = Connect-RedisCache -ConnectionString $redisConnection
# Cache backup metadata
$cacheKey = "backup:metadata:$tenantId"
$cached = Get-RedisCache -Key $cacheKey
if (-not $cached) {
$metadata = Get-BackupMetadata -TenantId $tenantId
Set-RedisCache -Key $cacheKey -Value $metadata -Expiry 3600
}Local Caching
Browser-side caching:// Cache API responses
const cache = new Map();
const cacheTimeout = 5 * 60 * 1000; // 5 minutes
function getCachedData(key) {
const cached = cache.get(key);
if (cached && Date.now() - cached.timestamp < cacheTimeout) {
return cached.data;
}
return null;
}Database Optimization
Index Strategy
Key indexes for performance:-- Backup metadata queries
CREATE INDEX idx_backup_tenant_date ON backups(tenant_id, backup_date DESC);
CREATE INDEX idx_backup_status ON backups(status) WHERE status != 'success';
-- Drift detection queries
CREATE INDEX idx_drift_severity ON drift_events(severity, detected_at DESC);
CREATE INDEX idx_drift_tenant ON drift_events(tenant_id, detected_at DESC);Monitoring and Alerting
Key Metrics to Monitor
System Health Metrics
Availability Metrics
- Portal uptime (target: 99.9%)
- API availability
- Storage accessibility
- Automation success rate
Performance Metrics
- Backup duration trend
- API response times
- Storage I/O operations
- Queue depths
Capacity Metrics
- Storage utilization
- Compute usage
- Network bandwidth
- API rate limit usage
Alert Configuration
Critical Alerts (Immediate)
{
"alerts": [
{
"name": "Backup Failed",
"condition": "backup_status == 'failed'",
"action": ["email", "sms", "teams"],
"severity": "critical"
},
{
"name": "Storage Full",
"condition": "storage_usage > 90%",
"action": ["email", "autoscale"],
"severity": "critical"
}
]
}Warning Alerts (Within hours)
- Backup duration > 2x average
- Drift detection > threshold
- Failed authentication attempts
- Certificate expiration < 30 days
Informational Alerts (Daily digest)
- Daily backup summary
- Storage growth rate
- Cost projections
- User activity summary
Dashboard Configuration
Executive Dashboard
- Backup success rate (30-day)
- Storage cost trend
- Compliance score
- Critical issues count
Operations Dashboard
- Real-time backup status
- Queue depth
- API throttling
- Error rates by type
Security Dashboard
- Authentication failures
- Unauthorized access attempts
- Configuration changes
- Drift detection summary
Change Management
Change Control Process
Standard Changes
- Backup schedule adjustments
- Report generation
- User access updates
- Tag modifications
Normal Changes
- Portal configuration
- Retention policy updates
- Network changes
- Integration modifications
Emergency Changes
- Security patches
- Critical bug fixes
- Compliance requirements
- Incident response
Documentation Standards
Change Documentation
## Change Request: CR-2024-001
**Summary**: Update backup retention from 30 to 90 days
**Requester**: John Doe
**Approver**: Jane Smith
**Risk Level**: Low
**Rollback Plan**: Revert storage lifecycle policy
### Implementation Steps
1. Update lifecycle management rules
2. Verify in test environment
3. Apply to production
4. Monitor for 24 hours
### Verification
- [ ] Lifecycle rules updated
- [ ] Old backups retained
- [ ] Cost impact assessedTesting Procedures
Test Environment
Maintain separate test instance:- Same configuration as production
- Subset of real data
- Isolated network
- Regular refresh from production
Test Scenarios
- 1Backup and restore cycle
- 1Drift detection accuracy
- 1Alert generation
- 1Performance under load
- 1Failure recovery
Disaster Recovery
RTO and RPO Targets
Service Level Objectives
Component RTO RPO Priority
| Portal Access | 4 hours | N/A | High |
| Backup Operations | 8 hours | 12 hours | Critical |
| Restore Capability | 2 hours | 0 | Critical |
| Reporting | 24 hours | 24 hours | Medium |
| Drift Detection | 12 hours | 24 hours | Medium |
DR Architecture
Active-Passive Setup
Primary and standby regions:Primary Region (East US)
├── Production Resources
├── Live Traffic
└── Active Backups
Secondary Region (West US)
├── Standby Resources
├── Replicated Storage
└── Cold StandbyFailover Process
- 1Detect failure in primary
- 1Verify secondary readiness
- 1Update DNS records
- 1Activate secondary resources
- 1Redirect traffic
- 1Verify operations
Backup Validation
Regular Testing
# Select random backup for restoration test
$testBackup = Get-Random -InputObject (Get-RecentBackups -Days 30)
# Restore to test environment
$result = Test-BackupRestoration `
-BackupId $testBackup.Id `
-TargetEnvironment "Test" `
-ValidateOnly
# Generate report
New-ValidationReport -Result $resultCost Optimization
Resource Right-Sizing
Regular Review Process
Quarterly optimization:- 1Analyze usage metrics
- 1Identify underutilized resources
- 1Recommend sizing changes
- 1Test in non-production
- 1Apply to production
Auto-Scaling Configuration
{
"autoscale": {
"minInstances": 1,
"maxInstances": 4,
"rules": [
{
"metric": "CPU",
"threshold": 70,
"action": "scaleOut"
},
{
"metric": "Memory",
"threshold": 80,
"action": "scaleOut"
}
]
}
}Storage Cost Management
Lifecycle Optimization
Aggressive archival for cost savings:# Archive everything older than 30 days
$lifecycle = @{
Rules = @(
@{
Name = "ArchiveOldBackups"
Definition = @{
Actions = @{
BaseBlob = @{
TierToArchive = @{
DaysAfterModificationGreaterThan = 30
}
}
}
}
}
)
}Reserved Capacity
Purchase reserved capacity:- 1-year reservation: 38% savings
- 3-year reservation: 51% savings
- Calculate based on baseline usage
Monitoring Costs
Cost Alerts
New-AzConsumptionBudget `
-Name "TenuVault-Monthly" `
-Amount 500 `
-TimeGrain Monthly `
-StartDate (Get-Date -Day 1) `
-ContactEmail "admin@company.com" `
-NotificationThreshold 80,100Compliance and Governance
Regulatory Compliance
Data Residency
Ensure compliance with data laws:- GDPR: EU data stays in EU
- CCPA: California data protection
- HIPAA: Healthcare data requirements
- SOC 2: Security controls
Audit Trail Requirements
# Log all operations
function Write-AuditLog {
param($Action, $User, $Details)
$log = @{
Timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
Action = $Action
User = $User
Details = $Details
IPAddress = $env:REMOTE_ADDR
}
# Write to multiple destinations
Write-EventLog -LogName "TenuVault" -Source "Audit" -Message ($log | ConvertTo-Json)
Send-LogAnalytics -Workspace $workspaceId -Data $log
}Policy Enforcement
Backup Policies
Enforce organizational policies:{
"backupPolicy": {
"minimumFrequency": "daily",
"minimumRetention": 90,
"requiredEncryption": true,
"allowedRegions": ["eastus", "westus"],
"mandatoryTags": ["environment", "owner", "costcenter"]
}
}Team Management
Role Definition
Team Structure
Recommended team organization:TenuVault Admin Team
- Portal administration
- User management
- Configuration changes
- Incident response
Backup Operations Team
- Monitor backups
- Handle failures
- Perform restorations
- Maintain schedules
Security Team
- Access reviews
- Drift monitoring
- Security updates
- Compliance audits
Training Requirements
Onboarding Checklist
- [ ] Portal access provisioned
- [ ] Role assignment completed
- [ ] Documentation provided
- [ ] Shadowing scheduled
- [ ] Test environment access
- [ ] First backup supervised
- [ ] Restoration practice
- [ ] Incident response training
Knowledge Management
Documentation Requirements
- Architecture diagrams
- Runbooks
- Troubleshooting guides
- Contact lists
- Escalation procedures
Maintenance and Updates
Regular Maintenance Tasks
Daily Tasks
- Review backup status
- Check alerts
- Monitor storage
- Verify automation
Weekly Tasks
- Analyze trends
- Review drift reports
- Update documentation
- Team sync meeting
Monthly Tasks
- Validate backups
- Review costs
- Update baselines
- Security review
Quarterly Tasks
- DR testing
- Capacity planning
- Policy review
- Training updates
Update Management
TenuVault Updates
# Check for updates
$currentVersion = Get-TenuVaultVersion
$latestVersion = Get-LatestTenuVaultVersion
if ($currentVersion -lt $latestVersion) {
# Plan update
New-ChangeRequest -Type "Update" -Version $latestVersion
}Dependency Updates
Regular updates for:- PowerShell modules
- Azure services
- Security patches
- Framework updates
Health Checks
Automated Health Monitoring
# Daily health check script
function Test-TenuVaultHealth {
$health = @{
Portal = Test-PortalHealth
Storage = Test-StorageHealth
Automation = Test-AutomationHealth
API = Test-APIHealth
}
if ($health.Values -contains $false) {
Send-Alert -Severity "Warning" -Message "Health check failed"
}
return $health
}Summary
Implementing these best practices will help you:
- Maximize reliability through proper architecture and redundancy
- Enhance security with defense-in-depth strategies
- Optimize performance via caching and efficient operations
- Control costs through right-sizing and lifecycle management
- Ensure compliance with comprehensive auditing and governance
- Improve operations with monitoring and automation
Remember that best practices evolve. Regularly review and update your implementation based on:
- New features and capabilities
- Lessons learned from incidents
- Changes in your environment
- Industry developments
- Regulatory updates
Success with TenuVault comes from continuous improvement and adaptation to your organization's unique needs.
---
For specific implementation details, refer to the Onboarding Guide. For operational procedures, see the User Guide.