Lifecycle Policies as Cost Control
Managing Data and Resource Lifecycle
Introduction
Azure resources and data have lifecycles—creation, use, and eventual retirement. Without lifecycle management, old data, unused resources, and temporary assets accumulate, driving up costs silently. Implementing lifecycle policies ensures resources and data are properly managed from birth to disposal, maintaining cost efficiency while meeting retention requirements.
This comprehensive guide covers:
- Resource lifecycle — Resource creation and retirement
- Data lifecycle — Storage tiering and deletion
- Azure policies — Lifecycle automation
- Cost optimization — Reducing waste
- Compliance — Meeting retention requirements
Resource Lifecycle
Resource Lifecycle Stages
┌─────────────────────────────────────────────────────────────────────┐
│ RESOURCE LIFECYCLE STAGES │
├─────────────────────────────────────────────────────────────────────┤
│ │
│ CREATE │
│ ───── │
│ • Provision with correct sizing │
│ • Apply tagging (environment, owner, cost center) │
│ • Configure monitoring │
│ • Set budget alerts │
│ │
│ USE │
│ ─── │
│ • Active management and optimization │
│ • Regular utilization review │
│ • Performance monitoring │
│ • Security patching │
│ │
│ MONITOR │
│ ────── │
│ • Track idle resources │
│ • Identify underutilized │
│ • Review cost trends │
│ │
│ RETIRE │
│ ────── │
│ • Decommission unused │
│ • Archive data if needed │
│ • Clean up dependencies │
│ • Delete resources │
│ │
└─────────────────────────────────────────────────────────────────────┘
Resource Lifecycle Automation
public class ResourceLifecycleManager
{
public async Task<List<IdleResource>> FindIdleResourcesAsync(
TimeRange inactivePeriod)
{
var resources = await GetAllResourcesAsync();
var idleResources = new List<IdleResource>();
foreach (var resource in resources)
{
var lastActivity = await GetLastActivityAsync(resource);
if (lastActivity < DateTime.UtcNow - inactivePeriod)
{
idleResources.Add(new IdleResource
{
Resource = resource,
DaysInactive = (DateTime.UtcNow - lastActivity).Days,
EstimatedMonthlyCost = resource.MonthlyCost,
Recommendation = GetRecommendation(resource, lastActivity)
});
}
}
return idleResources;
}
private string GetRecommendation(Resource resource, DateTime lastActivity)
{
var inactiveDays = (DateTime.UtcNow - lastActivity).Days;
if (inactiveDays > 90)
return "Delete - likely unused";
else if (inactiveDays > 30)
return "Stop/hibernate - may be needed";
else
return "Monitor - temporary inactivity";
}
}
Data Lifecycle Management
Azure Storage Lifecycle
{
"storageLifecycle": {
"policies": [
{
"name": "hot-to-cool",
"enabled": true,
"rules": [
{
"name": "move-to-cool",
"enabled": true,
"type": "Lifecycle",
"definition": {
"filters": {
"blobTypes": ["blockBlob"],
"prefixMatch": ["container1/logs", "container2/exports"]
},
"actions": {
"baseBlob": {
"tierToCool": {
"daysAfterModificationGreaterThan": 30
},
"delete": {
"daysAfterModificationGreaterThan": 365
}
}
}
}
},
{
"name": "archive-old-logs",
"enabled": true,
"definition": {
"filters": {
"blobTypes": ["blockBlob"],
"prefixMatch": ["container1/archivelogs"]
},
"actions": {
"baseBlob": {
"tierToArchive": {
"daysAfterModificationGreaterThan": 90
},
"delete": {
"daysAfterModificationGreaterThan": 2555
}
}
}
}
}
]
}
]
}
}
Implementing Lifecycle Policies
# Create lifecycle management policy
az storage account management-policy create \
--account-name mystorageaccount \
--resource-group my-rg \
--policy '@policy.json'
# View policy
az storage account management-policy show \
--account-name mystorageaccount \
--resource-group my-rg
# Test with dry-run
az storage blob start-delete-blob \
--container-name logs \
--name old-log-file.log \
--dry-run
Queue and Message Lifecycle
Service Bus Message Expiration
# Set default TTL for queue
az servicebus queue create \
--name orders-queue \
--namespace-name mynamespace \
--resource-group my-rg \
--default-message-time-to-live P7D \
--lock-duration PT1M \
--max-delivery-count 3
# Enable auto-forward for archiveling
az servicebus queue create \
--name archive-queue \
--namespace-name mynamespace \
--resource-group my-rg
# Update primary queue to forward
az servicebus queue update \
--name orders-queue \
--namespace-name mynamespace \
--resource-group my-rg \
--forward-to archive-queue
Dead Letter Queue Management
{
"dlqManagement": {
"maxDeliveryCount": 3,
"ttl": "P7D",
"processing": {
"frequency": "Daily",
"retention": "30 days",
"alertOnBuildup": "If > 1000 messages"
}
}
}
Integration Service Lifecycle
Function App Cleanup
{
"functionLifecycle": {
"versions": {
"keepActiveVersions": 3,
"autoDeleteAfterDays": 30
},
"deployment": {
"autoCleanupOldDeployments": true,
"keepLastN": 5
},
"logs": {
"retentionDays": 30,
"storageTier": "Cool"
}
}
}
Logic Apps Lifecycle
{
"logicAppLifecycle": {
"runs": {
"retentionDays": 90,
"cleanupFrequency": "Daily"
},
"history": {
"retentionDays": 30,
"archiveToStorage": true
},
"versions": {
"keepLastN": 10,
"autoDeleteDays": 60
}
}
}
Cost Optimization Rules
Lifecycle-Based Actions
┌─────────────────────────────────────────────────────────────────────┐
│ LIFECYCLE COST ACTIONS │
├─────────────────────────────────────────────────────────────────────┤
│ │
│ RESOURCE TYPE AGE ACTION SAVINGS │
│ ─────────────────────────────────────────────────────────────── │
│ Dev VM 30 days idle Delete 100% │
│ Staging VM 7 days idle Stop 70% │
│ Dev storage 90 days Move to Cool 40% │
│ Production storage 1 year Move to Archive 60% │
│ Old function app 60 days unused Delete 100% │
│ Test data in blob 30 days Delete 100% │
│ Expired logs 90 days Delete 100% │
│ Old backups 30 days Delete 100% │
│ │
└─────────────────────────────────────────────────────────────────────┘
Compliance and Retention
Retention Requirements
{
"retentionRequirements": {
"financial": {
"billingRecords": "7 years",
"invoices": "7 years",
"costReports": "5 years"
},
"operational": {
"deploymentLogs": "2 years",
"auditLogs": "1 year",
"performanceMetrics": "90 days"
},
"integration": {
"messageLogs": "30 days",
"transactionHistory": "3 years",
"errorLogs": "90 days"
}
}
}
Best Practices
Implementation Checklist
| Practice | Description |
|---|---|
| Tag resources at creation | Enable lifecycle tracking |
| Implement storage lifecycle | Move cold data to cheaper tiers |
| Automate cleanup | Schedule regular cleanup jobs |
| Monitor dead letter queues | Prevent message buildup |
| Set retention policies | Match business requirements |
| Review regularly | Quarterly lifecycle review |
Automation Schedule
┌─────────────────────────────────────────────────────────────────────┐
│ LIFECYCLE AUTOMATION SCHEDULE │
├─────────────────────────────────────────────────────────────────────┤
│ │
│ DAILY: │
│ • Process dead letter queues │
│ • Archive old workflow runs │
│ • Check for stopped resources │
│ │
│ WEEKLY: │
│ • Identify idle resources │
│ • Review storage lifecycle policies │
│ • Archive old logs to cold storage │
│ │
│ MONTHLY: │
│ • Review retention policy compliance │
│ • Cleanup old backups │
│ • Update lifecycle configurations │
│ │
└─────────────────────────────────────────────────────────────────────┘
Related Topics
- Cost Management — Budget and alerts
- Right-Sizing — Resource optimization
- FinOps Framework — Cost culture
Azure Integration Hub - Architect Level Cost Architecture & FinOps