# Multi-Cloud Pricing Cost Impact Report (`taroyamada/multi-cloud-pricing-cost-impact-report`) Actor

Compare official AWS public price-list and Azure Retail Prices data for explicitly normalized workload scenarios. Get source-linked cross-provider cost reports, price-change alerts, and exports without cloud credentials.

- **URL**: https://apify.com/taroyamada/multi-cloud-pricing-cost-impact-report.md
- **Developed by:** [naoki anzai](https://apify.com/taroyamada) (community)
- **Categories:** Automation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $6.00 / 1,000 multi-cloud price rows

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

Learn more: https://docs.apify.com/platform/actors/running/actors-in-store#pay-per-event

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.
Actors are written with capital "A".

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

## Multi-Cloud Pricing Cost Impact Report

FinOps and cloud architecture teams enter comparable workload scenarios with one bounded AWS public-price selector and one bounded Azure Retail Prices selector.
The Actor maps each provider quantity to the same explicit normalized unit and returns a source-linked cross-provider cost comparison report.
It also emits price-change alerts and optional exports; the first baseline and unchanged checks emit zero rows and zero charge.

### Store Quickstart

Run the first check with `baseline_only` to save an isolated AWS/Azure baseline without delivery or charges. Use one exact product or meter selector per provider and keep the normalized workload assumptions explicit.

```json
{
  "scenarios": [
    {
      "id": "object-storage-monthly",
      "workloadLabel": "Object storage monthly capacity",
      "comparisonAssumptions": "Compare the first public storage tier for the same monthly capacity. Requests, retrieval, replication, egress, discounts, tax, support, credits, and free tiers are excluded.",
      "normalizedUsage": { "unit": "storage-gb-month", "quantity": 1000 },
      "aws": {
        "serviceCode": "AmazonS3",
        "region": "us-east-1",
        "selectors": { "productFamily": "Storage", "unit": "GB-Mo", "descriptionIncludes": ["first 50 TB"], "attributes": { "storageClass": "General Purpose", "volumeType": "Standard" } },
        "usage": { "quantity": 1000, "unit": "GB-Mo", "mappingNote": "One thousand GB-months maps to the normalized monthly storage capacity." }
      },
      "azure": {
        "serviceName": "Storage",
        "armRegionName": "eastus",
        "selectors": { "meterName": "Hot LRS Data Stored", "productName": "Blob Storage", "priceType": "Consumption", "tierMinimumUnits": 0 },
        "usage": { "quantity": 1000, "unit": "1 GB/Month", "mappingNote": "The Azure first storage tier maps to the same normalized monthly storage capacity." }
      }
    }
  ],
  "monitorKey": "finops-api-compute",
  "initialRunMode": "baseline_only",
  "generateReport": true,
  "emitRawRows": false,
  "emitExport": false,
  "emitUnchanged": false,
  "maxChargeUsd": 25,
  "dryRun": false
}
```

### Run the next report

After the baseline, schedule the identical `monitorKey` and scenario selectors. A changed AWS or Azure price emits a source-linked alert and a comparison report. A run with no price change emits zero dataset rows and zero charges, even when `emitUnchanged` is true.

For a one-time current report, use `initialRunMode: "emit_current"`. The report is delivered first, followed by change alerts, optional provider rows, and the export.

### Input examples

#### Storage scenario with an explicit normalized unit

```json
{
  "scenarios": [
    {
      "id": "object-storage-monthly",
      "workloadLabel": "Object storage monthly capacity",
      "comparisonAssumptions": "Compare one normalized storage-capacity month. Requests, retrieval, replication, egress, discounts, tax, support, and free tiers are outside this scenario.",
      "normalizedUsage": { "unit": "storage-gb-month", "quantity": 1000 },
      "aws": {
        "serviceCode": "AmazonS3",
        "region": "us-east-1",
        "selectors": { "productFamily": "Storage", "attributes": { "storageClass": "General Purpose" }, "unit": "GB-Mo" },
        "usage": { "quantity": 1000, "unit": "GB-Mo", "mappingNote": "One thousand GB-months is the shared normalized storage quantity." }
      },
      "azure": {
        "serviceName": "Storage",
        "armRegionName": "eastus",
        "selectors": { "meterName": "Hot LRS Data Stored", "productName": "Blob Storage", "priceType": "Consumption" },
        "usage": { "quantity": 1000, "unit": "1 GB/Month", "mappingNote": "The selected Blob Storage meter maps to one thousand storage GB-months." }
      }
    }
  ],
  "monitorKey": "storage-portfolio",
  "initialRunMode": "baseline_only",
  "maxChargeUsd": 25,
  "dryRun": false
}
```

#### Current comparison with export

```json
{
  "scenarios": [
    {
      "id": "database-monthly",
      "workloadLabel": "Managed database monthly compute",
      "comparisonAssumptions": "Compare the stated monthly database compute quantity only. Storage, I/O, backup, high availability, discounts, tax, support, and egress are excluded.",
      "normalizedUsage": { "unit": "database-compute-hour", "quantity": 730 },
      "aws": {
        "serviceCode": "AmazonRDS",
        "region": "us-east-1",
        "selectors": { "productFamily": "Database Instance", "usageType": "InstanceUsage", "unit": "Hrs" },
        "usage": { "quantity": 730, "unit": "Hrs", "mappingNote": "730 provider hours represent the normalized database-compute-hour quantity." }
      },
      "azure": {
        "serviceName": "SQL Database",
        "armRegionName": "eastus",
        "selectors": { "meterName": "vCore", "productName": "SQL Database", "priceType": "Consumption" },
        "usage": { "quantity": 730, "unit": "1 Hour", "mappingNote": "730 Azure meter hours represent the same stated normalized database-compute-hour quantity." }
      }
    }
  ],
  "monitorKey": "database-comparison",
  "initialRunMode": "emit_current",
  "generateReport": true,
  "emitExport": true,
  "maxChargeUsd": 25,
  "dryRun": false
}
```

### Output and pricing

The report is the buyer-facing primary result. It retains both provider source URLs, normalized unit and quantity, provider units and quantities, mapping notes, assumptions, current monthly estimates, and the difference between them.

| Event | Price | Delivered when |
|---|---:|---|
| `multi-cloud-price-row` | $0.006 | Optional normalized AWS or Azure public price row |
| `multi-cloud-price-change-alert` | $0.20 | A selected AWS or Azure price row is added, changed, or removed |
| `multi-cloud-cost-comparison-report` | $12.00 | A current comparison is reportable after baseline or a provider change |
| `multi-cloud-pricing-export` | $8.00 | A source-linked JSON export is requested |

There is no start charge. The Actor preflights every event and stops if `maxChargeUsd` would be exceeded. State is committed only after delivery succeeds. Unknown event names, missing `chargedCount`, event charge limits, invalid source data, and state-write failures fail closed.

### Data source and safeguards

- AWS source: [AWS public price-list files](https://docs.aws.amazon.com/awsaccountbilling/latest/aboutv2/price-changes.html), accessed from `pricing.us-east-1.amazonaws.com` without an AWS key.
- Azure source: [Azure Retail Prices API](https://learn.microsoft.com/en-us/rest/api/cost-management/retail-prices/azure-retail-prices), accessed from `prices.azure.com` without an Azure subscription or key.
- GCP is explicitly excluded because this Actor does not add a billing or credential dependency.
- Oracle Cloud is explicitly excluded because no stable, verified machine-readable public retail-price API is used here.
- AWS selectors and Azure selectors are exact and bounded; ambiguous multiple matches fail closed.
- Public list prices are before discounts, tax, support, credits, free tiers, egress, and account-specific terms. No savings guarantee is made.
- This Actor is not affiliated with or endorsed by AWS, Amazon, Microsoft, Azure, GCP, or Oracle.

### See also

- [AWS Cloud Pricing Cost Impact Report](https://apify.com/taroyamada/aws-cloud-pricing-cost-impact-report) for AWS-only price monitoring.
- [Azure Retail Price Cost Impact Report](https://apify.com/taroyamada/azure-retail-price-cost-impact-report) for Azure-only price monitoring.
- [AI API Pricing & Model Lifecycle Report](https://apify.com/taroyamada/ai-api-pricing-model-lifecycle-report) for a public API pricing workflow.

### Development

```text
npm test
npm start
```

# Actor input Schema

## `scenarios` (type: `array`):

Each scenario must define one AWS selector, one Azure selector, the provider quantities, a shared normalized unit/quantity, and explicit comparison assumptions.

## `monitorKey` (type: `string`):

Stable state namespace for the same scenario portfolio.

## `initialRunMode` (type: `string`):

Store a free baseline or emit the current comparison.

## `generateReport` (type: `boolean`):

Generate one source-linked comparison report when current or changed prices are emitted.

## `emitRawRows` (type: `boolean`):

Optional low-cost provider rows. Reports and alerts remain the primary output.

## `emitExport` (type: `boolean`):

Generate a compact JSON export with the comparison.

## `emitUnchanged` (type: `boolean`):

Accepted for compatibility; unchanged runs always emit zero rows and zero charges.

## `maxPagesPerScope` (type: `integer`):

Maximum official Azure continuation pages fetched per scenario.

## `maxItemsPerProvider` (type: `integer`):

Maximum exact public price matches retained per provider.

## `maxChargeUsd` (type: `number`):

Fail closed before delivery if planned PAY\_PER\_EVENT charges exceed this cap.

## `dryRun` (type: `boolean`):

Return representative rows for all event types without network, state, delivery, or charges.

## Actor input object example

```json
{
  "scenarios": [
    {
      "id": "object-storage-monthly",
      "workloadLabel": "Object storage monthly capacity",
      "comparisonAssumptions": "Compare the first public storage tier for the same monthly capacity. Requests, retrieval, replication, egress, discounts, tax, support, credits, and free tiers are excluded.",
      "normalizedUsage": {
        "unit": "storage-gb-month",
        "quantity": 1000
      },
      "aws": {
        "serviceCode": "AmazonS3",
        "region": "us-east-1",
        "selectors": {
          "productFamily": "Storage",
          "unit": "GB-Mo",
          "descriptionIncludes": [
            "first 50 TB"
          ],
          "attributes": {
            "storageClass": "General Purpose",
            "volumeType": "Standard"
          }
        },
        "usage": {
          "quantity": 1000,
          "unit": "GB-Mo",
          "mappingNote": "One thousand GB-months is the normalized monthly capacity for this example."
        }
      },
      "azure": {
        "serviceName": "Storage",
        "armRegionName": "eastus",
        "selectors": {
          "meterName": "Hot LRS Data Stored",
          "productName": "Blob Storage",
          "priceType": "Consumption",
          "tierMinimumUnits": 0
        },
        "usage": {
          "quantity": 1000,
          "unit": "1 GB/Month",
          "mappingNote": "The Azure first storage tier is mapped to the same one thousand storage GB-months."
        }
      }
    }
  ],
  "monitorKey": "multi-cloud-finops-watch",
  "initialRunMode": "baseline_only",
  "generateReport": true,
  "emitRawRows": false,
  "emitExport": false,
  "emitUnchanged": false,
  "maxPagesPerScope": 2,
  "maxItemsPerProvider": 20,
  "maxChargeUsd": 25,
  "dryRun": false
}
```

# Actor output Schema

## `results` (type: `string`):

Source-linked AWS/Azure comparison rows written to the run default dataset.

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "scenarios": [
        {
            "id": "object-storage-monthly",
            "workloadLabel": "Object storage monthly capacity",
            "comparisonAssumptions": "Compare the first public storage tier for the same monthly capacity. Requests, retrieval, replication, egress, discounts, tax, support, credits, and free tiers are excluded.",
            "normalizedUsage": {
                "unit": "storage-gb-month",
                "quantity": 1000
            },
            "aws": {
                "serviceCode": "AmazonS3",
                "region": "us-east-1",
                "selectors": {
                    "productFamily": "Storage",
                    "unit": "GB-Mo",
                    "descriptionIncludes": [
                        "first 50 TB"
                    ],
                    "attributes": {
                        "storageClass": "General Purpose",
                        "volumeType": "Standard"
                    }
                },
                "usage": {
                    "quantity": 1000,
                    "unit": "GB-Mo",
                    "mappingNote": "One thousand GB-months is the normalized monthly capacity for this example."
                }
            },
            "azure": {
                "serviceName": "Storage",
                "armRegionName": "eastus",
                "selectors": {
                    "meterName": "Hot LRS Data Stored",
                    "productName": "Blob Storage",
                    "priceType": "Consumption",
                    "tierMinimumUnits": 0
                },
                "usage": {
                    "quantity": 1000,
                    "unit": "1 GB/Month",
                    "mappingNote": "The Azure first storage tier is mapped to the same one thousand storage GB-months."
                }
            }
        }
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("taroyamada/multi-cloud-pricing-cost-impact-report").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = { "scenarios": [{
            "id": "object-storage-monthly",
            "workloadLabel": "Object storage monthly capacity",
            "comparisonAssumptions": "Compare the first public storage tier for the same monthly capacity. Requests, retrieval, replication, egress, discounts, tax, support, credits, and free tiers are excluded.",
            "normalizedUsage": {
                "unit": "storage-gb-month",
                "quantity": 1000,
            },
            "aws": {
                "serviceCode": "AmazonS3",
                "region": "us-east-1",
                "selectors": {
                    "productFamily": "Storage",
                    "unit": "GB-Mo",
                    "descriptionIncludes": ["first 50 TB"],
                    "attributes": {
                        "storageClass": "General Purpose",
                        "volumeType": "Standard",
                    },
                },
                "usage": {
                    "quantity": 1000,
                    "unit": "GB-Mo",
                    "mappingNote": "One thousand GB-months is the normalized monthly capacity for this example.",
                },
            },
            "azure": {
                "serviceName": "Storage",
                "armRegionName": "eastus",
                "selectors": {
                    "meterName": "Hot LRS Data Stored",
                    "productName": "Blob Storage",
                    "priceType": "Consumption",
                    "tierMinimumUnits": 0,
                },
                "usage": {
                    "quantity": 1000,
                    "unit": "1 GB/Month",
                    "mappingNote": "The Azure first storage tier is mapped to the same one thousand storage GB-months.",
                },
            },
        }] }

# Run the Actor and wait for it to finish
run = client.actor("taroyamada/multi-cloud-pricing-cost-impact-report").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "scenarios": [
    {
      "id": "object-storage-monthly",
      "workloadLabel": "Object storage monthly capacity",
      "comparisonAssumptions": "Compare the first public storage tier for the same monthly capacity. Requests, retrieval, replication, egress, discounts, tax, support, credits, and free tiers are excluded.",
      "normalizedUsage": {
        "unit": "storage-gb-month",
        "quantity": 1000
      },
      "aws": {
        "serviceCode": "AmazonS3",
        "region": "us-east-1",
        "selectors": {
          "productFamily": "Storage",
          "unit": "GB-Mo",
          "descriptionIncludes": [
            "first 50 TB"
          ],
          "attributes": {
            "storageClass": "General Purpose",
            "volumeType": "Standard"
          }
        },
        "usage": {
          "quantity": 1000,
          "unit": "GB-Mo",
          "mappingNote": "One thousand GB-months is the normalized monthly capacity for this example."
        }
      },
      "azure": {
        "serviceName": "Storage",
        "armRegionName": "eastus",
        "selectors": {
          "meterName": "Hot LRS Data Stored",
          "productName": "Blob Storage",
          "priceType": "Consumption",
          "tierMinimumUnits": 0
        },
        "usage": {
          "quantity": 1000,
          "unit": "1 GB/Month",
          "mappingNote": "The Azure first storage tier is mapped to the same one thousand storage GB-months."
        }
      }
    }
  ]
}' |
apify call taroyamada/multi-cloud-pricing-cost-impact-report --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,taroyamada/multi-cloud-pricing-cost-impact-report"
        }
    }
}

```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/XSfn5oibDkWi2GWWl/builds/mBOeiO5HQ0iYPzIBa/openapi.json
