{
  "nbformat": 4,
  "nbformat_minor": 5,
  "metadata": {
    "kernelspec": {
      "display_name": "Python 3",
      "language": "python",
      "name": "python3"
    },
    "language_info": {
      "name": "python",
      "version": "3.13.0"
    },
    "blog_metadata": {
      "topic": "Azure Resource Manager MCP Server: Why Cost Management and Pricing Toolsets Matter for FinOps",
      "slug": "azure-resource-manager-mcp-server-why-cost-management-and-pr",
      "generated_by": "LinkedIn Post Generator + Azure OpenAI",
      "generated_at": "2026-07-30T18:35:02.481Z"
    }
  },
  "cells": [
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "# Azure Resource Manager MCP Server: Why Cost Management and Pricing Toolsets Matter for FinOps\n",
        "\n",
        "This notebook turns the blog post into a hands-on validation flow for FinOps-oriented pre-deployment controls. The focus is not autonomous optimization, but governed decision support: bringing pricing context, metadata validation, approval evidence, and auditability into the same workflow that could create spend."
      ]
    },
    {
      "cell_type": "code",
      "metadata": {},
      "source": [
        "%pip install pandas"
      ],
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {},
      "source": [
        "from datetime import datetime, timezone\n",
        "import json\n",
        "import pandas as pd"
      ],
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "## Read-only pre-deployment cost review\n",
        "\n",
        "This example models the first control the post recommends: retrieve pricing context before any deployment path. The outcome is a governed decision state such as `WithinBudget` or `NeedsApproval`, rather than directly creating Azure resources."
      ]
    },
    {
      "cell_type": "code",
      "metadata": {},
      "source": [
        "# Python: read-only pre-deployment cost review using an approved pricing tool\n",
        "from datetime import datetime\n",
        "\n",
        "proposal = {\n",
        "    \"subscription\": \"sub-prod-001\",\n",
        "    \"resourceGroup\": \"rg-app-prod\",\n",
        "    \"sku\": \"Standard_D4s_v5\",\n",
        "    \"hoursPerMonth\": 730,\n",
        "    \"region\": \"eastus\"\n",
        "}\n",
        "\n",
        "def approved_pricing_tool(payload):\n",
        "    return {\"monthlyEstimate\": 412.75, \"currency\": \"USD\", \"source\": \"ApprovedPricingAPI\"}\n",
        "\n",
        "pricing = approved_pricing_tool(proposal)\n",
        "budget_limit = 400.00\n",
        "status = \"NeedsApproval\" if pricing[\"monthlyEstimate\"] > budget_limit else \"WithinBudget\"\n",
        "\n",
        "print(\"Proposal:\")\n",
        "print(json.dumps(proposal, indent=2))\n",
        "print(\"\\nPricing Context:\")\n",
        "print(json.dumps(pricing, indent=2))\n",
        "print(f\"\\nBudget Limit: {budget_limit:.2f} {pricing['currency']}\")\n",
        "print(f\"Decision Status: {status}\")"
      ],
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "## Emit a review record without deploying\n",
        "\n",
        "This example captures the evidence needed for auditability. It records the proposal, pricing context, budget threshold, decision, and next action while remaining strictly read-only."
      ]
    },
    {
      "cell_type": "code",
      "metadata": {},
      "source": [
        "# Python: emit a review record without creating any Azure resources\n",
        "from datetime import datetime\n",
        "\n",
        "proposal = {\n",
        "    \"subscription\": \"sub-prod-001\",\n",
        "    \"resourceGroup\": \"rg-app-prod\",\n",
        "    \"sku\": \"Standard_D4s_v5\",\n",
        "    \"hoursPerMonth\": 730,\n",
        "    \"region\": \"eastus\"\n",
        "}\n",
        "\n",
        "def approved_pricing_tool(payload):\n",
        "    return {\"monthlyEstimate\": 412.75, \"currency\": \"USD\", \"source\": \"ApprovedPricingAPI\"}\n",
        "\n",
        "pricing = approved_pricing_tool(proposal)\n",
        "budget_limit = 400.00\n",
        "status = \"NeedsApproval\" if pricing[\"monthlyEstimate\"] > budget_limit else \"WithinBudget\"\n",
        "\n",
        "review_record = {\n",
        "    \"timestamp\": datetime.utcnow().isoformat() + \"Z\",\n",
        "    \"mode\": \"ReadOnlyReview\",\n",
        "    \"proposal\": proposal,\n",
        "    \"pricingContext\": pricing,\n",
        "    \"budgetLimit\": budget_limit,\n",
        "    \"decision\": status,\n",
        "    \"nextAction\": \"DoNotDeploy\" if status == \"NeedsApproval\" else \"ReadyForChangeReview\"\n",
        "}\n",
        "\n",
        "print(json.dumps(review_record, indent=2))\n",
        "\n",
        "review_df = pd.json_normalize(review_record)\n",
        "review_df"
      ],
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "## Validate ownership and allocation metadata\n",
        "\n",
        "The blog emphasizes required ownership and allocation metadata as a leadership guardrail. This Python version mirrors the PowerShell logic by blocking progression when required tags are missing or blank."
      ]
    },
    {
      "cell_type": "code",
      "metadata": {},
      "source": [
        "# Python equivalent: validate ownership/allocation metadata before any deployment\n",
        "\n",
        "tags = {\n",
        "    \"Owner\": \"team-payments\",\n",
        "    \"CostCenter\": \"CC-1042\",\n",
        "    \"Environment\": \"Prod\"\n",
        "}\n",
        "\n",
        "required = [\"Owner\", \"CostCenter\", \"Environment\"]\n",
        "missing = [key for key in required if key not in tags or str(tags[key]).strip() == \"\"]\n",
        "\n",
        "if missing:\n",
        "    raise ValueError(f\"Deployment blocked. Missing required metadata: {', '.join(missing)}\")\n",
        "\n",
        "print(\"Metadata validation passed.\")\n",
        "print(json.dumps(tags, indent=2))"
      ],
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "## Capture approval evidence and gate deployment intent\n",
        "\n",
        "The original post argues for separation between read-only pricing tools and write-capable actions, with human approval for spend-impacting changes. This Python example validates approval evidence and produces a deployment gate decision without invoking Azure."
      ]
    },
    {
      "cell_type": "code",
      "metadata": {},
      "source": [
        "# Python equivalent: capture approval evidence and gate the ARM/Bicep deployment intent\n",
        "\n",
        "approval = {\n",
        "    \"ApprovedBy\": \"finops.lead@contoso.com\",\n",
        "    \"TicketId\": \"CHG-48291\",\n",
        "    \"ApprovedAt\": datetime.now(timezone.utc).strftime(\"%Y-%m-%dT%H:%M:%SZ\")\n",
        "}\n",
        "\n",
        "tags = {\n",
        "    \"Owner\": \"team-payments\",\n",
        "    \"CostCenter\": \"CC-1042\",\n",
        "    \"Environment\": \"Prod\"\n",
        "}\n",
        "\n",
        "required_tag_keys = [\"Owner\", \"CostCenter\", \"Environment\"]\n",
        "missing_tags = [key for key in required_tag_keys if key not in tags or str(tags[key]).strip() == \"\"]\n",
        "\n",
        "if missing_tags:\n",
        "    raise ValueError(f\"Deployment blocked. Missing required metadata: {', '.join(missing_tags)}\")\n",
        "\n",
        "if not approval.get(\"ApprovedBy\") or not approval.get(\"TicketId\"):\n",
        "    raise ValueError(\"Deployment blocked. Approval evidence is incomplete.\")\n",
        "\n",
        "deployment_request = {\n",
        "    \"resourceGroupName\": \"rg-app-prod\",\n",
        "    \"templateFile\": \"./main.bicep\",\n",
        "    \"templateParameters\": {\n",
        "        \"tags\": tags,\n",
        "        \"approval\": approval\n",
        "    },\n",
        "    \"gateDecision\": \"ReadyForDeployment\"\n",
        "}\n",
        "\n",
        "print(\"Approval evidence validated.\")\n",
        "print(json.dumps(deployment_request, indent=2))"
      ],
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "## End-to-end FinOps control flow\n",
        "\n",
        "This cell translates the blog's workflow into executable Python. It simulates proposal intake, pricing lookup, budget evaluation, metadata validation, approval checks, and a final deployment gate outcome with a full audit trail."
      ]
    },