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

PracticeDescription
Tag resources at creationEnable lifecycle tracking
Implement storage lifecycleMove cold data to cheaper tiers
Automate cleanupSchedule regular cleanup jobs
Monitor dead letter queuesPrevent message buildup
Set retention policiesMatch business requirements
Review regularlyQuarterly 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


Azure Integration Hub - Architect Level Cost Architecture & FinOps