Switching from AWS Bedrock to Azure OpenAI

A developer's guide to migrating from AWS Bedrock to Azure OpenAI Service, covering SDK changes, model mapping, pricing differences, and authentication gotchas.

From: AWS Bedrock To: Azure OpenAI Service Difficulty: Medium
Switching from AWS Bedrock to Azure OpenAI

TL;DR

  • Yes, you can switch - but expect to rewrite your inference code since the SDKs are completely different (boto3 vs openai Python package)
  • Model mapping isn't one-to-one: Bedrock offers Claude, Llama, and Mistral with Nova; Azure locks you into the OpenAI family (GPT-5, GPT-4o, o3/o4-mini)
  • Azure's OpenAI SDK uses the familiar openai Python library, which simplifies the migration if your team already knows the OpenAI API
  • Medium difficulty, roughly 1-2 weeks for a production codebase depending on how many Bedrock-specific features you use

Why Switch to Azure OpenAI

Most teams moving from Bedrock to Azure OpenAI do it for one of three reasons: they need exclusive access to OpenAI's latest models, their organization is already deep in the Microsoft ecosystem, or they want tighter integration with Microsoft 365 and Azure Active Directory.

AWS Bedrock's strength is model diversity. It pools over 40 foundation models from Anthropic, Meta, Mistral, Cohere, DeepSeek, and Amazon's own Nova lineup, all behind a unified API. Azure OpenAI takes the opposite approach - it curates a smaller set of models, all from OpenAI, but gives you early and often exclusive access to the GPT-5 series, GPT-4.1, o3, o4-mini, and specialized variants like GPT-5.4 that aren't available on Bedrock.

If your workloads rely heavily on Claude or Llama 4, switching to Azure OpenAI means losing access to those models entirely. But if GPT-class models are your primary need and you want Microsoft's compliance stack (FedRAMP High, DoD IL5/IL6, HIPAA BAA built in), Azure OpenAI is a strong fit.

Azure OpenAI playground interface for testing model deployments Azure OpenAI's chat playground in the Microsoft Foundry portal, where you can test deployments and configure parameters before writing code. Source: learn.microsoft.com

Feature Parity Table

FeatureAWS BedrockAzure OpenAINotes
Chat completionsConverse API (brt.converse())Chat Completions API (client.chat.completions.create())Different SDK, similar concepts
StreamingConverseStreamstream=True parameterBoth support SSE streaming
Function/tool callingConverse API toolConfigtools[] parameter (OpenAI format)Different schema structure
Image inputSupported via Converse APISupported via image_url in messagesBoth handle vision tasks
EmbeddingsCohere Embed, Amazon Titan Embedtext-embedding-3-large/small, AdaDifferent model families
Image generationAmazon Nova Canvas, Stability AIDALL-E 3Bedrock has more options
Model variety40+ models from 10+ providersOpenAI models onlyBedrock wins on diversity
Fine-tuningSupported for select modelsSupported for GPT-4o, GPT-4o-miniBoth offer customization
AuthenticationAWS IAM + SigV4Azure AD (Entra ID) or API keyCompletely different auth systems
Content filteringGuardrails (configurable)Built-in content filtersAzure filters are on by default
Batch inference50% discount, asyncBatch API, 50% discount, 24h windowSimilar economics
Provisioned throughputProvisioned Throughput UnitsProvisioned Throughput Units (PTUs)Both offer reserved capacity

SDK and API Mapping

This is where the migration gets hands-on. Bedrock uses AWS's boto3 SDK with the bedrock-runtime service client. Azure OpenAI uses the standard openai Python package with an AzureOpenAI (or just OpenAI) client class pointed at your Azure endpoint.

Basic Chat Completion

Before (AWS Bedrock):

import boto3

client = boto3.client("bedrock-runtime", region_name="us-east-1")

response = client.converse(
    modelId="anthropic.claude-sonnet-4-6",
    messages=[
        {
            "role": "user",
            "content": [{"text": "What is cloud computing?"}],
        }
    ],
    inferenceConfig={"maxTokens": 512, "temperature": 0.7},
)

print(response["output"]["message"]["content"][0]["text"])

After (Azure OpenAI):

import os
from openai import OpenAI

client = OpenAI(
    api_key=os.getenv("AZURE_OPENAI_API_KEY"),
    base_url="https://YOUR-RESOURCE.openai.azure.com/openai/v1/",
)

response = client.chat.completions.create(
    model="gpt-5",  # your deployment name
    messages=[
        {"role": "system", "content": "You are a helpful assistant."},
        {"role": "user", "content": "What is cloud computing?"},
    ],
    max_tokens=512,
    temperature=0.7,
)

print(response.choices[0].message.content)

Notice the structural differences. Bedrock wraps message content in a list of typed objects ([{"text": "..."}]), while Azure OpenAI uses the flat OpenAI format ("content": "..."). Bedrock puts inference parameters under inferenceConfig; Azure OpenAI puts them as top-level parameters on the API call.

