Módulo 1: Genai In Production Vs A Notebook

7. Manos a la obra: el intento honesto contra Bedrock en LocalStack

Descripción

Esta lección hace, literalmente, lo que su título promete: intenta tocar Bedrock de verdad, contra LocalStack, en este mismo entorno de escritura, y documenta el resultado real — no una simulación en prosa de lo que "probablemente" pasaría. El intento se detiene en dos puntos distintos, cada uno con su causa exacta, citada, no asumida. El primero corrió, de verdad, mientras se escribía esta lección. El segundo es la conclusión, verificada contra la documentación oficial de LocalStack, de qué pasaría un paso más adelante, incluso con el primer obstáculo resuelto. Es el mismo patrón de honestidad que ya viste, con otro dominio, en cloud-security-and-guardrails-guide M2.6 — el experimento que muestra exactamente dónde termina lo que un laboratorio $0 puede probar.

Conexión con el módulo

La lección 5 confirmó, representativamente, la infraestructura heredada. La lección 6 mapeó el catálogo de modelos. Esta lección conecta ambas: intenta usar ese catálogo contra la misma infraestructura, y documenta con precisión por qué ese intento no llega a producir una respuesta de un modelo real — la pieza central del compromiso de honestidad que la lección 1 anticipó. La lección 8, el proyecto de este módulo, convierte esta conclusión en la primera decisión formal de un ADR.


Paso 1 — El intento real: arrancar LocalStack en este entorno

El comando que un estudiante correría primero, antes de poder ejecutar cualquier comando awslocal, es arrancar el propio contenedor de LocalStack:

docker run -d -p 4566:4566 --name localstack-bedrock-test localstack/localstack:latest

Este comando corrió de verdad, en este entorno, para escribir esta lección — no es una salida inventada.

Qué esperar (literal — ejecutado en este sandbox mientras se escribía esta lección):

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.

El contenedor arranca, imprime su versión, y se apaga solo, con el código de salida 55, antes de exponer un solo endpoint. Fíjate en algo importante: este mensaje no menciona Bedrock en ningún lugar. Es el mismo límite exacto que ya viste en la lección 5 de este módulo — este entorno específico de escritura no tiene un LOCALSTACK_AUTH_TOKEN exportado, así que el contenedor nunca llega a arrancar, para ningún servicio, ni siquiera para los que sí están en el plan gratuito Hobby (EventBridge, Lambda, IAM). En tu propia máquina, con una cuenta gratuita de LocalStack y un token de Hobby registrado, este primer paso sí funciona — el contenedor arranca, y los comandos de la lección 5 corren de verdad.


Paso 2 — El segundo obstáculo, el que ni un token de Hobby resuelve

Aquí es donde esta lección deja de repetir el patrón de la lección 5 y se vuelve genuinamente distinta. Con el primer obstáculo resuelto —un token de Hobby real, exportado, el contenedor arrancando sin problema, exactamente como en la lección 5—, el siguiente comando sería:

awslocal bedrock list-foundation-models --region us-east-1

Este comando no corrió contra un LocalStack funcionando —ni en este sandbox, por el Paso 1, ni serviría de nada intentarlo con un token de Hobby, por la razón que sigue—. La conclusión de esta sección es representativa, pero construida sobre una fuente verificada, no asumida: la propia página de cobertura de Bedrock en la documentación oficial de LocalStack.

La cita exacta, verificada en docs.localstack.cloud/aws/services/bedrock/: el badge de la página declara, textualmente, "Included in Plans: Ultimate" — sin mencionar Hobby, sin mencionar Base. Es el mismo patrón de badge que cloud-security-and-guardrails-guide ya documentó para IAM Policy Enforcement ("Included in Plans: Base, Ultimate"), aquí un escalón más restrictivo: ni siquiera el plan de pago intermedio (Base) lo incluye, solo Ultimate.

Qué esperar (representativo — reconstruido contra el comportamiento documentado de LocalStack para un servicio fuera del plan activo):

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.

Este es el punto donde el compromiso de honestidad de la lección 1 se vuelve concreto: ni con un token de Hobby registrado, gratis, este comando produciría una respuesta real. No es el mismo tipo de límite que EventBridge/Lambda/IAM en la lección 5 —ahí, el límite era exclusivo de este entorno de escritura—. Aquí, el límite es del servicio mismo, documentado, y persiste incluso si resuelves el Paso 1.


