Choose a Cloud Provider

Su Suriya Ravichandran Updated 10 Nov 2026
5 min read ·Lesson 165 of 200

Four Ways to Reach the Same Model

Claude can be reached through the direct Anthropic API, Amazon Bedrock, Google Cloud's Vertex AI, and Microsoft Foundry. The model behind each path is the same family, and the Messages API is the same interface, so the choice is rarely about the quality of the answers. It is about the constraints around the application: where its data may be processed, which cloud the organization already pays for, which features it needs first, and how its teams prefer to manage access and billing.

This lesson sets out those constraints as criteria, shows how to turn them into a decision that can be explained and revisited, and warns about the choices that look attractive but cause trouble later. The decision is worth making deliberately, because switching platforms later means changing clients, identifiers, credentials, and tests.


The Criteria

Five questions usually decide the matter, and they should be answered in this order:

QuestionWhy it comes first
Are there residency or compliance rules about where data is processed?A hard rule removes options outright
Does the organization already have a commitment or a contract with a cloud?Consolidating billing and access usually outweighs small technical differences
Does the application need a feature that some platforms lack or lag on?A missing feature removes that platform until it arrives
Which identity system and operations model do the teams already use?Running services with familiar tools reduces operational risk
What is the cost, and does it differ by path?Pricing matters, but it is usually the last tie-breaker

The order reflects how hard each constraint is. A residency rule cannot be traded away, a feature gap can be planned around, and a price difference is usually small compared with the cost of a second identity system.


Features Are Not Uniform

The feature set can differ by platform and by date. A tool, a beta option, or a newer model may be available on the direct API before it reaches a cloud, or on one cloud before another. The documentation for each platform carries a feature table, and it should be read for every capability the application depends on, rather than assumed from the direct API's documentation.

The practical consequence is a checklist. For each feature the application needs, the team confirms availability on each candidate platform, and records the answer with its date. A platform that lacks one required feature is not automatically wrong, but it must be excluded for the features that depend on that one.


A Decision Function

A decision written as code can be reviewed, tested, and rerun when constraints change. The function below applies the criteria in order. It takes a profile of the application, and returns the platform with a stated reason, so the outcome can be explained to anyone who asks:

"""choose_provider.py: apply the selection criteria in order, and explain the result."""

PLATFORM_CLOUD = {"direct": "none", "bedrock": "aws", "vertex": "gcp", "foundry": "azure"}


def recommend(profile: dict) -> tuple[str, str]:
    candidates = ["direct", "bedrock", "vertex", "foundry"]

    residency = profile.get("residency_platforms")
    if residency:
        candidates = [p for p in candidates if p in residency]
        if not candidates:
            return "none", "no platform meets the residency requirement"
        if len(candidates) == 1:
            return candidates[0], "only platform in the residency set"

    gaps = profile.get("unsupported", {})
    candidates = [p for p in candidates
                  if not (profile.get("features", set()) & gaps.get(p, set()))]
    if not candidates:
        return "none", "no platform supports every required feature"

    cloud = profile.get("existing_cloud")
    if cloud:
        for platform in candidates:
            if PLATFORM_CLOUD[platform] == cloud:
                return platform, f"uses the existing commitment on {cloud}"

    return candidates[0], "direct API: simplest path when no cloud constraint applies"


if __name__ == "__main__":
    scenarios = {
        "cloud commitment": {"existing_cloud": "aws", "features": {"tool_search"}},
        "no constraints": {"features": {"computer_use"}, "unsupported": {"bedrock": {"computer_use"}}},
        "residency": {"residency_platforms": {"vertex"}, "features": set()},
    }
    for name, profile in scenarios.items():
        platform, reason = recommend(profile)
        print(f"{name}: {platform} ({reason})")

Output:

cloud commitment: bedrock (uses the existing commitment on aws)
no constraints: direct (direct API: simplest path when no cloud constraint applies)
residency: vertex (only platform in the residency set)

How It Works

  1. The residency rule runs first and can remove every candidate. When the required platforms are known, only those remain, and the function explains when none qualifies.
  2. Feature gaps remove platforms next. A platform is dropped when it lacks any feature the application needs, which is how a missing capability becomes a visible exclusion rather than a surprise later.
  3. The existing cloud commitment decides among what remains. The first remaining platform on the organization's cloud is chosen, and the reason says so.
  4. The default is the direct API, because it is the simplest path with no cloud dependency, and a cloud should be chosen only when a constraint asks for it.
  5. Every result carries a reason. A decision that cannot be explained cannot be audited, and the reasons make it possible to see which criterion decided each case.

Revisiting the Decision

Constraints change. A new residency rule, a new cloud agreement, or a feature that arrives on one platform can all reverse an earlier choice. The decision function is a record of the reasoning at one moment, and it should be rerun when the profile changes, with the old and new outcomes compared. A change in the outcome is a signal to plan a migration, which involves the client, identifiers, credentials, and tests from the lessons that follow.


Avoiding Premature Choices