Code editor showing API migration between cloud platforms Migrating inference code requires rewriting client initialization, message formatting, and response parsing. Source: pexels.com

Streaming Response

Before (AWS Bedrock):

response = client.converse_stream(
    modelId="anthropic.claude-sonnet-4-6",
    messages=[{"role": "user", "content": [{"text": "Explain Docker."}]}],
    inferenceConfig={"maxTokens": 1024},
)

for event in response["stream"]:
    if "contentBlockDelta" in event:
        print(event["contentBlockDelta"]["delta"]["text"], end="")

After (Azure OpenAI):

stream = client.chat.completions.create(
    model="gpt-5",
    messages=[{"role": "user", "content": "Explain Docker."}],
    max_tokens=1024,
    stream=True,
)

for chunk in stream:
    if chunk.choices[0].delta.content:
        print(chunk.choices[0].delta.content, end="")

The streaming APIs differ substantially. Bedrock sends events wrapped in a dictionary with event type keys (contentBlockDelta, messageStop). Azure OpenAI streams typed chunk objects with a .choices[0].delta.content accessor. If you're using LiteLLM or LangChain as an abstraction layer, the migration is simpler since these libraries handle both backends - check our LangChain to LlamaIndex migration guide for framework-level switching patterns.

Tool Calling

Before (AWS Bedrock - Converse API):

tool_config = {
    "tools": [
        {
            "toolSpec": {
                "name": "get_weather",
                "description": "Get current weather for a city",
                "inputSchema": {
                    "json": {
                        "type": "object",
                        "properties": {
                            "city": {"type": "string", "description": "City name"}
                        },
                        "required": ["city"],
                    }
                },
            }
        }
    ]
}

response = client.converse(
    modelId="anthropic.claude-sonnet-4-6",
    messages=[{"role": "user", "content": [{"text": "Weather in London?"}]}],
    toolConfig=tool_config,
)

After (Azure OpenAI):

tools = [
    {
        "type": "function",
        "function": {
            "name": "get_weather",
            "description": "Get current weather for a city",
            "parameters": {
                "type": "object",
                "properties": {
                    "city": {"type": "string", "description": "City name"}
                },
                "required": ["city"],
            },
        },
    }
]

response = client.chat.completions.create(
    model="gpt-5",
    messages=[{"role": "user", "content": "Weather in London?"}],
    tools=tools,
)

The tool schemas look similar but nest differently. Bedrock uses toolSpec with inputSchema.json; Azure OpenAI uses function with parameters. You'll need to restructure your tool definitions during migration.

Model Availability

One of the biggest trade-offs in this migration is model access. AWS Bedrock and Azure OpenAI overlap on zero models - they serve completely different provider ecosystems.

Use CaseAWS Bedrock OptionAzure OpenAI Equivalent
Flagship reasoningClaude Opus 4.6GPT-5.4
Fast general purposeClaude Sonnet 4.6, Nova ProGPT-5, GPT-4o
Cost-efficientClaude Haiku 4.5, Nova MicroGPT-5-mini, GPT-5-nano
Code generationDeepSeek V3.2, Claude SonnetGPT-5.4, GPT-4.1
EmbeddingsCohere Embed v4, Amazon Titantext-embedding-3-large/small
Image generationNova Canvas, Stable Diffusion 3.5DALL-E 3
Open-source modelsLlama 4, Mistral Large 3, Qwen 3Not available

If you currently use Claude through Bedrock and want to keep using it, Azure OpenAI isn't the right destination. Consider the Anthropic API directly instead.

Pricing Comparison

Both platforms charge per token on a pay-as-you-go basis, but the specific rates and model tiers differ. For a sample workload of 10 million input tokens and 2 million output tokens per month on a mid-tier model:

Model TierAWS Bedrock (per 1M tokens)Azure OpenAI (per 1M tokens)Monthly Cost (10M in / 2M out)
FlagshipClaude Opus 4.6: ~$15 in / $75 outGPT-5.4: ~$15 in / $120 outBedrock: $300 / Azure: $390
Mid-tierClaude Sonnet 4.6: ~$6 in / $30 outGPT-5: $1.25 in / $10 outBedrock: $120 / Azure: $32.50
BudgetNova Micro: $0.035 in / $0.14 outGPT-5-nano: $0.05 in / $0.40 outBedrock: $0.63 / Azure: $1.30

The mid-tier comparison is striking. Azure OpenAI's GPT-5 is substantially cheaper per token than Claude Sonnet on Bedrock, though model quality varies by task. At the budget tier, Amazon Nova Micro undercuts everything. For detailed pricing breakdowns across more providers, see our LLM API pricing comparison.

Both platforms offer prompt caching to reduce costs on repeated context. Bedrock charges 1.25x for cache writes and 0.1x for cache reads; Azure OpenAI offers cached input tokens at roughly 90% discount on select models.

Authentication and Deployment

This is the migration step that often takes longest because it involves infrastructure changes, not just code.