Los dos obstáculos, en un solo diagrama

   EL INTENTO CONTRA BEDROCK, PASO A PASO

   docker run localstack/localstack:latest
              │
              ▼
   ¿LOCALSTACK_AUTH_TOKEN exportado?
              │
      NO ─────┴───── SÍ
      │               │
      ▼               ▼
   Exit code 55    El contenedor arranca
   (este sandbox,       │
   confirmado             ▼
   arriba)          awslocal bedrock list-foundation-models
                          │
                          ▼
                   ¿Plan Ultimate activo?
                          │
                  NO ─────┴───── SÍ
                  │               │
                  ▼               ▼
             "not included    Respuesta real
             in your current   del control plane
             license plan"     de Bedrock -- pero
             (Hobby, incluso   TODAVÍA sin invocar
             con token         inferencia real
             registrado)       (ver nota abajo)

Una nota final, incluso para la rama más favorable del diagrama. Aunque alguien tuviera acceso al plan Ultimate de LocalStack, list-foundation-models es una operación del control plane — devuelve metadata sobre qué modelos existen, no invoca ninguno. Ni siquiera en el escenario más favorable de este diagrama produciría este comando una respuesta de inferencia real. Y una invocación real, incluso contra LocalStack Ultimate, nunca ejecutaría el modelo de Bedrock de AWS —LocalStack Ultimate corre un modelo local de Ollama como sustituto: inferencia real, pero de un modelo distinto al que usarías en producción—, y contra AWS real, cada token de cada invocación cuesta dinero real. Es, como declaró la lección 1, la única guía del ecosistema donde ningún camino $0 —ni siquiera con el plan de pago más alto de LocalStack— produce una respuesta real del sistema que enseña a operar.


Errores comunes

Pensar que el error del Paso 1 (exit code 55) es el mismo problema que el error del Paso 2 (plan Ultimate) (de lectura, el mismo error que la lección 5 ya anticipó). Qué pasa: alguien lee esta lección y concluye que "LocalStack no funciona en este entorno" como una única causa. Cómo detectarlo: si no puedes explicar, sin mirar atrás, por qué resolver el Paso 1 (exportar un token) no resuelve el Paso 2. Cómo corregirlo: son dos límites completamente independientes. El Paso 1 es exclusivo de este entorno de escritura —cualquiera con un token de Hobby, gratis, lo resuelve—. El Paso 2 persiste incluso con ese token, porque Bedrock específicamente requiere el plan de pago Ultimate, no Hobby ni Base.

Concluir que esta lección prueba que LocalStack "es malo" para aprender AWS (de alcance, otra vez el mismo error de escala que ya viste en cloud-security-and-guardrails-guide M2.6). Qué pasa: alguien, después de dos obstáculos seguidos, empieza a desconfiar de LocalStack como herramienta para todo el ecosistema. Cómo detectarlo: si tu reacción es "entonces todo lo anterior tampoco corrió de verdad". Cómo corregirlo: las siete guías anteriores de este ecosistema, y la lección 5 de este mismo módulo, corrieron decenas de comandos reales contra servicios que sí están en el plan gratuito Hobby. Bedrock es, deliberadamente, el único servicio de todo este ecosistema que exige el plan de pago más alto — una decisión de producto de LocalStack sobre qué funcionalidad reservar para clientes de pago, no un defecto de la herramienta.

Esperar que el M3 de esta guía (Infraestructura como Código) resuelva este mismo problema con Terraform (de expectativa hacia adelante). Qué pasa: alguien asume que, si Terraform puede validate/plan un recurso Bedrock sin LocalStack ni cuenta AWS (como el M3 va a mostrar), entonces esta lección debería haber podido hacer lo mismo con awslocal. Cómo detectarlo: si tu pregunta es "¿por qué Terraform sí puede y awslocal no?". Cómo corregirlo: son operaciones fundamentalmente distintas. terraform plan sobre un recurso que no existe todavía en el state nunca necesita leer de ninguna API real —construye el diff solo a partir del HCL declarado—. awslocal bedrock list-foundation-models es lo opuesto: una llamada que sí necesita una API real, corriendo, respondiendo — exactamente lo que ni este entorno (Paso 1) ni el plan Hobby (Paso 2) pueden ofrecer.


Ejercicios

Ejercicio 1 — Explica, con tus propias palabras, por qué el mensaje del Paso 1 no menciona Bedrock. Un compañero pregunta por qué, si el problema de esta lección es "Bedrock no está disponible", el primer error ni siquiera nombra ese servicio. Explícale la secuencia real.

Ver solución

Porque el contenedor de LocalStack verifica primero si tiene una licencia válida —o, en el caso del plan gratuito, si al menos hay credenciales de una cuenta registrada— antes de exponer cualquier servicio, sea Bedrock, EventBridge o IAM. El chequeo de licencia es una puerta anterior a cualquier servicio específico: si el contenedor no puede confirmar que tiene autorización para arrancar en absoluto, nunca llega al punto de decidir qué servicios están o no están incluidos en el plan activo. El mensaje del Paso 2 —específico de Bedrock, sobre el plan Ultimate— solo aparecería si el contenedor lograra arrancar primero.

Ejercicio 2 — Predice qué pasaría si esta lección se corriera con un token de LocalStack Ultimate real. Sin inventar una respuesta de modelo, describe qué esperarías ver, paso a paso, si alguien con una suscripción de pago a LocalStack Ultimate corriera exactamente los mismos dos comandos de esta lección.

Ver solución

El Paso 1 arrancaría sin el error de licencia — el contenedor se iniciaría normalmente, exponiendo el endpoint en el puerto 4566, con Bedrock incluido entre los servicios disponibles. El Paso 2, awslocal bedrock list-foundation-models, respondería con una lista real de modelos emulados por LocalStack Ultimate para el control plane —qué modelos "existen" en esa cuenta simulada—, sin ningún error de plan. Lo que no cambiaría, ni con Ultimate: cualquier intento posterior de invocar uno de esos modelos (bedrock-runtime invoke-model) seguiría sin producir una respuesta del modelo real de Bedrock de AWS —LocalStack Ultimate sí ejecuta inferencia real, pero contra un modelo local de Ollama, no contra el modelo de Bedrock ni idéntico a producción—, la misma limitación de fondo que esta lección ya nombró en su nota final.

Ejercicio 3 — Compara esta lección con el M2.6 de cloud-security-and-guardrails-guide. Ambas lecciones se llaman "el intento honesto" o equivalente, y ambas terminan en un resultado representativo. ¿Qué tienen en común sus dos conclusiones, y en qué se diferencian?

Ver solución

Lo que tienen en común: ambas identifican un límite real y documentado de LocalStack —no un error de la guía—, citan la fuente oficial exacta en el momento en que el límite aparece, y distinguen con precisión qué SÍ se construyó y verificó de verdad (en esa lección, el identity provider y la trust policy declarados y aplicados; en esta, la infraestructura heredada de la lección 5) de lo que queda representativo. La diferencia: el límite de cloud-security-and-guardrails-guide M2.6 es de enforcement —la API existe y se puede invocar, pero el motor que verificaría la firma de un JWT es de pago—. El límite de esta lección es más temprano y más duro: la API de Bedrock ni siquiera está disponible para invocarse en el plan gratuito, independientemente de si el token que se presenta es válido o no.


Resumen y siguiente paso

En esta lección intentaste, de verdad, tocar Bedrock desde este laboratorio $0, y documentaste dos obstáculos independientes: primero, que este entorno específico de escritura no tiene un token de LocalStack exportado —el mismo límite que ya viste en la lección 5, confirmado en vivo con el exit code 55 real de esta sesión—; segundo, y más importante, que ni un token de Hobby registrado resolvería el problema, porque Bedrock está documentado explícitamente como "Included in Plans: Ultimate" — un escalón por encima de lo que cualquier plan gratuito de LocalStack ofrece. Confirmaste, con la fuente exacta citada, el compromiso de honestidad completo de esta guía: ningún camino $0, en ningún punto, produce una invocación real de un modelo.

Antes de avanzar deberías poder: explicar la diferencia entre los dos obstáculos de esta lección, sin confundirlos; citar, de memoria o cerca, la frase exacta de la documentación de LocalStack sobre Bedrock; y explicar por qué ni siquiera el plan Ultimate resolvería completamente el problema, dado lo que la nota final de esta lección explica sobre la naturaleza de la emulación.

La lección 8 —el proyecto que cierra este módulo— convierte todo lo que aprendiste en las siete lecciones anteriores en un documento real: un ADR corto que fija, por escrito, la decisión de arquitectura de esta guía, el inventario heredado, y el mapa de los siete módulos que siguen.

Recursos

  1. LocalStack Docs — Bedrock — la fuente exacta de esta lección: "Included in Plans: Ultimate", sin Hobby ni Base.
  2. LocalStack — Pricing — comparación completa de planes y servicios incluidos en cada uno.
  3. cloud-security-and-guardrails-guide, Módulo 2, lección 6 (06-hands-on-what-localstack-does-and-does-not-validate.md) — el mismo patrón de "intento honesto" aplicado a un dominio distinto (OIDC/IAM Policy Enforcement).
  4. AWS CLI — bedrock list-foundation-models — referencia oficial del comando de esta lección, contra AWS real.
  5. Docker Docs — docker run — referencia del comando usado en el Paso 1 de esta lección.