A common mistake is to choose the cloud before the requirements are known, usually because it is familiar. The decision then becomes a justification rather than a comparison. Writing the criteria down first, and checking each candidate against them, keeps the choice honest, even when the answer happens to be the one the team expected.


Summary

The four paths reach the same model, and the choice depends on the application's constraints: residency rules, existing cloud commitments, feature availability, operations, and cost, in that order of weight. Features differ across platforms and over time, so each required feature must be checked on each candidate. A decision written as code, which applies the criteria in order and states its reasons, is easy to review and to revisit. The next lesson turns to the practical question of how a team configures each provider's client once it has chosen.

0 Comments

Reviewed before they appear

No comments yet.

Anthropic SDK Using Python
Anthropic SDK Intro Claude API Intro SDK Requirements Install Anthropic SDK Upgrade the SDK Create an API Key Set API Keys Use Environment Variables Import Anthropic Create a Client Send Your First Message Choose a Claude Model Set Max Tokens Read a Response Print Response Text Understand Message Blocks Use System Prompts Send User Messages Set Temperature Handle Stop Reasons Messages API Intro Create Messages Use Message Roles Send Conversation History Continue a Conversation Build a Chat Loop Reset Chat History Use Multiple Turns Inspect Message IDs Read Usage Data Write Clear Prompts Set a System Prompt Add Context to Prompts Use Prompt Templates Add Examples to Prompts Request JSON Output Use XML Tags Control Response Length Improve Prompt Quality Avoid Prompt Injection Read Text Blocks Read Content Blocks Check Stop Reasons Count Input Tokens Count Output Tokens Count Tokens Before Sending Limit Output Tokens Use Stop Sequences Read Request IDs Parse API Responses Streaming Intro Stream Text Output Use Stream Events Use Stream Helpers Get Final Messages Stream Async Responses Handle Stream Errors Build a Live Chat Stream Long Responses Close Streams Safely Build a Chatbot Keep Chat History Manage Chat Sessions Add Chat Memory Build a CLI Chatbot Build a Web Chatbot Use Flask with Claude Use FastAPI with Claude Return JSON from an API Add Chat Error Messages Async SDK Intro Create an Async Client Send Async Messages Use asyncio Run Parallel Requests Stream Async Text Handle Async Errors Set Async Timeouts Close Async Clients Choose Sync or Async Tool Use Intro Define a Tool Create Tool Schemas Send Tools to Claude Read Tool Calls Run Python Tools Return Tool Results Continue After Tool Use Control Tool Choice Handle Tool Errors Use the beta_tool Decorator Create a Tool Runner Add Tool Docstrings Validate Tool Inputs Use Multiple Tools Limit Tool Calls Log Tool Activity Build a Weather Tool Build a Search Tool Build a Calculator Tool Structured Output Intro Request JSON Data Validate JSON Output Use Pydantic Models Handle Invalid JSON Extract Fields from Text Generate Typed Data Use Image URLs Send Base64 Images Read PDFs with Claude Use Output Schemas Build Data Extraction Test Structured Responses Send Image Inputs Upload Files Use File IDs Process Text Files Summarize Documents Extract Table Data Handle File Errors Read Cache Usage Reduce Repeated Input Costs Debug Cache Misses Prompt Caching Intro Enable Prompt Caching Cache System Prompts Cache Long Context Test Cache Performance Use Cache Breakpoints Cache Best Practices Message Batches Intro Create a Message Batch Set Batch IDs Check Batch Status List Message Batches Get Batch Results Process Batch Outputs Handle Failed Batch Items Use Batches for Bulk Tasks Compare Batches and Requests Handle API Errors Handle Rate Limits Retry Failed Requests Set Request Timeouts Handle Network Errors Use Exponential Backoff Build Reliable API Calls Use Extended Thinking Log API Errors Track Request IDs Paginate API Results Set Thinking Budgets Read Thinking Blocks Use Tool Search Use Web Search Tools Use Computer Tools Use Citations Use Token Counting Read Raw Responses Set Custom Headers Use Claude on AWS Bedrock Use Claude on Vertex AI Use Claude on Microsoft Foundry Configure Cloud Credentials Choose a Cloud Provider Compare API Integrations Configure Provider Clients Handle Cloud Errors Use Cloud SDK Extras Deploy Cloud Apps Protect API Keys Use a .env File Ignore Secrets in Git Validate User Input Reduce Prompt Injection Limit Tool Permissions Avoid Unsafe Tool Calls Sanitize Tool Results Set Usage Limits Review Security Logs Test SDK Functions Mock API Responses Test Error Handling Test Streaming Code Measure Token Usage Track API Costs Configure Logging Deploy with Docker Deploy a FastAPI App Monitor Production Apps Build a Claude Chatbot Build a Text Summarizer Build a Code Explainer Build a JSON Extractor Build a PDF Assistant Build a Streaming Chat App Build a Tool-Calling Agent Build a Batch Processor Build a Research Assistant Build a Claude API Dashboard
Ask about this post
AI Ask about this post

Ask questions about Choose a Cloud Provider and get answers drawn from it.

Signed-in readers only.