AWS Bedrock — Dev Profile
GitHubOne container, ~/.aws mounted read-only, four short curls that isolate config / chat / embeddings / health — prove Bedrock reachability before adding any platform on top.
Project Files
name: lite-llm-dev-bedrock services: litellm: image: ghcr.io/berriai/litellm:main-stable container_name: lite-llm-dev-bedrock env_file: - .env command: ["--config", "/app/config.yaml", "--host", "0.0.0.0", "--port", "4000"] environment: AWS_REGION_NAME: ${AWS_REGION_NAME:-us-east-1} AWS_REGION: ${AWS_REGION:-us-east-1} AWS_PROFILE: ${AWS_PROFILE:-default} ports: - "${LITELLM_PORT:-4002}:4000" volumes: - ~/.aws:/root/.aws:ro - ./litellm_config.yaml:/app/config.yaml:ro restart: unless-stopped
Why a separate dev profile
Most Bedrock setup pain has nothing to do with LiteLLM — it is AWS-side. The common failure modes:-
IAM identity has no
bedrock:InvokeModelpermission - Model access not requested or approved in the Bedrock console
- The region you're calling does not host the model you picked
- Credentials missing, expired, or scoped to a different account
- AWS SSO session timed out and the host stopped refreshing credentials
What you're running
A single container, with your local AWS credentials mounted read-only:-
litellm— the LiteLLM proxy onhttp://localhost:4002,~/.awsmounted at/root/.aws:ro
Two model aliases, named on purpose to match OpenAI client defaults:
| Alias | Backing Bedrock model | Why this alias |
|---|---|---|
gpt-4o-mini | bedrock/amazon.nova-micro-v1:0 | Drop-in for code already calling gpt-4o-mini |
text-embedding-3-large | bedrock/amazon.titan-embed-text-v2:0 | Drop-in for code already calling text-embedding-3-large |
base_url and the auth token point at this gateway.
What this is NOT
- Not a production deployment — no TLS, no rate limiting, no secret manager, no autoscaling
- Not a benchmark — Nova Micro is picked because it's cheap and fast to invoke
- Not a replacement for the production stack — it's the smaller stack you debug first so the production stack only has to fight its own bugs
Dev vs prod — what actually differs
The Bedrock side is identical between the two profiles. Same model entries, same aws_region_name, same ~/.aws mount, same auth flow. Everything that differs is platform infrastructure around the gateway:
| Concern | dev-bedrock (this lesson) | prod-bedrock |
|---|---|---|
| Port | 4002 | 4003 |
| Services | litellm only | litellm + postgres + redis (both healthchecked) |
Admin UI (/ui/) | Not available (needs Postgres) | Available |
| Virtual keys / budgets | Not available | Available |
| Response cache | Off | On, Redis-backed |
num_retries | 1 | 2 |
fallbacks | None | Declared in router_settings |
set_verbose | true (loud logs for debug) | false (quieter logs) |
| Volumes | None | postgres_data, redis_data |
| AWS auth | ~/.aws:/root/.aws:ro | Same |
Deploy
- 1 Download All the project files into a new folder
-
2
Make sure
~/.awsexists with a working profile on your host -
3
Copy
env.exampleto.env— changeLITELLM_MASTER_KEYto something strong
cp env.example .env
docker compose --env-file .env -f docker-compose.yml up -d
You should see one container running:
docker ps --filter name=lite-llm-dev-bedrock
CONTAINER ID IMAGE STATUS
abc123 ghcr.io/berriai/litellm:main-stable Up
The four curls that isolate each layer
Each call answers one question. Run them in order. The first one that fails tells you which layer is broken.1. Did LiteLLM parse the config?
set -a
source .env
set +a
curl "http://localhost:${LITELLM_PORT:-4002}/v1/models" \
-H "Authorization: Bearer $LITELLM_MASTER_KEY"
Expected — a JSON object listing gpt-4o-mini and text-embedding-3-large.
If this fails, the gateway never started cleanly. Read docker compose logs -f litellm. It is almost always a YAML mistake in litellm_config.yaml or a missing env variable.
Note: This call does not prove AWS works — only that the config file loaded.
2. Does Bedrock chat actually work?
curl "http://localhost:${LITELLM_PORT:-4002}/v1/chat/completions" \
-H "Authorization: Bearer $LITELLM_MASTER_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "gpt-4o-mini",
"messages": [
{"role": "user", "content": "Reply with one short sentence: Bedrock works."}
]
}'
A successful response proves three things at once:
- AWS credentials are mounted into the container
-
IAM allows
bedrock:InvokeModelon Nova Micro - The region you set hosts Nova Micro
3. Do Bedrock embeddings work?
curl "http://localhost:${LITELLM_PORT:-4002}/v1/embeddings" \
-H "Authorization: Bearer $LITELLM_MASTER_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "text-embedding-3-large",
"input": "LiteLLM dev Bedrock embedding test"
}'
Security: Embedding access is a separate model-access toggle in the Bedrock console. This call can fail even when chat already works. That's a common surprise.
4. Does the gateway think the providers are healthy?
curl "http://localhost:${LITELLM_PORT:-4002}/health" \
-H "Authorization: Bearer $LITELLM_MASTER_KEY"
/health does a minimal upstream probe per model. Treat this as the single-shot sanity check before pointing an application at the gateway.
The seven Bedrock failure modes — ordered by likelihood
When/v1/models returns 200 but chat or embeddings fail, the bug is almost always one of these. Walk them in order:
- 1 Credentials not mounted. Inside the container:
docker exec -it lite-llm-dev-bedrock ls /root/.aws
If empty, the host ~/.aws is missing or the volume mount failed.
-
1
Wrong profile. The container reads
AWS_PROFILEfrom.env. If your host uses a non-default profile, set it explicitly. - 2
- 3 Expired SSO / STS credentials. If you use AWS SSO:
aws sso login --profile default
docker compose restart litellm
-
1
Missing IAM permission. Attach a policy granting
bedrock:InvokeModel(andbedrock:InvokeModelWithResponseStreamif you plan to stream) on the specific model ARNs. - 2
- 3 Model access not granted. AWS Console → Bedrock → Model access → request and wait for approval for Nova Micro and Titan Embed v2.
- 4
- 5 Wrong region. Not every Bedrock model is in every region:
aws bedrock list-foundation-models --region us-east-1
-
1
Region mismatch between env vars. LiteLLM reads
AWS_REGION_NAME. The AWS SDK also looks atAWS_REGIONandAWS_DEFAULT_REGION. This compose sets bothAWS_REGION_NAMEandAWS_REGION— keep them aligned.
Lab: Only after all seven check out is it worth reading verbose LiteLLM logs.
Why this matters for platform teams
The dev profile is where you build the muscle for AI infrastructure. It is the smallest place where you can:- Prove AWS Bedrock reachability without a Postgres dependency
- Prove the OpenAI-compatible alias trick does what existing client code expects
-
Iterate on
litellm_config.yamlquickly — restart in two seconds, re-run four curls
Next Steps
- AWS Bedrock — Prod Profile — same Bedrock model list, now wrapped in Postgres + Redis + admin UI + virtual keys + response cache