The Problem
The March invoice arrived. It was $47,000. The February invoice was $23,000. Finance wanted an explanation by end of day.
Nobody was watching the bill. The cloud provider has a billing dashboard. It has alerts. Nobody configured them. The team assumed someone else was monitoring costs. Nobody was.
The investigation took three days. The spike was caused by a Kubernetes deployment that autoscaled to 100 replicas during a load test. The load test ran on Thursday. The replicas were never scaled back down because the HPA minReplicas was accidentally set to the same value as maxReplicas during debugging. 100 replicas ran for 10 days at $4/hour each before anyone noticed.
Right-sizing recommendations existed but were ignored. The cloud provider's cost advisor had been recommending smaller instance types for six months. The recommendations were in a CSV export that a platform engineer downloaded once, looked at, and forgot about. The oversized instances cost an extra $8,000 per month.
Cost allocation was impossible. Finance asked: "How much does the Order Service cost per month?" Nobody could answer. The Kubernetes cluster ran 12 services on shared nodes. The database was shared. The load balancer was shared. There were no cost allocation tags. The best anyone could do was divide the total bill by 12, which was useless.
Spot instances were not used. The workload was stateless and fault-tolerant -- a perfect candidate for spot instances at 70% discount. But nobody configured spot because the last time someone tried, the instances were reclaimed during a demo and the CTO said "never again." There was no fallback-to-on-demand policy.
What is missing:
- Budget declarations in code. Every service should declare its expected monthly cost. Alerts should fire when spending exceeds thresholds.
- Right-sizing as a scheduled review. Instance sizes should be evaluated against actual utilization on a declared schedule.
- Cost tags generated from service metadata. Every resource should be tagged for cost allocation, automatically.
- Spot policies with fallback. Spot usage should be declared with explicit fallback behavior, not left to tribal knowledge.
Attribute Definitions
// =================================================================
// Ops.Cost.Lib -- Cost DSL Attributes
// =================================================================
/// Payment option for reserved capacity.
public enum PaymentOption
{
AllUpfront,
PartialUpfront,
NoUpfront
}
/// Reserved capacity term length.
public enum ReservationTerm
{
OneYear,
ThreeYear
}
/// Declares a monthly budget for a service or resource.
[AttributeUsage(AttributeTargets.Class, AllowMultiple = true)]
public sealed class ResourceBudgetAttribute : Attribute
{
public string Service { get; }
public decimal MonthlyBudget { get; }
public string Currency { get; }
public int AlertAtPercent { get; }
public string[] NotifyChannels { get; }
public ResourceBudgetAttribute(
string service,
double monthlyBudget,
string currency,
int alertAtPercent,
params string[] notifyChannels)
{
Service = service;
MonthlyBudget = (decimal)monthlyBudget;
Currency = currency;
AlertAtPercent = alertAtPercent;
NotifyChannels = notifyChannels;
}
/// <summary>
/// Forecast alert: warn when projected spend exceeds budget.
/// </summary>
public bool ForecastAlert { get; init; } = true;
/// <summary>
/// Action when budget is exceeded: Notify, Throttle, or Shutdown.
/// </summary>
public string OnExceeded { get; init; } = "Notify";
/// <summary>Monthly budget breakdown by resource type.</summary>
public string? ComputeBudget { get; init; }
public string? StorageBudget { get; init; }
public string? NetworkBudget { get; init; }
}
/// Declares right-sizing review schedule and targets.
[AttributeUsage(AttributeTargets.Class)]
public sealed class RightSizingRuleAttribute : Attribute
{
public string Target { get; }
public int CpuUtilizationTarget { get; }
public int MemoryUtilizationTarget { get; }
public string ReviewSchedule { get; }
public RightSizingRuleAttribute(
string target,
int cpuUtilizationTarget,
int memoryUtilizationTarget,
string reviewSchedule)
{
Target = target;
CpuUtilizationTarget = cpuUtilizationTarget;
MemoryUtilizationTarget = memoryUtilizationTarget;
ReviewSchedule = reviewSchedule;
}
/// <summary>
/// Minimum observation window before recommending a change.
/// </summary>
public string ObservationWindow { get; init; } = "14d";
/// <summary>
/// Automatically apply right-sizing recommendations.
/// </summary>
public bool AutoApply { get; init; } = false;
}
/// Declares spot instance policy for a workload.
[AttributeUsage(AttributeTargets.Class)]
public sealed class SpotPolicyAttribute : Attribute
{
public string Target { get; }
public bool AllowSpotInstances { get; }
public int MaxSpotPercentage { get; }
public bool FallbackToOnDemand { get; }
public SpotPolicyAttribute(
string target,
bool allowSpotInstances,
int maxSpotPercentage,
bool fallbackToOnDemand)
{
Target = target;
AllowSpotInstances = allowSpotInstances;
MaxSpotPercentage = maxSpotPercentage;
FallbackToOnDemand = fallbackToOnDemand;
}
/// <summary>Maximum price as percentage of on-demand price.</summary>
public int MaxPricePercent { get; init; } = 100;
/// <summary>
/// Diversify across instance types for availability.
/// </summary>
public bool DiversifyInstanceTypes { get; init; } = true;
/// <summary>Interruption behavior: Terminate, Stop, or Hibernate.</summary>
public string InterruptionBehavior { get; init; } = "Terminate";
}
/// Declares reserved capacity commitment.
[AttributeUsage(AttributeTargets.Class, AllowMultiple = true)]
public sealed class ReservedCapacityAttribute : Attribute
{
public string Target { get; }
public string InstanceType { get; }
public ReservationTerm Term { get; }
public PaymentOption PaymentOption { get; }
public ReservedCapacityAttribute(
string target,
string instanceType,
ReservationTerm term,
PaymentOption paymentOption)
{
Target = target;
InstanceType = instanceType;
Term = term;
PaymentOption = paymentOption;
}
/// <summary>Number of reserved instances.</summary>
public int Count { get; init; } = 1;
/// <summary>Expiry notification lead time.</summary>
public string NotifyBeforeExpiry { get; init; } = "90d";
}
/// Declares a cost allocation tag for a resource.
[AttributeUsage(AttributeTargets.Class, AllowMultiple = true)]
public sealed class CostTagAttribute : Attribute
{
public string Key { get; }
public string Value { get; }
public CostTagAttribute(string key, string value)
{
Key = key;
Value = value;
}
}// =================================================================
// Ops.Cost.Lib -- Cost DSL Attributes
// =================================================================
/// Payment option for reserved capacity.
public enum PaymentOption
{
AllUpfront,
PartialUpfront,
NoUpfront
}
/// Reserved capacity term length.
public enum ReservationTerm
{
OneYear,
ThreeYear
}
/// Declares a monthly budget for a service or resource.
[AttributeUsage(AttributeTargets.Class, AllowMultiple = true)]
public sealed class ResourceBudgetAttribute : Attribute
{
public string Service { get; }
public decimal MonthlyBudget { get; }
public string Currency { get; }
public int AlertAtPercent { get; }
public string[] NotifyChannels { get; }
public ResourceBudgetAttribute(
string service,
double monthlyBudget,
string currency,
int alertAtPercent,
params string[] notifyChannels)
{
Service = service;
MonthlyBudget = (decimal)monthlyBudget;
Currency = currency;
AlertAtPercent = alertAtPercent;
NotifyChannels = notifyChannels;
}
/// <summary>
/// Forecast alert: warn when projected spend exceeds budget.
/// </summary>
public bool ForecastAlert { get; init; } = true;
/// <summary>
/// Action when budget is exceeded: Notify, Throttle, or Shutdown.
/// </summary>
public string OnExceeded { get; init; } = "Notify";
/// <summary>Monthly budget breakdown by resource type.</summary>
public string? ComputeBudget { get; init; }
public string? StorageBudget { get; init; }
public string? NetworkBudget { get; init; }
}
/// Declares right-sizing review schedule and targets.
[AttributeUsage(AttributeTargets.Class)]
public sealed class RightSizingRuleAttribute : Attribute
{
public string Target { get; }
public int CpuUtilizationTarget { get; }
public int MemoryUtilizationTarget { get; }
public string ReviewSchedule { get; }
public RightSizingRuleAttribute(
string target,
int cpuUtilizationTarget,
int memoryUtilizationTarget,
string reviewSchedule)
{
Target = target;
CpuUtilizationTarget = cpuUtilizationTarget;
MemoryUtilizationTarget = memoryUtilizationTarget;
ReviewSchedule = reviewSchedule;
}
/// <summary>
/// Minimum observation window before recommending a change.
/// </summary>
public string ObservationWindow { get; init; } = "14d";
/// <summary>
/// Automatically apply right-sizing recommendations.
/// </summary>
public bool AutoApply { get; init; } = false;
}
/// Declares spot instance policy for a workload.
[AttributeUsage(AttributeTargets.Class)]
public sealed class SpotPolicyAttribute : Attribute
{
public string Target { get; }
public bool AllowSpotInstances { get; }
public int MaxSpotPercentage { get; }
public bool FallbackToOnDemand { get; }
public SpotPolicyAttribute(
string target,
bool allowSpotInstances,
int maxSpotPercentage,
bool fallbackToOnDemand)
{
Target = target;
AllowSpotInstances = allowSpotInstances;
MaxSpotPercentage = maxSpotPercentage;
FallbackToOnDemand = fallbackToOnDemand;
}
/// <summary>Maximum price as percentage of on-demand price.</summary>
public int MaxPricePercent { get; init; } = 100;
/// <summary>
/// Diversify across instance types for availability.
/// </summary>
public bool DiversifyInstanceTypes { get; init; } = true;
/// <summary>Interruption behavior: Terminate, Stop, or Hibernate.</summary>
public string InterruptionBehavior { get; init; } = "Terminate";
}
/// Declares reserved capacity commitment.
[AttributeUsage(AttributeTargets.Class, AllowMultiple = true)]
public sealed class ReservedCapacityAttribute : Attribute
{
public string Target { get; }
public string InstanceType { get; }
public ReservationTerm Term { get; }
public PaymentOption PaymentOption { get; }
public ReservedCapacityAttribute(
string target,
string instanceType,
ReservationTerm term,
PaymentOption paymentOption)
{
Target = target;
InstanceType = instanceType;
Term = term;
PaymentOption = paymentOption;
}
/// <summary>Number of reserved instances.</summary>
public int Count { get; init; } = 1;
/// <summary>Expiry notification lead time.</summary>
public string NotifyBeforeExpiry { get; init; } = "90d";
}
/// Declares a cost allocation tag for a resource.
[AttributeUsage(AttributeTargets.Class, AllowMultiple = true)]
public sealed class CostTagAttribute : Attribute
{
public string Key { get; }
public string Value { get; }
public CostTagAttribute(string key, string value)
{
Key = key;
Value = value;
}
}Usage
[DeploymentApp("order-service")]
// Budget: $500/month, alert at 80%, notify Slack and email
[ResourceBudget(
"order-service", 500.0, "USD", 80,
"#finops-alerts", "platform-team@acme.com",
ForecastAlert = true,
OnExceeded = "Notify",
ComputeBudget = "350",
StorageBudget = "100",
NetworkBudget = "50")]
// Right-sizing: target 60% CPU, 70% memory, review quarterly
[RightSizingRule(
"order-service",
cpuUtilizationTarget: 60,
memoryUtilizationTarget: 70,
reviewSchedule: "quarterly",
ObservationWindow = "14d",
AutoApply = false)]
// Spot: 70% spot with on-demand fallback
[SpotPolicy(
"order-service",
allowSpotInstances: true,
maxSpotPercentage: 70,
fallbackToOnDemand: true,
MaxPricePercent = 80,
DiversifyInstanceTypes = true,
InterruptionBehavior = "Terminate")]
// Reserved capacity for the database (always-on, predictable)
[ReservedCapacity(
"orders-db",
instanceType: "db.r6g.large",
ReservationTerm.ThreeYear,
PaymentOption.PartialUpfront,
Count = 2,
NotifyBeforeExpiry = "90d")]
// Cost allocation tags
[CostTag("team", "order-platform")]
[CostTag("product", "commerce")]
[CostTag("environment", "production")]
[CostTag("cost-center", "CC-4200")]
public partial class OrderServiceCost { }[DeploymentApp("order-service")]
// Budget: $500/month, alert at 80%, notify Slack and email
[ResourceBudget(
"order-service", 500.0, "USD", 80,
"#finops-alerts", "platform-team@acme.com",
ForecastAlert = true,
OnExceeded = "Notify",
ComputeBudget = "350",
StorageBudget = "100",
NetworkBudget = "50")]
// Right-sizing: target 60% CPU, 70% memory, review quarterly
[RightSizingRule(
"order-service",
cpuUtilizationTarget: 60,
memoryUtilizationTarget: 70,
reviewSchedule: "quarterly",
ObservationWindow = "14d",
AutoApply = false)]
// Spot: 70% spot with on-demand fallback
[SpotPolicy(
"order-service",
allowSpotInstances: true,
maxSpotPercentage: 70,
fallbackToOnDemand: true,
MaxPricePercent = 80,
DiversifyInstanceTypes = true,
InterruptionBehavior = "Terminate")]
// Reserved capacity for the database (always-on, predictable)
[ReservedCapacity(
"orders-db",
instanceType: "db.r6g.large",
ReservationTerm.ThreeYear,
PaymentOption.PartialUpfront,
Count = 2,
NotifyBeforeExpiry = "90d")]
// Cost allocation tags
[CostTag("team", "order-platform")]
[CostTag("product", "commerce")]
[CostTag("environment", "production")]
[CostTag("cost-center", "CC-4200")]
public partial class OrderServiceCost { }Every cost decision is now a typed declaration. The $47,000 surprise cannot happen because the $500 budget has an 80% alert. The right-sizing CSV is replaced by a quarterly review schedule with utilization targets. Spot instances have an explicit fallback policy. Cost allocation tags exist on every resource because the generator puts them there.
budget-alerts.json (AWS Budgets Format)
{
"budgets": [
{
"budgetName": "order-service-monthly",
"budgetType": "COST",
"budgetLimit": {
"amount": "500",
"unit": "USD"
},
"timePeriod": {
"start": "2026-04-01T00:00:00Z"
},
"timeUnit": "MONTHLY",
"costFilters": {
"TagKeyValue": [
"user:team$order-platform",
"user:cost-center$CC-4200"
]
},
"notifications": [
{
"notificationType": "ACTUAL",
"comparisonOperator": "GREATER_THAN",
"threshold": 80,
"thresholdType": "PERCENTAGE",
"subscribers": [
{
"subscriptionType": "SNS",
"address": "arn:aws:sns:eu-west-1:123456789:finops-alerts"
},
{
"subscriptionType": "EMAIL",
"address": "platform-team@acme.com"
}
]
},
{
"notificationType": "FORECASTED",
"comparisonOperator": "GREATER_THAN",
"threshold": 100,
"thresholdType": "PERCENTAGE",
"subscribers": [
{
"subscriptionType": "SNS",
"address": "arn:aws:sns:eu-west-1:123456789:finops-alerts"
}
]
}
]
}
]
}{
"budgets": [
{
"budgetName": "order-service-monthly",
"budgetType": "COST",
"budgetLimit": {
"amount": "500",
"unit": "USD"
},
"timePeriod": {
"start": "2026-04-01T00:00:00Z"
},
"timeUnit": "MONTHLY",
"costFilters": {
"TagKeyValue": [
"user:team$order-platform",
"user:cost-center$CC-4200"
]
},
"notifications": [
{
"notificationType": "ACTUAL",
"comparisonOperator": "GREATER_THAN",
"threshold": 80,
"thresholdType": "PERCENTAGE",
"subscribers": [
{
"subscriptionType": "SNS",
"address": "arn:aws:sns:eu-west-1:123456789:finops-alerts"
},
{
"subscriptionType": "EMAIL",
"address": "platform-team@acme.com"
}
]
},
{
"notificationType": "FORECASTED",
"comparisonOperator": "GREATER_THAN",
"threshold": 100,
"thresholdType": "PERCENTAGE",
"subscribers": [
{
"subscriptionType": "SNS",
"address": "arn:aws:sns:eu-west-1:123456789:finops-alerts"
}
]
}
]
}
]
}cost-tags.g.cs
// <auto-generated by Ops.Cost.Generator />
namespace OrderService.Generated;
/// <summary>
/// Registers cost allocation tags as resource metadata.
/// Used by infrastructure-as-code generators and cloud resource tagging.
/// </summary>
public static class CostTags
{
public static readonly IReadOnlyDictionary<string, string> Tags =
new Dictionary<string, string>
{
["team"] = "order-platform",
["product"] = "commerce",
["environment"] = "production",
["cost-center"] = "CC-4200",
// Auto-added by generator:
["service"] = "order-service",
["managed-by"] = "ops-cost-dsl",
};
/// <summary>
/// Applies cost tags to all outgoing cloud SDK requests.
/// Register in DI: services.AddCostTagging();
/// </summary>
public static IServiceCollection AddCostTagging(
this IServiceCollection services)
{
// AWS: register TagResourceMiddleware
// Azure: register TaggingDelegatingHandler
// The generator picks the right provider based on
// [CloudProvider] from the Infrastructure DSL.
services.AddSingleton<ICostTagProvider>(
new StaticCostTagProvider(Tags));
return services;
}
}
public interface ICostTagProvider
{
IReadOnlyDictionary<string, string> GetTags();
}
public sealed class StaticCostTagProvider : ICostTagProvider
{
private readonly IReadOnlyDictionary<string, string> _tags;
public StaticCostTagProvider(
IReadOnlyDictionary<string, string> tags) => _tags = tags;
public IReadOnlyDictionary<string, string> GetTags() => _tags;
}// <auto-generated by Ops.Cost.Generator />
namespace OrderService.Generated;
/// <summary>
/// Registers cost allocation tags as resource metadata.
/// Used by infrastructure-as-code generators and cloud resource tagging.
/// </summary>
public static class CostTags
{
public static readonly IReadOnlyDictionary<string, string> Tags =
new Dictionary<string, string>
{
["team"] = "order-platform",
["product"] = "commerce",
["environment"] = "production",
["cost-center"] = "CC-4200",
// Auto-added by generator:
["service"] = "order-service",
["managed-by"] = "ops-cost-dsl",
};
/// <summary>
/// Applies cost tags to all outgoing cloud SDK requests.
/// Register in DI: services.AddCostTagging();
/// </summary>
public static IServiceCollection AddCostTagging(
this IServiceCollection services)
{
// AWS: register TagResourceMiddleware
// Azure: register TaggingDelegatingHandler
// The generator picks the right provider based on
// [CloudProvider] from the Infrastructure DSL.
services.AddSingleton<ICostTagProvider>(
new StaticCostTagProvider(Tags));
return services;
}
}
public interface ICostTagProvider
{
IReadOnlyDictionary<string, string> GetTags();
}
public sealed class StaticCostTagProvider : ICostTagProvider
{
private readonly IReadOnlyDictionary<string, string> _tags;
public StaticCostTagProvider(
IReadOnlyDictionary<string, string> tags) => _tags = tags;
public IReadOnlyDictionary<string, string> GetTags() => _tags;
}CostReport.g.md (Monthly Review Template)
# Cost Review — order-service
Period: 2026-04-01 to 2026-04-30
Generated: 2026-04-06T10:00:00Z
## Budget Status
| Category | Budget | Actual (MTD) | Projected | Status |
|----------|--------|-------------|-----------|--------|
| Compute | $350 | $-- | $-- | -- |
| Storage | $100 | $-- | $-- | -- |
| Network | $50 | $-- | $-- | -- |
| **Total**| **$500** | **$--** | **$--** | -- |
> Fill in actuals from cloud billing dashboard.
## Right-Sizing Review (Quarterly)
| Resource | Current Type | CPU Avg | Mem Avg | Target CPU | Target Mem | Recommendation |
|-----------------|-------------|---------|---------|------------|------------|----------------|
| order-service | -- | -- | -- | 60% | 70% | -- |
> Observation window: 14 days. AutoApply: disabled.
## Spot Instance Summary
| Workload | Spot % | On-Demand Fallback | Interruptions (30d) | Savings |
|---------------|--------|--------------------|---------------------|---------|
| order-service | 70% | Yes | -- | -- |
## Reserved Capacity
| Resource | Instance Type | Term | Payment | Count | Expiry | Action Needed |
|-----------|--------------|---------|-----------------|-------|---------|---------------|
| orders-db | db.r6g.large | 3-Year | Partial Upfront | 2 | -- | Renew 90d before |
## Cost Tags Applied
| Key | Value |
|--------------|----------------|
| team | order-platform |
| product | commerce |
| environment | production |
| cost-center | CC-4200 |
| service | order-service |
| managed-by | ops-cost-dsl |# Cost Review — order-service
Period: 2026-04-01 to 2026-04-30
Generated: 2026-04-06T10:00:00Z
## Budget Status
| Category | Budget | Actual (MTD) | Projected | Status |
|----------|--------|-------------|-----------|--------|
| Compute | $350 | $-- | $-- | -- |
| Storage | $100 | $-- | $-- | -- |
| Network | $50 | $-- | $-- | -- |
| **Total**| **$500** | **$--** | **$--** | -- |
> Fill in actuals from cloud billing dashboard.
## Right-Sizing Review (Quarterly)
| Resource | Current Type | CPU Avg | Mem Avg | Target CPU | Target Mem | Recommendation |
|-----------------|-------------|---------|---------|------------|------------|----------------|
| order-service | -- | -- | -- | 60% | 70% | -- |
> Observation window: 14 days. AutoApply: disabled.
## Spot Instance Summary
| Workload | Spot % | On-Demand Fallback | Interruptions (30d) | Savings |
|---------------|--------|--------------------|---------------------|---------|
| order-service | 70% | Yes | -- | -- |
## Reserved Capacity
| Resource | Instance Type | Term | Payment | Count | Expiry | Action Needed |
|-----------|--------------|---------|-----------------|-------|---------|---------------|
| orders-db | db.r6g.large | 3-Year | Partial Upfront | 2 | -- | Renew 90d before |
## Cost Tags Applied
| Key | Value |
|--------------|----------------|
| team | order-platform |
| product | commerce |
| environment | production |
| cost-center | CC-4200 |
| service | order-service |
| managed-by | ops-cost-dsl |The template is regenerated each build. The -- placeholders are filled by a cost reporting script that queries the cloud provider API. The structure is always correct because it comes from the attributes.
Analyzers
| ID | Severity | Rule |
|---|---|---|
| CST001 | Warning | [ContainerSpec] without corresponding [ResourceBudget] |
| CST002 | Warning | [ResourceBudget] without alert threshold |
| CST003 | Error | [SpotPolicy] on stateful workload without fallback |
| CST004 | Warning | Reserved capacity expiring within NotifyBeforeExpiry |
CST001 -- Container Without Budget
warning CST001: Service 'analytics-service' has [ContainerSpec] but no
[ResourceBudget]. Every deployed service should have a cost budget.
Add [ResourceBudget("analytics-service", ...)] to your cost class.warning CST001: Service 'analytics-service' has [ContainerSpec] but no
[ResourceBudget]. Every deployed service should have a cost budget.
Add [ResourceBudget("analytics-service", ...)] to your cost class.CST003 -- Spot Without Fallback
error CST003: Service 'payment-service' has [SpotPolicy] with
AllowSpotInstances=true but FallbackToOnDemand=false. Stateful or
critical workloads using spot instances must have on-demand fallback
enabled. Set FallbackToOnDemand=true or remove the spot policy.error CST003: Service 'payment-service' has [SpotPolicy] with
AllowSpotInstances=true but FallbackToOnDemand=false. Stateful or
critical workloads using spot instances must have on-demand fallback
enabled. Set FallbackToOnDemand=true or remove the spot policy.Cost --> Infrastructure
Every [ContainerSpec] from the Infrastructure DSL should have a corresponding [ResourceBudget]. The cross-DSL analyzer enforces this. When the Infrastructure DSL declares CPU and memory limits, the Cost DSL uses those limits to validate that the budget is realistic:
warning CST-INF001: Service 'order-service' requests 2 vCPU and 4Gi
memory via [ContainerSpec]. At current on-demand pricing, this costs
approximately $145/month per replica. With MaxReplicas=10 from
[AutoscaleRule], peak cost is $1,450/month. Budget is $500/month.
Consider adjusting the budget or the resource limits.warning CST-INF001: Service 'order-service' requests 2 vCPU and 4Gi
memory via [ContainerSpec]. At current on-demand pricing, this costs
approximately $145/month per replica. With MaxReplicas=10 from
[AutoscaleRule], peak cost is $1,450/month. Budget is $500/month.
Consider adjusting the budget or the resource limits.This is the warning that would have caught the $47,000 surprise.
Cost --> Capacity
The Capacity DSL declares [AutoscaleRule] with MaxReplicas. The Cost DSL multiplies MaxReplicas by the per-replica cost to compute peak spend. If peak spend exceeds the budget, the analyzer warns. This creates a natural tension: the capacity team wants high max replicas for availability, the finops team wants low max replicas for cost. The DSL makes the tension explicit and quantifiable.
Cost --> Deployment
The Deployment DSL declares rolling update strategies. During a blue-green deployment, both old and new versions run simultaneously, doubling compute cost for the duration. The Cost DSL models this:
info CST-DEP001: Service 'order-service' uses BlueGreen deployment
strategy. During deployment, cost doubles temporarily. Monthly budget
of $500 includes $35 headroom for deployment overlap (estimated 2
deployments/month, 30 minutes each).info CST-DEP001: Service 'order-service' uses BlueGreen deployment
strategy. During deployment, cost doubles temporarily. Monthly budget
of $500 includes $35 headroom for deployment overlap (estimated 2
deployments/month, 30 minutes each).The budget is not just a number. It is a typed value connected to every other DSL that affects cost.