
    {
      "cell_type": "code",
      "metadata": {},
      "source": [
        "def approved_pricing_tool(payload):\n",
        "    price_book = {\n",
        "        (\"Standard_D4s_v5\", \"eastus\"): 412.75,\n",
        "        (\"Standard_D2s_v5\", \"eastus\"): 205.10,\n",
        "        (\"Standard_D4s_v5\", \"westus2\"): 425.40\n",
        "    }\n",
        "    estimate = price_book.get((payload[\"sku\"], payload[\"region\"]), 500.00)\n",
        "    return {\n",
        "        \"monthlyEstimate\": estimate,\n",
        "        \"currency\": \"USD\",\n",
        "        \"source\": \"ApprovedPricingAPI\"\n",
        "    }\n",
        "\n",
        "\n",
        "def validate_tags(tags, required=(\"Owner\", \"CostCenter\", \"Environment\")):\n",
        "    missing = [k for k in required if k not in tags or str(tags[k]).strip() == \"\"]\n",
        "    return missing\n",
        "\n",
        "\n",
        "def validate_approval(approval):\n",
        "    return bool(approval.get(\"ApprovedBy\")) and bool(approval.get(\"TicketId\"))\n",
        "\n",
        "\n",
        "proposal = {\n",
        "    \"subscription\": \"sub-prod-001\",\n",
        "    \"resourceGroup\": \"rg-app-prod\",\n",
        "    \"sku\": \"Standard_D4s_v5\",\n",
        "    \"hoursPerMonth\": 730,\n",
        "    \"region\": \"eastus\"\n",
        "}\n",
        "\n",
        "tags = {\n",
        "    \"Owner\": \"team-payments\",\n",
        "    \"CostCenter\": \"CC-1042\",\n",
        "    \"Environment\": \"Prod\"\n",
        "}\n",
        "\n",
        "approval = {\n",
        "    \"ApprovedBy\": \"finops.lead@contoso.com\",\n",
        "    \"TicketId\": \"CHG-48291\",\n",
        "    \"ApprovedAt\": datetime.now(timezone.utc).strftime(\"%Y-%m-%dT%H:%M:%SZ\")\n",
        "}\n",
        "\n",
        "budget_limit = 400.00\n",
        "pricing = approved_pricing_tool(proposal)\n",
        "status = \"NeedsApproval\" if pricing[\"monthlyEstimate\"] > budget_limit else \"WithinBudget\"\n",
        "missing_tags = validate_tags(tags)\n",
        "approval_ok = validate_approval(approval)\n",
        "\n",
        "if status == \"NeedsApproval\" and approval_ok and not missing_tags:\n",
        "    final_decision = \"ReadyForDeployment\"\n",
        "elif status == \"WithinBudget\" and not missing_tags:\n",
        "    final_decision = \"ReadyForChangeReview\"\n",
        "elif missing_tags:\n",
        "    final_decision = \"BlockedMissingMetadata\"\n",
        "else:\n",
        "    final_decision = \"BlockedPendingApproval\"\n",
        "\n",
        "audit_record = {\n",
        "    \"timestamp\": datetime.now(timezone.utc).strftime(\"%Y-%m-%dT%H:%M:%SZ\"),\n",
        "    \"proposal\": proposal,\n",
        "    \"pricingContext\": pricing,\n",
        "    \"budgetLimit\": budget_limit,\n",
        "    \"budgetDecision\": status,\n",
        "    \"tags\": tags,\n",
        "    \"missingTags\": missing_tags,\n",
        "    \"approval\": approval,\n",
        "    \"approvalValid\": approval_ok,\n",
        "    \"finalDecision\": final_decision\n",
        "}\n",
        "\n",
        "print(json.dumps(audit_record, indent=2))\n",
        "\n",
        "pd.json_normalize(audit_record)"
      ],
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "## Scenario testing\n",
        "\n",
        "To validate where this model breaks first in your environment, test multiple scenarios. This table compares outcomes for pricing, metadata, and approval conditions across several proposals."
      ]
    },