Step 1 - Set Up Azure OpenAI Resource

  1. Create an Azure OpenAI resource in the Azure portal
  2. Deploy your chosen model (GPT-5, GPT-4o, etc.) through the Microsoft Foundry portal at ai.azure.com
  3. Note your endpoint URL and either create an API key or configure Microsoft Entra ID authentication

Step 2 - Update Authentication

Bedrock uses AWS IAM credentials with SigV4 signing, usually through environment variables (AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY) or IAM roles. Azure OpenAI supports two authentication methods:

API Key (simpler):

client = OpenAI(
    api_key=os.getenv("AZURE_OPENAI_API_KEY"),
    base_url="https://YOUR-RESOURCE.openai.azure.com/openai/v1/",
)

Microsoft Entra ID (recommended for production):

from azure.identity import DefaultAzureCredential, get_bearer_token_provider

token_provider = get_bearer_token_provider(
    DefaultAzureCredential(), "https://ai.azure.com/.default"
)

client = OpenAI(
    base_url="https://YOUR-RESOURCE.openai.azure.com/openai/v1/",
    api_key=token_provider,
)

Step 3 - Update Dependencies

Remove boto3 (or at least the Bedrock-specific usage) and add the openai package. If using Entra ID, also add azure-identity:

pip install openai azure-identity

Step 4 - Rewrite Inference Calls

Using the code examples above, update every converse() or invoke_model() call to chat.completions.create(). The response parsing also changes - Bedrock returns nested dictionaries while Azure OpenAI returns typed Python objects.

Step 5 - Update Monitoring

Replace CloudWatch metrics and logging with Azure Monitor. If you're using Bedrock Guardrails for content filtering, note that Azure OpenAI has built-in content filters enabled by default, which you can customize but not fully disable.

Known Gotchas

  1. Model deployment is required. Unlike Bedrock where you simply reference a model ID, Azure OpenAI requires you to explicitly deploy each model before calling it. The model parameter in API calls refers to your deployment name, not the model name itself.

  2. Content filters are on by default. Azure OpenAI applies content filtering to all requests. Some prompts that worked on Bedrock may get blocked. You can adjust severity thresholds through the Azure portal but can't remove filters entirely without applying for a managed customer exemption.

  3. No multi-provider access. On Bedrock, you could call Claude for reasoning, Llama for code, and Nova for cheap tasks in the same codebase. Azure OpenAI only serves OpenAI models. If you need model diversity, you'll need additional providers.

  4. Region availability differs. Not all Azure regions offer all models. GPT-5.4 and the latest reasoning models may only be available in specific regions. Check Azure's model availability page before choosing your region.

  5. Quota and rate limits need pre-approval. Azure OpenAI assigns default tokens-per-minute quotas that are often lower than Bedrock's defaults. For production workloads, you'll likely need to request quota increases through the Azure portal.

  6. The Converse API has no direct equivalent. Bedrock's Converse API unified multi-model access behind one schema. On Azure OpenAI, the chat completions API already follows OpenAI's standard format, so there's less need for unification - but if your code relied on Converse's model-agnostic structure, you'll need to update your abstraction layer.

  7. Embedding dimensions differ. If you're migrating embeddings alongside chat, Cohere Embed v4 and Amazon Titan Embed produce different vector dimensions than OpenAI's text-embedding-3-large (3072) or text-embedding-3-small (1536). You'll need to re-embed your entire vector store. See our embedding models pricing guide for cost estimates.

FAQ

Can I use the same SDK for both platforms?

No. Bedrock requires boto3 while Azure OpenAI uses the openai Python package. Libraries like LiteLLM can abstract both, but native SDK code must be rewritten.

Will my Bedrock prompts work on Azure OpenAI without changes?

Most prompts transfer well since both platforms follow chat completion conventions. Prompts relying on Claude's XML tag style or model-specific features will need adjustment.

Is there a compatibility layer between Bedrock and Azure OpenAI?

LiteLLM and LangChain both support both backends. You can also build a thin wrapper that translates Bedrock's Converse format to OpenAI's chat completions format.

How long does a typical migration take?

For a production codebase with 5-10 inference endpoints, expect 1-2 weeks including testing. The authentication and deployment setup adds 1-3 days depending on your Azure environment.

Can I keep using Claude after migrating to Azure?

Not through Azure OpenAI. You'd need to call the Anthropic API directly or use a proxy service. Azure OpenAI only serves OpenAI models.

Which platform has better compliance coverage?

Both are strong. Bedrock holds FedRAMP High, HIPAA, SOC 1/2/3, ISO 27001, and PCI DSS. Azure OpenAI matches this and adds DoD IL5/IL6 authorization and built-in Microsoft Purview integration.


Sources:

✓ Last verified March 26, 2026

Switching from AWS Bedrock to Azure OpenAI
About the author AI Education & Guides Writer

Priya is an AI educator and technical writer whose mission is making artificial intelligence approachable for everyone - not just engineers.