Module 1: Genai In Production Vs A Notebook
7. Hands-on: the honest attempt against Bedrock on LocalStack
Description
This lesson does, literally, what its title promises: it tries to actually touch Bedrock, against LocalStack, in this very writing environment, and documents the real result — not a prose simulation of what "probably" would happen. The attempt stops at two distinct points, each with its exact, cited cause, not assumed. The first one ran, for real, while writing this lesson. The second is the conclusion, verified against LocalStack's official documentation, of what would happen one step further, even with the first obstacle resolved. It's the same honesty pattern you already saw, in a different domain, in cloud-security-and-guardrails-guide M2.6 — the experiment that shows exactly where what a $0 lab can prove ends.
Connection to the module
Lesson 5 confirmed, representatively, the inherited infrastructure. Lesson 6 mapped the model catalog. This lesson connects both: it tries to use that catalog against that same infrastructure, and precisely documents why that attempt never produces a real model's response — the central piece of the honesty commitment lesson 1 previewed. Lesson 8, this module's project, turns this conclusion into an ADR's first formal decision.
Step 1 — The real attempt: starting LocalStack in this environment
The command a student would run first, before being able to execute any awslocal command, is starting the LocalStack container itself:
docker run -d -p 4566:4566 --name localstack-bedrock-test localstack/localstack:latest
This command ran for real, in this environment, to write this lesson — it isn't invented output.
What to expect (literal — executed in this sandbox while writing this lesson):
LocalStack version: 2026.7.4
LocalStack build date: 2026-08-14
LocalStack build git hash: 875b30838
Localstack returning with exit code 55. Reason:
===============================================
License activation failed! 🔑❌
Reason: No credentials were found in the environment. Please make sure to either
set the LOCALSTACK_AUTH_TOKEN variable to a valid auth token. If you are using
the CLI, you can also run `localstack auth set-token`.
Due to this error, Localstack has quit. LocalStack pro features can only be
used with a valid license.
The container starts, prints its version, and shuts itself down, with exit code 55, before exposing a single endpoint. Notice something important: this message doesn't mention Bedrock anywhere. It's the exact same limit you already saw in lesson 5 of this module — this specific writing environment has no LOCALSTACK_AUTH_TOKEN exported, so the container never gets to start, for any service, not even the ones that are in the free Hobby plan (EventBridge, Lambda, IAM). On your own machine, with a free LocalStack account and a registered Hobby token, this first step does work — the container starts, and lesson 5's commands run for real.
Step 2 — The second obstacle, the one not even a Hobby token resolves
This is where this lesson stops repeating lesson 5's pattern and becomes genuinely different. With the first obstacle resolved — a real, exported Hobby token, the container starting without a hitch, exactly as in lesson 5 —, the next command would be:
awslocal bedrock list-foundation-models --region us-east-1
This command did not run against a working LocalStack — not in this sandbox, because of Step 1, nor would it help to try it with a Hobby token, for the reason that follows. This section's conclusion is representative, but built on a verified source, not assumed: LocalStack's own official documentation page for Bedrock coverage.
The exact quote, verified at docs.localstack.cloud/aws/services/bedrock/: the page's badge states, verbatim, "Included in Plans: Ultimate" — with no mention of Hobby, no mention of Base. It's the same badge pattern cloud-security-and-guardrails-guide already documented for IAM Policy Enforcement ("Included in Plans: Base, Ultimate"), here one step more restrictive: not even the intermediate paid plan (Base) includes it, only Ultimate.
What to expect (representative — reconstructed against LocalStack's documented behavior for a service outside the active plan):
An error occurred (InternalFailure) when calling the ListFoundationModels
operation: API for service 'bedrock' is not included in your current license
plan. Please contact LocalStack support or upgrade your plan to access this
API.
This is where lesson 1's honesty commitment becomes concrete: not even with a free, registered Hobby token would this command produce a real response. This isn't the same kind of limit as EventBridge/Lambda/IAM in lesson 5 — there, the limit was exclusive to this writing environment. Here, the limit belongs to the service itself, documented, and it persists even if you resolve Step 1.
The two obstacles, in a single diagram
THE ATTEMPT AGAINST BEDROCK, STEP BY STEP
docker run localstack/localstack:latest
│
▼
LOCALSTACK_AUTH_TOKEN exported?
│
NO ─────┴───── YES
│ │
▼ ▼
Exit code 55 Container starts
(this sandbox, │
confirmed ▼
above) awslocal bedrock list-foundation-models
│
▼
Ultimate plan active?
│
NO ─────┴───── YES
│ │
▼ ▼
"not included Real response
in your current from Bedrock's
license plan" control plane -- but
(Hobby, even STILL without real
with registered inference invoked
token) (see note below)
One final note, even for the diagram's most favorable branch. Even if someone had access to LocalStack's Ultimate plan, list-foundation-models is a control plane operation — it returns metadata about which models exist, it doesn't invoke any of them. Not even in this diagram's most favorable scenario would this command produce a real inference response. And a real invocation, even against LocalStack Ultimate, would never run AWS's actual Bedrock model — LocalStack Ultimate runs a local Ollama model as a substitute: real inference, but of a different model than the one you'd use in production —, and against real AWS, every token of every invocation costs real money. It is, as lesson 1 declared, the only guide in the ecosystem where no $0 path — not even LocalStack's highest paid plan — produces a real response from the system it teaches you to operate.
Common mistakes
Thinking Step 1's error (exit code 55) is the same problem as Step 2's error (Ultimate plan) (reading mistake, the same one lesson 5 already anticipated). What happens: someone reads this lesson and concludes "LocalStack doesn't work in this environment" as a single cause. How to spot it: if you can't explain, without looking back, why resolving Step 1 (exporting a token) doesn't resolve Step 2. How to fix it: these are two completely independent limits. Step 1 is exclusive to this writing environment — anyone with a free Hobby token resolves it. Step 2 persists even with that token, because Bedrock specifically requires the paid Ultimate plan, not Hobby or Base.
Concluding this lesson proves LocalStack "is bad" for learning AWS (scope mistake, the same scale error you already saw in cloud-security-and-guardrails-guide M2.6). What happens: someone, after two consecutive obstacles, starts distrusting LocalStack as a tool for the whole ecosystem. How to spot it: if your reaction is "so nothing before this ran for real either." How to fix it: the previous seven guides in this ecosystem, and lesson 5 of this same module, ran dozens of real commands against services that are indeed in the free Hobby plan. Bedrock is, deliberately, the only service in this entire ecosystem that requires the highest paid plan — a LocalStack product decision about what functionality to reserve for paying customers, not a flaw in the tool.
Expecting this guide's M3 (Infrastructure as Code) to solve this same problem with Terraform (forward-looking expectation mistake). What happens: someone assumes that, if Terraform can validate/plan a Bedrock resource without LocalStack or an AWS account (as M3 is going to show), then this lesson should have been able to do the same with awslocal. How to spot it: if your question is "why can Terraform do it but awslocal can't?" How to fix it: these are fundamentally different operations. terraform plan on a resource that doesn't exist yet in the state never needs to read from any real API — it builds the diff purely from the declared HCL. awslocal bedrock list-foundation-models is the opposite: a call that does need a real API, running, responding — exactly what neither this environment (Step 1) nor the Hobby plan (Step 2) can offer.
Exercises
Exercise 1 — Explain, in your own words, why Step 1's message doesn't mention Bedrock. A colleague asks why, if this lesson's problem is "Bedrock isn't available," the first error doesn't even name that service. Explain the real sequence to them.
See solution
Because the LocalStack container first checks whether it has a valid license — or, in the free plan's case, whether there are at least credentials from a registered account — before exposing any service, whether Bedrock, EventBridge, or IAM. The license check is a gate that comes before any specific service: if the container can't confirm it's authorized to start at all, it never reaches the point of deciding which services are or aren't included in the active plan. Step 2's message — specific to Bedrock, about the Ultimate plan — would only appear if the container managed to start first.
Exercise 2 — Predict what would happen if this lesson were run with a real LocalStack Ultimate token. Without inventing a model response, describe what you'd expect to see, step by step, if someone with a paid LocalStack Ultimate subscription ran exactly this lesson's same two commands.
See solution
Step 1 would start without the license error — the container would start normally, exposing the endpoint on port 4566, with Bedrock included among the available services. Step 2, awslocal bedrock list-foundation-models, would respond with a real list of models emulated by LocalStack Ultimate for the control plane — which models "exist" in that simulated account —, with no plan error. What would not change, not even with Ultimate: any later attempt to invoke one of those models (bedrock-runtime invoke-model) would still not produce a response from AWS's actual Bedrock model — LocalStack Ultimate does run real inference, but against a local Ollama model, not against Bedrock's model nor identical to production —, the same underlying limitation this lesson already named in its final note.
Exercise 3 — Compare this lesson with cloud-security-and-guardrails-guide M2.6. Both lessons are called "the honest attempt" or equivalent, and both end in a representative result. What do their two conclusions have in common, and how do they differ?
See solution
What they have in common: both identify a real, documented LocalStack limit — not a guide error —, cite the exact official source at the moment the limit appears, and precisely distinguish what WAS actually built and verified for real (in that lesson, the identity provider and trust policy declared and applied; in this one, the inherited infrastructure from lesson 5) from what stays representative. The difference: cloud-security-and-guardrails-guide M2.6's limit is about enforcement — the API exists and can be invoked, but the engine that would verify a JWT's signature is paid. This lesson's limit is earlier and harder: Bedrock's API isn't even available to invoke on the free plan, regardless of whether the presented token is valid or not.
Summary and next step
In this lesson you tried, for real, to touch Bedrock from this $0 lab, and documented two independent obstacles: first, that this specific writing environment has no LocalStack token exported — the same limit you already saw in lesson 5, confirmed live with this session's real exit code 55 —; second, and more importantly, that not even a registered Hobby token would resolve the problem, because Bedrock is explicitly documented as "Included in Plans: Ultimate" — one step above what any free LocalStack plan offers. You confirmed, with the exact source cited, this guide's complete honesty commitment: no $0 path, at any point, produces a real model invocation.
Before moving on you should be able to: explain the difference between this lesson's two obstacles, without conflating them; cite, from memory or close to it, LocalStack documentation's exact phrase about Bedrock; and explain why not even the Ultimate plan would completely solve the problem, given what this lesson's final note explains about the nature of the emulation.
Lesson 8 — the project that closes this module — turns everything you learned across the previous seven lessons into a real document: a short ADR that fixes, in writing, this guide's architecture decision, the inherited inventory, and the map of the seven modules that follow.
Resources
- LocalStack Docs — Bedrock — this lesson's exact source: "Included in Plans: Ultimate", no Hobby or Base.
- LocalStack — Pricing — a complete comparison of plans and services included in each.
cloud-security-and-guardrails-guide, Module 2, lesson 6 (06-hands-on-what-localstack-does-and-does-not-validate.md) — the same "honest attempt" pattern applied to a different domain (OIDC/IAM Policy Enforcement).- AWS CLI —
bedrock list-foundation-models— official reference for this lesson's command, against real AWS. - Docker Docs —
docker run— reference for the command used in this lesson's Step 1.