
    {
      "cell_type": "code",
      "metadata": {},
      "source": [
        "def approved_pricing_tool(payload):\n",
        "    price_book = {\n",
        "        (\"Standard_D4s_v5\", \"eastus\"): 412.75,\n",
        "        (\"Standard_D2s_v5\", \"eastus\"): 205.10,\n",
        "        (\"Premium_LRS_Storage\", \"eastus\"): 89.99,\n",
        "        (\"AKS_Standard\", \"eastus\"): 620.00\n",
        "    }\n",
        "    estimate = price_book.get((payload[\"sku\"], payload[\"region\"]), 500.00)\n",
        "    return {\"monthlyEstimate\": estimate, \"currency\": \"USD\", \"source\": \"ApprovedPricingAPI\"}\n",
        "\n",
        "\n",
        "def evaluate_request(proposal, tags, approval, budget_limit=400.0):\n",
        "    pricing = approved_pricing_tool(proposal)\n",
        "    status = \"NeedsApproval\" if pricing[\"monthlyEstimate\"] > budget_limit else \"WithinBudget\"\n",
        "    missing_tags = [k for k in [\"Owner\", \"CostCenter\", \"Environment\"] if k not in tags or str(tags[k]).strip() == \"\"]\n",
        "    approval_ok = bool(approval.get(\"ApprovedBy\")) and bool(approval.get(\"TicketId\"))\n",
        "\n",
        "    if missing_tags:\n",
        "        final = \"BlockedMissingMetadata\"\n",
        "    elif status == \"NeedsApproval\" and not approval_ok:\n",
        "        final = \"BlockedPendingApproval\"\n",
        "    elif status == \"NeedsApproval\" and approval_ok:\n",
        "        final = \"ReadyForDeployment\"\n",
        "    else:\n",
        "        final = \"ReadyForChangeReview\"\n",
        "\n",
        "    return {\n",
        "        \"sku\": proposal[\"sku\"],\n",
        "        \"region\": proposal[\"region\"],\n",
        "        \"monthlyEstimate\": pricing[\"monthlyEstimate\"],\n",
        "        \"budgetLimit\": budget_limit,\n",
        "        \"budgetDecision\": status,\n",
        "        \"missingTags\": \", \".join(missing_tags) if missing_tags else \"\",\n",
        "        \"approvalValid\": approval_ok,\n",
        "        \"finalDecision\": final\n",
        "    }\n",
        "\n",
        "\n",
        "scenarios = [\n",
        "    evaluate_request(\n",
        "        {\"subscription\": \"sub-prod-001\", \"resourceGroup\": \"rg-app-prod\", \"sku\": \"Standard_D2s_v5\", \"hoursPerMonth\": 730, \"region\": \"eastus\"},\n",
        "        {\"Owner\": \"team-payments\", \"CostCenter\": \"CC-1042\", \"Environment\": \"Prod\"},\n",
        "        {\"ApprovedBy\": \"\", \"TicketId\": \"\"}\n",
        "    ),\n",
        "    evaluate_request(\n",
        "        {\"subscription\": \"sub-prod-001\", \"resourceGroup\": \"rg-app-prod\", \"sku\": \"Standard_D4s_v5\", \"hoursPerMonth\": 730, \"region\": \"eastus\"},\n",
        "        {\"Owner\": \"team-payments\", \"CostCenter\": \"CC-1042\", \"Environment\": \"Prod\"},\n",
        "        {\"ApprovedBy\": \"finops.lead@contoso.com\", \"TicketId\": \"CHG-48291\"}\n",
        "    ),\n",
        "    evaluate_request(\n",
        "        {\"subscription\": \"sub-prod-001\", \"resourceGroup\": \"rg-app-prod\", \"sku\": \"AKS_Standard\", \"hoursPerMonth\": 730, \"region\": \"eastus\"},\n",
        "        {\"Owner\": \"team-platform\", \"CostCenter\": \"\", \"Environment\": \"Prod\"},\n",
        "        {\"ApprovedBy\": \"finops.lead@contoso.com\", \"TicketId\": \"CHG-48292\"}\n",
        "    ),\n",
        "    evaluate_request(\n",
        "        {\"subscription\": \"sub-prod-001\", \"resourceGroup\": \"rg-app-prod\", \"sku\": \"Premium_LRS_Storage\", \"hoursPerMonth\": 730, \"region\": \"eastus\"},\n",
        "        {\"Owner\": \"team-data\", \"CostCenter\": \"CC-2201\", \"Environment\": \"Prod\"},\n",
        "        {\"ApprovedBy\": \"\", \"TicketId\": \"\"}\n",
        "    )\n",
        "]\n",
        "\n",
        "pd.DataFrame(scenarios)"
      ],
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "## Reference workflow\n",
        "\n",
        "The blog's core process can be summarized as: proposal enters workflow, approved pricing context is retrieved, budget or policy checks are evaluated, human approval happens where required, and deployment proceeds only with evidence attached. This notebook validated that pattern using Python-only, read-first controls."
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "## Next Steps\n",
        "\n",
        "- Replace the mock pricing function with an approved enterprise pricing source.\n",
        "- Connect budget thresholds to your real FinOps policy model.\n",
        "- Persist review records to an auditable store for prompts, tool calls, approvals, and deployment outcomes.\n",
        "- Add stronger validation for ownership metadata, chargeback fields, and environment-specific controls.\n",
        "- Keep read-only pricing tools separate from write-capable deployment actions until controls are proven."
      ]
    }
  ]
}