Skip to content

feat(azure): wire payment_option to reservation billingPlanType (Azure RIs always bill upfront) #1502

Description

@cristim

Gap

Azure Reserved Instance purchases always bill upfront regardless of the requested payment_option. The purchase body builder (providers/azure/services/compute/client.go, buildReservationBody) is called with opts.Source and opts.IdempotencyToken but never receives opts.PaymentOption, so Azure's reservation API sends no billingPlanType and defaults to upfront.

Impact

  • A caller requesting no-upfront or partial-upfront for an Azure RI would silently get an upfront commitment (different cash-flow schedule than requested).
  • Currently guarded, not honored: the CUDly MCP server (PR feat(mcp): CUDly MCP server for RI/SP/CUD purchases across AWS, Azure, GCP #1495) fails loud and rejects non-all-upfront Azure RI real purchases rather than silently mis-billing. So there is no active money-safety hole; this issue is to actually support the other billing plans.

Fix

  • Thread opts.PaymentOption into buildReservationBody and map it to Azure's billingPlanType (Upfront vs Monthly) on the reservation purchase request. Azure reservations support Upfront and Monthly billing plans; map all-upfront -> Upfront, no-upfront/partial-upfront -> the closest supported plan (Monthly), or reject combinations Azure genuinely cannot express (fail loud, no silent default).
  • Use the SDK's typed billing-plan enum, not a raw string literal (project convention).
  • Once wired, remove the MCP tool's real-purchase rejection of non-all-upfront in mcp/tools/azure_compute_ri.go and let the value flow through.

Scope note

This is a provider-layer change that also benefits the CLI and web (internal/api) purchase paths, not just MCP. Verify against Azure's reservation billing-plan API surface before wiring; do not assume the mapping.

Related

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions