<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Luis Fernando de León Ramírez</title>
    <description>The latest articles on DEV Community by Luis Fernando de León Ramírez (@luisferdeleon).</description>
    <link>https://dev.to/luisferdeleon</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3806746%2Fdd120c9b-aa38-43c9-a4a1-fefab68a061e.jpg</url>
      <title>DEV Community: Luis Fernando de León Ramírez</title>
      <link>https://dev.to/luisferdeleon</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/luisferdeleon"/>
    <language>en</language>
    <item>
      <title>¿Y si construir un chatbot con IA fuera tan fácil como armar con LEGO? — AWS Blocks"</title>
      <dc:creator>Luis Fernando de León Ramírez</dc:creator>
      <pubDate>Sat, 04 Jul 2026 05:02:56 +0000</pubDate>
      <link>https://dev.to/aws-builders/y-si-construir-un-chatbot-con-ia-fuera-tan-facil-como-armar-con-lego-aws-blocks-1kb3</link>
      <guid>https://dev.to/aws-builders/y-si-construir-un-chatbot-con-ia-fuera-tan-facil-como-armar-con-lego-aws-blocks-1kb3</guid>
      <description>&lt;h2&gt;
  
  
  1. ¿Qué es Blocks?
&lt;/h2&gt;

&lt;p&gt;Es un marco de trabajo de código abierto lanzado recientemente que facilita la implementación de proyectos en AWS; tú solamente te encargarás de desarrollar tu proyecto como lo haces normalmente en TypeScript. El marco de trabajo se encargará de convertir tu código en servicios de AWS.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Beneficios
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Desarrollo sin necesidad de una cuenta de AWS.&lt;/li&gt;
&lt;li&gt;Puedes probar tu código en local y tendrás la certeza de que el funcionamiento será igual en producción.&lt;/li&gt;
&lt;li&gt;Orientado a costo bajo utilizando la tecnología serverless.&lt;/li&gt;
&lt;li&gt;Experiencia de desarrollo con IA al incluir guías que permiten hacer uso de herramientas de IA para codificación, como Kiro, ya que el framework orienta al agente sobre cómo mejorar tus arquitecturas.&lt;/li&gt;
&lt;li&gt;Tendrás un ambiente de desarrollo aislado y totalmente funcional.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  3. ¿Qué es un Block?
&lt;/h2&gt;

&lt;p&gt;Un Block es una pieza de funcionalidad que encapsula lógica + infraestructura AWS en una sola abstracción que usas con una a tres líneas de código.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Analogía:&lt;/strong&gt;&lt;br&gt;
Piensa en un Block como un módulo de LEGO: cada pieza tiene una forma y función específica, y las combinas para construir lo que quieras. No te preocupas de cómo está hecha internamente.&lt;/p&gt;
&lt;h2&gt;
  
  
  4. ¿Qué Blocks puedo utilizar?
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Datos y almacenamiento&lt;/li&gt;
&lt;li&gt;Autenticación&lt;/li&gt;
&lt;li&gt;Cómputo y trabajos en segundo plano&lt;/li&gt;
&lt;li&gt;Inteligencia artificial&lt;/li&gt;
&lt;li&gt;Comunicación&lt;/li&gt;
&lt;li&gt;Configuración&lt;/li&gt;
&lt;li&gt;Observabilidad&lt;/li&gt;
&lt;li&gt;Alojamiento y despliegue&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  5. ¿Cómo inicio con mi proyecto?
&lt;/h2&gt;

&lt;p&gt;Con un comando de npm podemos crear la estructura principal del proyecto. Para entender cómo funciona todo desde cero, creé un repositorio que cuenta con una plantilla en blanco la cual puedes utilizar para crear tu proyecto. Ejecuta lo siguiente:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx @luisfdeleonramirez/create-aws-blocks-base chatbot-ia
&lt;span class="nb"&gt;cd &lt;/span&gt;chatbot-ia
npm &lt;span class="nb"&gt;install
&lt;/span&gt;npm run dev
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Al ejecutar estos comandos tendremos un servicio local corriendo en &lt;a href="http://localhost:3000" rel="noopener noreferrer"&gt;http://localhost:3000&lt;/a&gt; donde podrás realizar tus pruebas.&lt;/p&gt;

&lt;h2&gt;
  
  
  6. ¿Qué vamos a construir?
&lt;/h2&gt;

&lt;p&gt;Desarrollé una app que funciona como un agente que usa Amazon Nova Lite (amazon.nova-lite-v1:0) y responde consultas de los usuarios. Luego de varias pruebas, considero que un flujo adecuado para organizar el desarrollo es el siguiente:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;"Primero defino qué hace mi app (index.ts)"&lt;/li&gt;
&lt;li&gt;"Luego defino dónde corre (index.cdk.ts)"&lt;/li&gt;
&lt;li&gt;"Finalmente defino cómo se ve para el usuario (app.tsx)"&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  7. ¿Qué Blocks utilicé?
&lt;/h2&gt;

&lt;p&gt;Originalmente pensé que utilizaría los bloques únicamente del lado del backend, pero en la interfaz web terminé utilizando funciones propias de Blocks para el manejo de conversaciones.&lt;/p&gt;

&lt;h3&gt;
  
  
  Scope
&lt;/h3&gt;

&lt;p&gt;Para la agrupación de recursos.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;scope&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Scope&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;chatbot&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  AuthBasic
&lt;/h3&gt;

&lt;p&gt;Para la configuración de autenticación utilizando correo y contraseña.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;auth&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;AuthBasic&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;scope&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;auth&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Agent
&lt;/h3&gt;

&lt;p&gt;Bloque para el agente de IA con Bedrock, que incluye configuración, streaming y tools. Algo sumamente interesante es que solamente en un par de líneas puedes configurar el comportamiento de tu agente para su interacción.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;agent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Agent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;scope&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;chat&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;model&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;deployed&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;provider&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;bedrock&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;modelId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;amazon.nova-lite-v1:0&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="na"&gt;systemPrompt&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`Eres un agente amigable que se encargará de solucionar dudas a los usuarios sobre tecnología.
Debes responderles en el mismo idioma que te hagan las preguntas.
Cuando el usuario pregunte sobre la empresa, productos, precios o información específica, 
usa la herramienta searchKnowledge para buscar en la base de conocimiento antes de responder.
Si no encuentras información relevante en la base de conocimiento, responde con tu conocimiento general.`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;tools&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;tool&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;searchKnowledge&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;tool&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
      &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Busca información relevante en la base de conocimiento de la empresa. Usa esta herramienta cuando el usuario pregunte sobre productos, precios, servicios o información específica de la empresa.&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;parameters&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;z&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;object&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
        &lt;span class="na"&gt;query&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;z&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;string&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;describe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Consulta de búsqueda en lenguaje natural&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
      &lt;span class="p"&gt;}),&lt;/span&gt;
      &lt;span class="na"&gt;handler&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;input&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;results&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;kb&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;retrieve&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;query&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;maxResults&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
        &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;results&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;No se encontró información relevante en la base de conocimiento.&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;results&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;r&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;r&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;text&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="se"&gt;\n\n&lt;/span&gt;&lt;span class="s1"&gt;---&lt;/span&gt;&lt;span class="se"&gt;\n\n&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;}),&lt;/span&gt;
  &lt;span class="p"&gt;}),&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  KnowledgeBase
&lt;/h3&gt;

&lt;p&gt;Base de conocimiento RAG con documentos propios que el agente usará para responder.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;kb&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;KnowledgeBase&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;scope&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;docs&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;source&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./knowledge&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;'Documentación y base de conocimiento del chatbot',&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  ApiNamespace
&lt;/h3&gt;

&lt;p&gt;Para la comunicación de la API mediante JSON-RPC.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;api&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;ApiNamespace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;scope&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;api&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;context&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;({}));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  8. Desarrollo
&lt;/h2&gt;

&lt;p&gt;Luego de ajustar el código para que fuera funcional, quise probar si funcionaba totalmente en local y la respuesta es que sí: tenía un funcionamiento básico que podía simular usando datos mock en el código. Sin embargo, la funcionalidad del agente sí requiere que al menos hagamos la prueba en el sandbox. Teniendo algo listo, pasé al sandbox.&lt;/p&gt;

&lt;h2&gt;
  
  
  9. Configuración de IAM
&lt;/h2&gt;

&lt;p&gt;Para poder realizar esto bajo el principio del privilegio mínimo, hice pruebas con los permisos mínimos que debería tener el usuario que ejecutará los deploys. Te dejo a continuación la política:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"Version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2012-10-17"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"Statement"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"Sid"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"AWSBlocksCloudFormationAndIAM"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"Effect"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Allow"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"Action"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="s2"&gt;"cloudformation:*"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="s2"&gt;"iam:CreateRole"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="s2"&gt;"iam:DeleteRole"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="s2"&gt;"iam:GetRole"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="s2"&gt;"iam:GetRolePolicy"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="s2"&gt;"iam:ListRolePolicies"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="s2"&gt;"iam:ListAttachedRolePolicies"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="s2"&gt;"iam:PassRole"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="s2"&gt;"iam:AttachRolePolicy"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="s2"&gt;"iam:DetachRolePolicy"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="s2"&gt;"iam:PutRolePolicy"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="s2"&gt;"iam:DeleteRolePolicy"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="s2"&gt;"iam:TagRole"&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"Resource"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"*"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"Sid"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"AWSBlocksAllPossibleFrameworkServices"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"Effect"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Allow"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"Action"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="s2"&gt;"lambda:*"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="s2"&gt;"dynamodb:*"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="s2"&gt;"apigateway:*"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="s2"&gt;"s3:*"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="s2"&gt;"bedrock:*"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="s2"&gt;"events:*"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="s2"&gt;"sqs:*"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="s2"&gt;"ecr:*"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="s2"&gt;"ssm:*"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="s2"&gt;"sts:AssumeRole"&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"Resource"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"*"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  10. Bootstrap
&lt;/h2&gt;

&lt;p&gt;Inicié con la prueba de sandbox, sin embargo, para esto necesitaba tener el bootstrap listo. El bootstrap es una preparación base para que las aplicaciones de Blocks puedan funcionar correctamente. Esta preparación se realiza una sola vez por cuenta y región. La realizas de esta forma:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx cdk bootstrap aws://&lt;span class="o"&gt;{&lt;/span&gt;id_de_tu_cuenta&lt;span class="o"&gt;}&lt;/span&gt;/&lt;span class="o"&gt;{&lt;/span&gt;region&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;El resultado de esta ejecución es la creación de un CloudFormation y la pregunta más grande: ¿esto genera costos? La respuesta es no, únicamente crea un bucket de S3 vacío, los roles en IAM y un parámetro en SSM. El costo se genera cuando el CDK sube los assets del código estático durante los deploys. Toma en cuenta que para el sandbox el CDK no copia estos archivos, ya que la interfaz sigue corriendo en tu ambiente.&lt;/p&gt;

&lt;h2&gt;
  
  
  11. Sandbox
&lt;/h2&gt;

&lt;p&gt;Durante la creación del sandbox, encontré diversos retos. Al ser una nueva tecnología, es posible encontrar detalles que puedan generar un funcionamiento inesperado. Puedes iniciar el sandbox ejecutando:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm run sandbox
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Opté por probar el sandbox en la región de us-west-2. La experiencia fue buena y fortalecí mis conocimientos sobre el framework. Te dejo algunos consejos:&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Crea tags en tu proyecto
&lt;/h3&gt;

&lt;p&gt;Para tener control sobre tus recursos, así como el monitoreo de tus costos.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;index.cdk.ts:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;cdk&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;aws-cdk-lib&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nx"&gt;cdk&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Tags&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;of&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;blocksStack&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Project&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;blocks-chatbot-ia&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;cdk&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Tags&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;of&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;blocksStack&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Environment&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;sandboxMode&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;sandbox&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;production&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;cdk&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Tags&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;of&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;blocksStack&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Team&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;dev&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;cdk&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Tags&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;of&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;blocksStack&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;CostCenter&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;chatbot-ia&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2. Nombres de stack cortos
&lt;/h3&gt;

&lt;p&gt;En ocasiones los recursos no podrán crearse si el nombre de tu proyecto es muy largo, por lo cual puedes cambiar el nombre base de tu stack, ya que los recursos se crean con este prefijo. Para este caso hice cambios para que el stack fuera el nombre del proyecto definido en el package:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;index.cdk.ts:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;stackName&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;sandboxMode&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="nx"&gt;pkg&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s2"&gt;`-sandbox`&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;pkg&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;prod&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;blocksStack&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;BlocksStack&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;stackName&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;backendHandlerPath&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;__dirname&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;index.handler.ts&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
  &lt;span class="na"&gt;backendCDKPath&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;__dirname&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;index.ts&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  3. Cuotas de Bedrock en Organizations
&lt;/h3&gt;

&lt;p&gt;Si tu cuenta forma parte de una organización, recuerda que debes establecer las cuotas en los modelos de Bedrock, de lo contrario no podrás verificar la respuesta de los modelos.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Bug de región en @strands-agents/sdk
&lt;/h3&gt;

&lt;p&gt;El bloque @aws-blocks/bb-agent usa internamente el módulo @strands-agents/sdk en su última versión disponible hasta la fecha de la prueba (1.7.0), para guardar las conversaciones del agente en S3. Sin embargo, este módulo por defecto apunta a la región us-east-1, por lo que al intentar hacer uso del agente en otra región podrías tener problemas. Para eso únicamente debes hacer el siguiente cambio:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;node_modules/@strands-agents/sdk/dist/src/session/s3-storage.js:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;_s3&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;s3Client&lt;/span&gt; &lt;span class="o"&gt;??&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;S3Client&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;region&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;region&lt;/span&gt; &lt;span class="o"&gt;??&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;AWS_REGION&lt;/span&gt; &lt;span class="o"&gt;??&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;us-east-1&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Con este cambio, por defecto ahora revisará la variable de ambiente de la región para que puedas ver el histórico de tus conversaciones. Esta solución es para esa versión. Hice el reporte #120 al equipo de mantenimiento del framework de AWS Blocks y fue resuelto, así que ya es poco probable que encuentres ese error. Te dejo detalles de la corrección que aplicaron:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/aws-devtools-labs/aws-blocks/issues/120" rel="noopener noreferrer"&gt;https://github.com/aws-devtools-labs/aws-blocks/issues/120&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Al finalizar las pruebas del sandbox, pude ver un CloudFormation con los diversos recursos creados. En este caso es posible darles un mejor seguimiento gracias a los tags, que identifican a qué proyecto pertenece cada recurso.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fb1h4xpctopwehkg27shg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fb1h4xpctopwehkg27shg.png" alt=" " width="800" height="347"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  12. Despliegue
&lt;/h2&gt;

&lt;p&gt;Al haber realizado las pruebas en el sandbox, solamente queda hacer el deploy para que la aplicación sea accesible para todo el mundo. Es una experiencia satisfactoria, ya que este framework permite llevar a producción aplicaciones estables y seguras utilizando arquitecturas serverless. Para este paso, la diferencia con el sandbox es que se genera el hosting estático almacenado en S3 y distribuido por CloudFront. El tiempo de despliegue fue de 12 minutos.&lt;/p&gt;

&lt;p&gt;A continuación podemos ver el funcionamiento del chatbot en ambiente productivo.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F1xsp6awp783udutyrvh9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F1xsp6awp783udutyrvh9.png" alt=" " width="451" height="764"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  13. Limpieza de recursos
&lt;/h2&gt;

&lt;p&gt;Posterior a las pruebas y para no incurrir en gastos, destruí la infraestructura creada. Esto es tan sencillo como ejecutar los siguientes comandos:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Borrar Sandbox:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm run sandbox:destroy
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Borrar despliegue:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm run destroy
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Borrar el CDK&lt;/strong&gt; (tomar en cuenta que no genera gasto mientras no se transfieran assets):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;aws s3 &lt;span class="nb"&gt;rm &lt;/span&gt;s3://cdk-hnb659fds-assets-xxxxx-&lt;span class="o"&gt;{&lt;/span&gt;region&lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="nt"&gt;--recursive&lt;/span&gt; &lt;span class="nt"&gt;--region&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;region&lt;span class="o"&gt;}&lt;/span&gt;
aws cloudformation delete-stack &lt;span class="nt"&gt;--stack-name&lt;/span&gt; CDKToolkit &lt;span class="nt"&gt;--region&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;region&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  Sobre el autor
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Luis Fernando de León&lt;/strong&gt; — AWS Community Builder 🇬🇹&lt;/p&gt;

&lt;p&gt;📸 Instagram: instagram.com/luisenlanube&lt;br&gt;
📝 DEV: dev.to/luisferdeleon&lt;br&gt;
👤 Facebook: facebook.com/luisenlanube&lt;br&gt;
💼 LinkedIn: linkedin.com/in/luisfdeleonramirez&lt;/p&gt;

</description>
      <category>aws</category>
      <category>awscdk</category>
      <category>awscommunity</category>
      <category>serverless</category>
    </item>
    <item>
      <title>What if building an AI chatbot was as easy as snapping LEGO bricks together? — AWS Blocks</title>
      <dc:creator>Luis Fernando de León Ramírez</dc:creator>
      <pubDate>Fri, 03 Jul 2026 02:38:38 +0000</pubDate>
      <link>https://dev.to/aws-builders/what-if-building-an-ai-chatbot-was-as-easy-as-snapping-lego-bricks-together-aws-blocks-3lhm</link>
      <guid>https://dev.to/aws-builders/what-if-building-an-ai-chatbot-was-as-easy-as-snapping-lego-bricks-together-aws-blocks-3lhm</guid>
      <description>&lt;h2&gt;
  
  
  1. What is Blocks?
&lt;/h2&gt;

&lt;p&gt;It is a recently launched open-source framework that simplifies deploying projects to AWS; you only need to develop your project as you normally do in TypeScript. The framework takes care of converting your code into AWS services.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Benefits
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Development without needing an AWS account.&lt;/li&gt;
&lt;li&gt;You can test your code locally with the certainty that it will work the same in production.&lt;/li&gt;
&lt;li&gt;Low-cost oriented using serverless technology.&lt;/li&gt;
&lt;li&gt;AI-powered development experience by including guides that enable the use of AI coding tools, such as Kiro, since the framework guides the agent on how to improve your architectures.&lt;/li&gt;
&lt;li&gt;You will have an isolated and fully functional development environment.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  3. What is a Block?
&lt;/h2&gt;

&lt;p&gt;A Block is a piece of functionality that encapsulates logic + AWS infrastructure in a single abstraction that you use with one to three lines of code.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Analogy:&lt;/strong&gt;&lt;br&gt;
Think of a Block as a LEGO module: each piece has a specific shape and function, and you combine them to build whatever you want. You don't worry about how it's made internally.&lt;/p&gt;
&lt;h2&gt;
  
  
  4. What Blocks can I use?
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Data and storage&lt;/li&gt;
&lt;li&gt;Authentication&lt;/li&gt;
&lt;li&gt;Compute and background jobs&lt;/li&gt;
&lt;li&gt;Artificial intelligence&lt;/li&gt;
&lt;li&gt;Communication&lt;/li&gt;
&lt;li&gt;Configuration&lt;/li&gt;
&lt;li&gt;Observability&lt;/li&gt;
&lt;li&gt;Hosting and deployment&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  5. How do I start my project?
&lt;/h2&gt;

&lt;p&gt;With a single npm command we can create the main project structure. To understand how everything works from scratch, I created a repository with a blank template that you can use to create your project. Run the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx @luisfdeleonramirez/create-aws-blocks-base chatbot-ia
&lt;span class="nb"&gt;cd &lt;/span&gt;chatbot-ia
npm &lt;span class="nb"&gt;install
&lt;/span&gt;npm run dev
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After running these commands, we will have a local service running at &lt;a href="http://localhost:3000" rel="noopener noreferrer"&gt;http://localhost:3000&lt;/a&gt; where you can run your tests.&lt;/p&gt;

&lt;h2&gt;
  
  
  6. What are we going to build?
&lt;/h2&gt;

&lt;p&gt;I developed an app that works as an agent using Amazon Nova Lite (amazon.nova-lite-v1:0) and responds to user queries. After several tests, I consider that an adequate flow to organize development is the following:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;"First I define what my app does (index.ts)"&lt;/li&gt;
&lt;li&gt;"Then I define where it runs (index.cdk.ts)"&lt;/li&gt;
&lt;li&gt;"Finally I define how it looks for the user (app.tsx)"&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  7. What Blocks did I use?
&lt;/h2&gt;

&lt;p&gt;Originally I thought I would only use blocks on the backend side, but on the web interface I ended up using Blocks' own functions for conversation management.&lt;/p&gt;

&lt;h3&gt;
  
  
  Scope
&lt;/h3&gt;

&lt;p&gt;For resource grouping.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;scope&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Scope&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;chatbot&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  AuthBasic
&lt;/h3&gt;

&lt;p&gt;For authentication configuration using email and password.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;auth&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;AuthBasic&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;scope&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;auth&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Agent
&lt;/h3&gt;

&lt;p&gt;Block for the AI agent with Bedrock, which includes configuration, streaming, and tools. Something really interesting is that in just a couple of lines you can configure your agent's behavior for its interactions.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;agent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Agent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;scope&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;chat&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;model&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;deployed&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;provider&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;bedrock&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;modelId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;amazon.nova-lite-v1:0&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="na"&gt;systemPrompt&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`You are a friendly agent that will help users solve their questions about technology.
You must respond in the same language the user asks the question.
When the user asks about the company, products, prices or specific information,
use the searchKnowledge tool to search the knowledge base before responding.
If you don't find relevant information in the knowledge base, respond with your general knowledge.`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;tools&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;tool&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;searchKnowledge&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;tool&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
      &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Searches for relevant information in the company knowledge base. Use this tool when the user asks about products, prices, services or specific company information.&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;parameters&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;z&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;object&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
        &lt;span class="na"&gt;query&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;z&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;string&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;describe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Search query in natural language&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
      &lt;span class="p"&gt;}),&lt;/span&gt;
      &lt;span class="na"&gt;handler&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;input&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;results&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;kb&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;retrieve&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;query&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;maxResults&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
        &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;results&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;No relevant information found in the knowledge base.&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;results&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;r&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;r&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;text&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="se"&gt;\n\n&lt;/span&gt;&lt;span class="s1"&gt;---&lt;/span&gt;&lt;span class="se"&gt;\n\n&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;}),&lt;/span&gt;
  &lt;span class="p"&gt;}),&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  KnowledgeBase
&lt;/h3&gt;

&lt;p&gt;RAG knowledge base with custom documents that the agent will use to respond.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;kb&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;KnowledgeBase&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;scope&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;docs&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;source&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./knowledge&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;'Documentation and chatbot knowledge base',&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  ApiNamespace
&lt;/h3&gt;

&lt;p&gt;For API communication via JSON-RPC.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;api&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;ApiNamespace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;scope&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;api&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;context&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;({}));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  8. Development
&lt;/h2&gt;

&lt;p&gt;After adjusting the code to make it functional, I wanted to test if it worked entirely locally and the answer is yes: it had basic functionality that I could simulate using mock data in the code. However, the agent functionality does require that we at least run the test in the sandbox. Having something ready, I moved on to the sandbox.&lt;/p&gt;

&lt;h2&gt;
  
  
  9. IAM Configuration
&lt;/h2&gt;

&lt;p&gt;To accomplish this under the principle of least privilege, I tested with the minimum permissions that the user running the deploys should have. Here is the policy:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"Version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2012-10-17"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"Statement"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"Sid"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"AWSBlocksCloudFormationAndIAM"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"Effect"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Allow"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"Action"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="s2"&gt;"cloudformation:*"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="s2"&gt;"iam:CreateRole"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="s2"&gt;"iam:DeleteRole"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="s2"&gt;"iam:GetRole"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="s2"&gt;"iam:GetRolePolicy"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="s2"&gt;"iam:ListRolePolicies"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="s2"&gt;"iam:ListAttachedRolePolicies"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="s2"&gt;"iam:PassRole"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="s2"&gt;"iam:AttachRolePolicy"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="s2"&gt;"iam:DetachRolePolicy"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="s2"&gt;"iam:PutRolePolicy"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="s2"&gt;"iam:DeleteRolePolicy"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="s2"&gt;"iam:TagRole"&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"Resource"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"*"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"Sid"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"AWSBlocksAllPossibleFrameworkServices"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"Effect"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Allow"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"Action"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="s2"&gt;"lambda:*"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="s2"&gt;"dynamodb:*"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="s2"&gt;"apigateway:*"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="s2"&gt;"s3:*"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="s2"&gt;"bedrock:*"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="s2"&gt;"events:*"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="s2"&gt;"sqs:*"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="s2"&gt;"ecr:*"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="s2"&gt;"ssm:*"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="s2"&gt;"sts:AssumeRole"&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"Resource"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"*"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  10. Bootstrap
&lt;/h2&gt;

&lt;p&gt;I started with the sandbox test, however, I needed to have the bootstrap ready first. The bootstrap is a base preparation so that Blocks applications can work correctly. This preparation is done once per account and region. You do it like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx cdk bootstrap aws://&lt;span class="o"&gt;{&lt;/span&gt;your_account_id&lt;span class="o"&gt;}&lt;/span&gt;/&lt;span class="o"&gt;{&lt;/span&gt;region&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The result of this execution is the creation of a CloudFormation stack and the biggest question: does this generate costs? The answer is no, it only creates an empty S3 bucket, IAM roles, and an SSM parameter. The cost is generated when CDK uploads the static code assets during deploys. Keep in mind that for the sandbox, CDK does not copy these files since the interface keeps running in your local environment.&lt;/p&gt;

&lt;h2&gt;
  
  
  11. Sandbox
&lt;/h2&gt;

&lt;p&gt;During the sandbox creation, I encountered several challenges. Being a new technology, it is possible to find details that may cause unexpected behavior. You can start the sandbox by running:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm run sandbox
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I chose to test the sandbox in the us-west-2 region. The experience was good and I strengthened my knowledge of the framework. Here are some tips:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Create tags in your project&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;To have control over your resources, as well as cost monitoring.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;index.cdk.ts:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;cdk&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;aws-cdk-lib&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nx"&gt;cdk&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Tags&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;of&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;blocksStack&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Project&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;blocks-chatbot-ia&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;cdk&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Tags&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;of&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;blocksStack&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Environment&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;sandboxMode&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;sandbox&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;production&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;cdk&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Tags&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;of&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;blocksStack&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Team&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;dev&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;cdk&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Tags&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;of&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;blocksStack&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;CostCenter&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;chatbot-ia&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Short stack names&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Sometimes resources cannot be created if your project name is too long, so you can change the base name of your stack since resources are created with this prefix. In this case, I made changes so the stack would be the project name defined in the package:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;index.cdk.ts:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;stackName&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;sandboxMode&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="nx"&gt;pkg&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s2"&gt;`-sandbox`&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;pkg&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;prod&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;blocksStack&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;BlocksStack&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;stackName&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;backendHandlerPath&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;__dirname&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;index.handler.ts&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
  &lt;span class="na"&gt;backendCDKPath&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;__dirname&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;index.ts&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Bedrock quotas in Organizations&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If your account is part of an organization, remember that you must set the quotas for Bedrock models, otherwise you won't be able to verify the model responses.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Region bug in @strands-agents/sdk&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The @aws-blocks/bb-agent block internally uses the @strands-agents/sdk module in its latest version available at the time of testing (1.7.0), to save agent conversations in S3. However, this module by default points to the us-east-1 region, so when trying to use the agent in another region you might encounter issues. To fix this, you only need to make the following change:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;node_modules/@strands-agents/sdk/dist/src/session/s3-storage.js:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;_s3&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;s3Client&lt;/span&gt; &lt;span class="o"&gt;??&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;S3Client&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;region&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;region&lt;/span&gt; &lt;span class="o"&gt;??&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;AWS_REGION&lt;/span&gt; &lt;span class="o"&gt;??&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;us-east-1&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With this change, it will now check the region environment variable by default so you can see the history of your conversations. This fix is for that version. I filed report #120 to the AWS Blocks framework maintenance team and it was resolved, so it's unlikely you'll encounter this error anymore. Here are the details of the fix they applied:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/aws-devtools-labs/aws-blocks/issues/120" rel="noopener noreferrer"&gt;https://github.com/aws-devtools-labs/aws-blocks/issues/120&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After finishing the sandbox tests, I could see a CloudFormation with the various created resources. In this case, it is possible to better track them thanks to the tags, which identify which project each resource belongs to.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F0akeyp8l90i8tubgxvc9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F0akeyp8l90i8tubgxvc9.png" alt=" " width="800" height="347"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  12. Deployment
&lt;/h2&gt;

&lt;p&gt;Having completed the tests in the sandbox, the only thing left is to deploy so the application is accessible to everyone. It is a satisfying experience, since this framework allows you to take stable and secure applications to production using serverless architectures. For this step, the difference from the sandbox is that static hosting is generated, stored in S3 and distributed by CloudFront. The deployment time was 12 minutes.&lt;/p&gt;

&lt;p&gt;Below we can see the chatbot working in the production environment.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fxixt65har0ulhp21mssz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fxixt65har0ulhp21mssz.png" alt=" " width="451" height="764"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  13. Resource Cleanup
&lt;/h2&gt;

&lt;p&gt;After testing and to avoid incurring costs, I destroyed the created infrastructure. This is as simple as running the following commands:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Delete Sandbox:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm run sandbox:destroy
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Delete deployment:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm run destroy
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Delete CDK&lt;/strong&gt; (keep in mind that it does not generate costs as long as no assets are transferred):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;aws s3 &lt;span class="nb"&gt;rm &lt;/span&gt;s3://cdk-hnb659fds-assets-xxxxx-&lt;span class="o"&gt;{&lt;/span&gt;region&lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="nt"&gt;--recursive&lt;/span&gt; &lt;span class="nt"&gt;--region&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;region&lt;span class="o"&gt;}&lt;/span&gt;
aws cloudformation delete-stack &lt;span class="nt"&gt;--stack-name&lt;/span&gt; CDKToolkit &lt;span class="nt"&gt;--region&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;region&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  About the author
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Luis Fernando de León&lt;/strong&gt; — AWS Community Builder 🇬🇹&lt;/p&gt;

&lt;p&gt;📸 Instagram: instagram.com/luisenlanube&lt;br&gt;
📝 DEV: dev.to/luisferdeleon&lt;br&gt;
👤 Facebook: facebook.com/luisenlanube&lt;br&gt;
💼 LinkedIn: linkedin.com/in/luisfdeleonramirez&lt;/p&gt;

</description>
      <category>aws</category>
      <category>awscdk</category>
      <category>awscommunity</category>
      <category>serverless</category>
    </item>
    <item>
      <title>¿Para que sirve Kubernetes (k8s)?</title>
      <dc:creator>Luis Fernando de León Ramírez</dc:creator>
      <pubDate>Mon, 18 May 2026 03:31:32 +0000</pubDate>
      <link>https://dev.to/luisferdeleon/para-que-sirve-kubernetes-k8s-546a</link>
      <guid>https://dev.to/luisferdeleon/para-que-sirve-kubernetes-k8s-546a</guid>
      <description>&lt;p&gt;Kubernetes es una plataforma de código abierto para la orquestación de contenedores, en muchos casos es una tecnología que no tiene mucha aceptación por la complejidad que puede representar, sin embargo, en escenarios donde las arquitecturas pueden llegar a crear demasiado, puede ser un aliado estratégico para la administración de estos ambientes.&lt;br&gt;
AWS provee el servicio de EKS, el cual permite el uso de Kubernetes de forma sencilla al administrar por nosotros el plano de control, lo cual permite que podamos ir directo al despliegue de nuestras aplicaciones y para conocer más sobre este servicio estaré realizando un proyecto que pueda hacer uso de la mayor parte de sus características.&lt;/p&gt;

&lt;p&gt;¡Acompáñame durante estas semanas a ir conociendo más a fondo de este servicio!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fuw71ked5qgn3cs4tavcl.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fuw71ked5qgn3cs4tavcl.png" alt=" " width="800" height="1000"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>awscommunitybuilders</category>
      <category>kubernetes</category>
      <category>aws</category>
      <category>containers</category>
    </item>
    <item>
      <title>Application Load Balancer de EKS se desvincula de WAF</title>
      <dc:creator>Luis Fernando de León Ramírez</dc:creator>
      <pubDate>Wed, 15 Apr 2026 03:40:57 +0000</pubDate>
      <link>https://dev.to/aws-builders/application-load-balancer-de-eks-se-desvincula-de-waf-38g1</link>
      <guid>https://dev.to/aws-builders/application-load-balancer-de-eks-se-desvincula-de-waf-38g1</guid>
      <description>&lt;p&gt;La creación de recursos fuera de infraestructura como código suele darnos sorpresas, regularmente muchos dan mantenimiento a su infraestructura a través de cloudformation, sin embargo en algunos servicios es recomendable que se tome en cuenta la documentación oficial para prevenir imprevistos que puedan ponernos en aprietos.&lt;/p&gt;

&lt;p&gt;Hace unos días revisando mi infraestructura la cual se compone de varios clústeres de kubernetes, los cuales aún utilizan ingress controler para definir los paths que dirigen a los servicios publicados, dentro de estos ingress utilicé la función de que automáticamente al crearlos se generara un balanceador de aplicaciones dentro de la infraestructura de AWS, todo había ido muy bien, hasta que hice la actualización de versión de kubernetes.&lt;/p&gt;

&lt;p&gt;Todo funcionó correctamente, hice mi actualización a la versión 1.33 de Kubernetes en EKS y todo fue sencillo como siempre, inicialmente hice la actualización de mi plano de control, tratando de ser muy ordenado (En lo personal me gusta realizarlo desde el cli), de la siguiente forma.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;1. Verifiqué la versión actual del clúster: 
       aws eks describe-cluster --name eks-cluster-infraestructura --query cluster.version --output text

2. Actualicé el plano de control:
       aws eks update-cluster-version --name eks-cluster-infraestructura  --kubernetes-version 1.33 --output json

3. Actualicé los grupos de nodos:
      aws eks update-nodegroup-version --cluster-name eks-cluster-infraestructura --nodegroup-name ng-cluster-infraestructura --kubernetes-version 1.33

4. Y finalmente actualicé los complementos del clúster:
     aws eks update-addon --cluster-name eks-cluster-infraestructura  --addon-name coredns --addon-version v1.13.2-eksbuild.1 --configuration-values '{}'
     aws eks update-addon --cluster-name eks-cluster-infraestructura   --addon-name vpc-cni --addon-version v1.21.1-eksbuild.5  --configuration-values '{}'
     aws eks update-addon --cluster-name eks-cluster-infraestructura  --addon-name kube-proxy --addon-version v1.33.9-eksbuild.2   --configuration-values '{}'
     aws eks update-addon --cluster-name eks-cluster-infraestructura   --addon-name amazon-cloudwatch-observability --addon-version  v5.2.2-eksbuild.1   --configuration-values '{}'
     aws eks update-addon --cluster-name eks-cluster-infraestructura  --addon-name eks-pod-identity-agent --addon-version  v1.3.10-eksbuild.2 -  --configuration-values '{}'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Como dato adicional les recomiendo esta actualización del complemento de amazon-cloudwatch-observability, acá ya podrán integrar el uso de applications signals (APM) el cual permite un monitoreo a detalle de lo que puede estar pasando en cada carga de trabajo dentro de tu clúster de EKS.    &lt;/p&gt;

&lt;p&gt;Hasta el momento todo iba muy bien, la actualización fue exitosa, no hubo necesidad de realizar cambios adicionales, sin embargo para revisar que todo estuviera bien hice algunas pruebas y vaya sorpresa, resulta que el web ACL que tenía vinculado el balanceador del cluster, ya no tenía recursos vinculados, luego de leer a fondo la documentación pude observar que es necesario que dentro de la definición de mi recurso Ingress debo vincular el ARN del web ACL, y esto sucede porqué cuando se vincula manualmente el balanceador desde la consola de AWS esa configuración termina siendo efímera, solamente existirá mientras no hayan cambios en el clúster, el archivo yaml de tu ingress no tiene idea de que en algún momento vinculaste el balanceador a un WAF, por lo que al actualizar el clúster este toma la definición inicial del YAML del ingress y al no estar declarado el vinculo al WAF asume que no debe estar ahí.&lt;/p&gt;

&lt;p&gt;Es por eso que para que no te suceda esto, te dejaré la forma en la cual debes agregar el ARN del WAF a tu ingress.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: mi-app-web
  annotations:
    # En esta línea debes agregar el ARN de tu web ACL 
    alb.ingress.kubernetes.io/wafv2-acl-arn: arn:aws:wafv2:region:123456789012:regional/webacl/nombre-waf/a1b2c3d4...
spec:
  ingressClassName: alb
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;La propiedad en el recurso de ingress ha sido permitida desde hace varios años, sin embargo el adoptar infraestructura que no fue creada por nosotros puede generar inconvenientes como este que en muchos casos genera confusión.&lt;/p&gt;

</description>
      <category>awscommunitybuilder</category>
      <category>aws</category>
      <category>eks</category>
      <category>waf</category>
    </item>
    <item>
      <title>Billing and Cost Manager (Administración de facturación y costos)</title>
      <dc:creator>Luis Fernando de León Ramírez</dc:creator>
      <pubDate>Thu, 19 Mar 2026 05:28:43 +0000</pubDate>
      <link>https://dev.to/aws-builders/billing-and-cost-manager-administracion-de-facturacion-y-costos-5ap</link>
      <guid>https://dev.to/aws-builders/billing-and-cost-manager-administracion-de-facturacion-y-costos-5ap</guid>
      <description>&lt;p&gt;Cuando inicie a conocer sobre los servicios de AWS, me generaba miedo el no saber utilizar los créditos de la capa gratuita y tener que pagar una factura muy costosa solamente por hacer pruebas, por lo que cada vez que pensaba en crear una cuenta recordaba eso y no lo hacía, sin embargo existe un servicio dentro de la consola de AWS llamado "Gestión de facturación y costes de AWS", a través de este es posible la generación de reportes y el monitoreo constante de los costos que estamos generando en la consola, cuando descubrí el uso de esto tuve paz al saber que no tendría que pagar cuando estuviera utilizando la capa gratuita, a continuación te dejo un artículo donde te explico cómo crear estos presupuestos.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Al iniciar sesión en  tu cuenta debes ingresar al servicio de  &lt;strong&gt;"Billing and Cost Manager (Administración de facturación y costos"&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhn2x1af82in347x9rdni.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhn2x1af82in347x9rdni.png" alt="Captura de pantalla 1 - Servicio Billing" width="716" height="125"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Selecciona la opción de &lt;strong&gt;"Budgets"&lt;/strong&gt; (Presupuestos) &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Para este ejercicio crearemos un presupuesto, el cual nos permitirá saber el total gastado hasta el momento, tomando como referencia que el máximo a gastar por mes serán 50 dólares, para esto  utilizaremos la opción de plantillas simplificadas, lo cual utilizará las configuraciones recomendadas, pudiendo cambiar algunas de estas después de haber creado el presupuesto (Alertas configurables).&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fo67yzl2vvbq8w0kv5p3n.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fo67yzl2vvbq8w0kv5p3n.png" alt="Captura de pantalla 3 - Crear Presupuesto" width="800" height="509"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Al finalizar la creación del presupuesto se listarán los presupuestos disponibles en esta sección daremos clic sobre el presupuesto creado para realizar la configuración de las alertas.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fb8qihb8to4cn5dtxidia.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fb8qihb8to4cn5dtxidia.png" alt="Captura de pantalla 4 - Seleccionar Presupuesto Creado" width="797" height="106"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Al editar el presupuesto, en el paso 1 se visualizará el presupuesto creado, en esta sección se deberá indicar el periodo para el cual se asignará el presupuesto, así como el mes en el cual se iniciará la evaluación del presupuesto.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ft42qoor9vqs5lrljzaep.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ft42qoor9vqs5lrljzaep.png" alt="Captura de pantalla 5 - Editar Paso 1" width="800" height="442"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;En el paso 2 se configurarán tres alertas las cuales nos informarán cuando alguna de estas se cumpla, las condiciones serán las siguientes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Cuando el total del consumo exceda el 25%&lt;/li&gt;
&lt;li&gt;Cuando el total del consumo exceda el 50%&lt;/li&gt;
&lt;li&gt;Cuando el total del consumo exceda el 90%&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6xvhc5g1u2t0wxq6k2hm.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6xvhc5g1u2t0wxq6k2hm.png" alt="Captura de pantalla 6 - Configurar Alertas Paso 2" width="800" height="467"&gt;&lt;/a&gt; &lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fi2jli8iortux3eeivwxt.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fi2jli8iortux3eeivwxt.png" alt="Captura de pantalla 6-1 - Configurar Alertas Paso 2" width="799" height="486"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;A cada alerta podremos indicarle un máximo de 10 direcciones de correo electrónico a las cuales se notificará, con la finalidad de mantener un control sobre los recursos que podamos dejar encendidos por equivocación, y poder tomar acciones correctivas de forma manual para evitar el incremento de gastos.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;En el paso 3  se presentará un resumen de las alertas y las acciones que se tendrán cuando estas se cumplan (tomar en cuenta que el uso de acciones personalizadas podría incurrir en un gasto adicional, por lo cual con fines de prueba únicamente se establece la notificación por correo electrónico).&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxtmdxei4m7c8j5ubztsk.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxtmdxei4m7c8j5ubztsk.png" alt="Captura de pantalla 7 - Resumen Alertas Paso 3" width="800" height="480"&gt;&lt;/a&gt; &lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;En el paso 4 se generará un resumen con todas tus configuraciones realizadas en el presupuesto, al dar clic en guardar todas las configuraciones se aplicarán, de esta forma se habrá creado el presupuesto para monitorear el total consumido en tu cuenta.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdfnogzjt8r7bmvtd0hd0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdfnogzjt8r7bmvtd0hd0.png" alt="Captura de pantalla 8 - Guardar Paso 4" width="800" height="432"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;




&lt;h3&gt;
  
  
  Bonus
&lt;/h3&gt;

&lt;p&gt;Si prefieres tener un resumen de lo que recopilan las alertas podrás configurar reportes diarios que lleguen a tu correo electrónico en el cual tendrás el detalle del consumo hasta el final del día.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Ingresa a la opción &lt;strong&gt;"Budgets reports (Reportes de presupuesto)"&lt;/strong&gt; y dar clic sobre la opción de crear reporte, al visualizar la configuración inicial podrás seleccionar el presupuesto al cual deseas dar seguimiento y establecer la frecuencia del envío, para este ejercicio se seleccionará diario, para que el correo sea enviado al final del día con los datos recopilados por la alerta.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Farxhr58jc634z26icp0w.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Farxhr58jc634z26icp0w.png" alt="Captura de pantalla B1 - Reportes de Presupuesto" width="799" height="386"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Al final del día recibirás un correo en el cual tendrás el resumen de tus gastos.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffzbkwpbmnv23sil8y9ic.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffzbkwpbmnv23sil8y9ic.png" alt="Captura de pantalla B2 - Ejemplo de Correo" width="800" height="432"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;




&lt;p&gt;Recuerda que el crear presupuestos para seguimiento de costos no tendrá ningún valor en tu factura, siempre y cuando sean alertas básicas y con notificación a un máximo de 10 correos electrónicos y sin el uso de acciones correctivas de forma automática.&lt;/p&gt;

&lt;p&gt;Accede al siguiente enlace para leer la documentación oficial: &lt;a href="https://docs.aws.amazon.com/cost-management/latest/userguide/create-budget-report.html" rel="noopener noreferrer"&gt;Documentación AWS Cost Management&lt;/a&gt;&lt;/p&gt;

</description>
      <category>aws</category>
      <category>awscommunity</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Dockerfile</title>
      <dc:creator>Luis Fernando de León Ramírez</dc:creator>
      <pubDate>Tue, 10 Mar 2026 02:29:42 +0000</pubDate>
      <link>https://dev.to/aws-builders/dockerfile-3ba</link>
      <guid>https://dev.to/aws-builders/dockerfile-3ba</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fs0jtcr9gurqa6poortf0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fs0jtcr9gurqa6poortf0.png" alt=" " width="799" height="436"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;El traslado de aplicaciones entre ambientes sigue siendo un problema constante, ya que pueden utilizar diversos tipos de servidores, sistemas operativos, dependencias, etc. &lt;/p&gt;

&lt;p&gt;Pero esto tiene una solución muy sencilla, el uso de contenedores facilita el traslado de entornos de trabajo generando copias inmutables,  las cuales no pueden tener cambios posteriores a su compilación, para realizar esto se hace uso de un archivo de texto plano en el cual se establecen las condiciones para la generación del contenedor.&lt;/p&gt;

&lt;p&gt;Dockerfile, este archivo contiene una serie de instrucciones en este caso nuestro robot ensamblador, que se encarga de la construcción del contenedor siguiendo paso a paso las indicaciones proporcionadas, este proceso consiste en la creación de diversas capas que contienen los elementos que serán utilizados.&lt;/p&gt;

&lt;p&gt;Es importante conocer estas instrucciones y las acciones que pueden realizar, esto facilitará la administración de la infraestructura de las aplicaciones sin afectar el funcionamiento interno de las aplicaciones, las instrucciones más comunes son:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;FROM&lt;/strong&gt;: Define una base para la imagen, normalmente acá se hacen uso de sistemas operativos optimizados, normalmente se dividen en sistemas operativos completos y mínimos&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;RUN&lt;/strong&gt;: A través de esta instrucción ejecuta un comando sobre una capa nueva, también es posible utilizarla para le ejecución de comandos shell.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;WORKDIR&lt;/strong&gt;: Permite situarse sobre un directorio específico.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;COPY&lt;/strong&gt;:  Copia nuevos archivos a la imagen del contenedor.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;CMD&lt;/strong&gt;:  Permite que puedan ejecutarse comandos al iniciar el contenedor.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Ahora crearemos un ejemplo sencillo para que puedas interactuar con docker.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;NOTA&lt;/strong&gt;: Para este ejercicio haremos uso del Subsistema de Windows para Linux (WSL) con docker instalado.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Crearemos una carpeta en la cual desarrollaremos la creación de nuestra imagen&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Creamos un archivo sin extensión llamado Dockerfile&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Agregaremos las siguientes líneas dentro del archivo &lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Usa una imagen mínima - Alpine Linux
FROM alpine:latest

# Ejecuta un comando para identificar el progreso de la construcción
RUN echo "Construyendo mi primera imagen desde el Dockerfile..."

# Define el comando por defecto que se ejecutará al iniciar el contenedor
CMD ["echo", "¡Hola mundo desde mi primer imagen en docker!"]
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Generaremos la imagen por primera vez a través del siguiente comando:&lt;br&gt;
    &lt;code&gt;docker build -t mi-hola-mundo .&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Deberíamos ver algo similar a esta salida.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffbc8jjeegwu2q961xu77.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffbc8jjeegwu2q961xu77.png" alt=" " width="800" height="141"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Verificaremos que la imagen fue creada correctamente a través del siguiente comando:&lt;br&gt;
    &lt;code&gt;Docker images&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Deberemos ver nuestra imagen lista para ser utilizada&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnnsxf9vh3pe7j41i5ph7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnnsxf9vh3pe7j41i5ph7.png" alt=" " width="798" height="15"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Ejecutaremos la imagen, cabe mencionar que usaremos la opción --rm para que docker elimine la imagen cuando esta termine de utilizarse.&lt;br&gt;
    &lt;code&gt;docker run --rm mi-hola-mundo&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Obtendrás la siguiente salida:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;¡Hola mundo desde mi primera imagen en docker!&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Acá habrás creado tu primera imagen de Docker, esto será el inicio de muchas imágenes que crearas, las cuales podrás modificar para mejores resultados.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;¿Quieres saber más de &lt;strong&gt;docker&lt;/strong&gt;?, ingresa al siguiente enlace: &lt;a href="https://docs.docker.com/build/concepts/dockerfile/" rel="noopener noreferrer"&gt;Link&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;En la nube de AWS podrás hacer uso los contenedores que crees en diferentes servicios como ECS y EKS, te invito a que puedas conocer estos servicios &lt;br&gt;
ECS: &lt;a href="https://aws.amazon.com/es/ecs/" rel="noopener noreferrer"&gt;Link&lt;/a&gt;&lt;br&gt;
EKS: &lt;a href="https://aws.amazon.com/es/eks/" rel="noopener noreferrer"&gt;Link&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;Y recuerda que puedes obtener hasta 200 dólares en la capa gratuita de AWS para hacer tus pruebas, si quieres conocer más de esto, ingresa al siguiente enlace: &lt;a href="https://aws.amazon.com/es/free/" rel="noopener noreferrer"&gt;Link&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;#Containers #Dockerfile #AWS #AWSComunityBuilders #ECS #EKS&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>aws</category>
      <category>containers</category>
      <category>docker</category>
      <category>awscomunitybuilders</category>
    </item>
    <item>
      <title>¿Qué es un contenedor?</title>
      <dc:creator>Luis Fernando de León Ramírez</dc:creator>
      <pubDate>Thu, 05 Mar 2026 01:09:16 +0000</pubDate>
      <link>https://dev.to/luisferdeleon/que-es-un-contenedor-2498</link>
      <guid>https://dev.to/luisferdeleon/que-es-un-contenedor-2498</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fuk7zp9ztwqfsnw42bzca.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fuk7zp9ztwqfsnw42bzca.png" alt=" " width="800" height="436"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Los contenedores son elementos de transporte o cajas de almacenamiento que son utilizadas para facilitar el traslado de diversos objetos.&lt;/p&gt;

&lt;p&gt;¡Ahora imaginate hacer todo esto con software!&lt;/p&gt;

&lt;p&gt;En muchas ocasiones necesitamos trasladar software a un ambiente productivo, sin embargo las versiones de dependencias o sistemas operativos generan comportamientos distintos al trasladarlo, es por ello que en 2013 buscando solucionar este problema se lanzó una tecnología llamada Docker que buscaba empaquetar el software haciendo uso de sistemas operativos ligeros para aumentar la eficiencia de los servidores y manteniendo las versiones de dependencias utilizadas.&lt;/p&gt;

&lt;p&gt;Quieres conocer más sobre esta tecnología, puedes leer el artículo completo acá: &lt;a href="https://www.docker.com/resources/what-container/" rel="noopener noreferrer"&gt;Link&lt;/a&gt; &lt;/p&gt;

</description>
      <category>containers</category>
      <category>aws</category>
      <category>awscomunitybuilders</category>
      <category>cloudarchitecture</category>
    </item>
    <item>
      <title>💡☁️ Ciclo de operaciones en la nube</title>
      <dc:creator>Luis Fernando de León Ramírez</dc:creator>
      <pubDate>Thu, 05 Mar 2026 00:12:41 +0000</pubDate>
      <link>https://dev.to/luisferdeleon/ciclo-de-operaciones-en-la-nube-5646</link>
      <guid>https://dev.to/luisferdeleon/ciclo-de-operaciones-en-la-nube-5646</guid>
      <description>&lt;p&gt;📈La creciente incursión de la tecnología en empresas y organizaciones requiere la administración adecuada de las cargas de trabajo, para poder destacarse frente a sus competidores, es necesario fomentar la innovación y optimización de procesos, promoviendo la eficiencia en el desarrollo e implementación de software en producción.&lt;/p&gt;

&lt;p&gt;Es por ello que es importante conocer el ciclo de operaciones en la nube, el cual se desarrolla a través de las siguientes etapas:&lt;br&gt;
🚀 Despliegue.&lt;br&gt;
📊 Monitoreo.&lt;br&gt;
🔧 Mantenimiento.&lt;br&gt;
🔏 Seguridad. &lt;br&gt;
✅ Optimización.&lt;/p&gt;

&lt;p&gt;¿Quieres conocer más sobre el ciclo de operaciones en la nube?&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0p1fcedd3e77l4r9z5q1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0p1fcedd3e77l4r9z5q1.png" alt=" " width="800" height="800"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Puedes seguir el curso gratuito de AWS CloudOps Engineer en Skillbuilders, a través del siguiente enlace:&lt;br&gt;
&lt;a href="https://lnkd.in/eNf_kNtN" rel="noopener noreferrer"&gt;Link&lt;/a&gt;&lt;/p&gt;

</description>
      <category>cloudcomputing</category>
      <category>aws</category>
      <category>gt</category>
      <category>cloudoperationscycle</category>
    </item>
    <item>
      <title>AWS cloud Adoption Framework</title>
      <dc:creator>Luis Fernando de León Ramírez</dc:creator>
      <pubDate>Thu, 05 Mar 2026 00:10:18 +0000</pubDate>
      <link>https://dev.to/luisferdeleon/aws-cloud-adoption-framework-475e</link>
      <guid>https://dev.to/luisferdeleon/aws-cloud-adoption-framework-475e</guid>
      <description>&lt;p&gt;🚀☁️¿Trabajas on-premises y te preguntas como iniciar con el traslado de cargas de trabajo a la nube?&lt;/p&gt;

&lt;p&gt;Es una pregunta muy común; Para llevar a cabo una migración es necesario definir una planificación que contribuya a la transformación digital y la entrega de resultados empresariales de forma eficiente.&lt;/p&gt;

&lt;p&gt;AWS Cloud Adoption Framework (AWS CAF) provee una serie de buenas prácticas que se enfocan en proveer conocimientos que faciliten a las organizaciones una migración eficaz a la nube de AWS.&lt;/p&gt;

&lt;p&gt;El CAF se enfoca en seis perspectivas principales:&lt;br&gt;
💰 Comercial&lt;br&gt;
🙋 Personas&lt;br&gt;
⚖ Gobernanza&lt;br&gt;
💻 Plataforma&lt;br&gt;
 🔐 Seguridad&lt;br&gt;
⚒ Operaciones&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F06x1ihszn34nhsvzue2l.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F06x1ihszn34nhsvzue2l.png" alt=" " width="800" height="800"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;¿Quieres conocer más sobre AWS Cloud Adoption Framework ?&lt;/p&gt;

&lt;p&gt;Puedes leer el artículo completo acá&lt;br&gt;
&lt;a href="https://lnkd.in/eEFrieAv" rel="noopener noreferrer"&gt;Link&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;&lt;code&gt;#Cloud hashtag#AWS #gt #AWSCAF #CloudComputing #CloudArchitecture #Architecture #AWSCloudAdoptionFramework&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

</description>
    </item>
    <item>
      <title>AWS Identity and Access Managment (IAM)</title>
      <dc:creator>Luis Fernando de León Ramírez</dc:creator>
      <pubDate>Thu, 05 Mar 2026 00:01:15 +0000</pubDate>
      <link>https://dev.to/luisferdeleon/aws-identity-and-access-managment-iam-1h2g</link>
      <guid>https://dev.to/luisferdeleon/aws-identity-and-access-managment-iam-1h2g</guid>
      <description>&lt;p&gt;🔐 AWS Identity and Access Managment (IAM) fortalece el control de los recursos en AWS, al crear una cuenta se establece un usuario raíz que tendrá acceso ilimitado a todos los servicios en la cuenta.&lt;/p&gt;

&lt;p&gt;Dentro del servicio de IAM existen identidades, las cuales pueden asociarse a diversas políticas que definen acciones a realizar con los servicios, los tipos de identidades son:&lt;/p&gt;

&lt;p&gt;🙋 Usuarios&lt;br&gt;
 👨‍👩‍👦‍👦 Grupos de usuarios&lt;br&gt;
👮Roles&lt;/p&gt;

&lt;p&gt;📜 Las políticas permiten establecer a detalle los permisos que tendrán las identidades para la interacción con los servicios de AWS&lt;/p&gt;

&lt;p&gt;➡️ Si quieres conocer más sobre IAM el sitio de AWS SkillBuilder ofrece una introducción a IAM en 10 minutos, ¿Quieres verlo?&lt;br&gt;
&lt;a href="https://lnkd.in/eg9QvWHN" rel="noopener noreferrer"&gt;Link&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;➡️ Quieres saber más sobre IAM: &lt;a href="https://lnkd.in/eDffye-s" rel="noopener noreferrer"&gt;Link&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbp9yhdygwti0qe1ux1mu.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbp9yhdygwti0qe1ux1mu.png" alt=" " width="800" height="436"&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;&lt;code&gt;#Cloud #AWS #gt #SkillBuilder #IAM #CloudComputing #CloudArchitecture #Architecture&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

</description>
      <category>aws</category>
      <category>beginners</category>
      <category>security</category>
      <category>spanish</category>
    </item>
    <item>
      <title>Seguridad en AWS</title>
      <dc:creator>Luis Fernando de León Ramírez</dc:creator>
      <pubDate>Wed, 04 Mar 2026 23:58:51 +0000</pubDate>
      <link>https://dev.to/luisferdeleon/seguridad-en-aws-3jmi</link>
      <guid>https://dev.to/luisferdeleon/seguridad-en-aws-3jmi</guid>
      <description>&lt;p&gt;👮Gestión de identidad y accesos&lt;/p&gt;

&lt;p&gt;🔒AWS IAM: Este servicio permite la creación de usuarios, roles y políticas, estos fortalecen el control de accesos a los recursos siendo parte fundamental para el cumplimiento del principio de privilegio mínimo.&lt;/p&gt;

&lt;p&gt;🔑AWS SSO (identity Center): Este servicio facilita la administración de acceso a múltipes cuentas de AWS, proporcionando un inicio de sesión único para todas las cuentas y aplicaciones asignadas.&lt;/p&gt;

&lt;p&gt;👓 AWS Cognito: Gestiona la autenticación, autorización e identidad de usuarios para aplicaciones web y móviles.&lt;/p&gt;

&lt;p&gt;💻AWS Directory Service: Es una solución nativa en la nube que permite la integración de cargas de trabajos dependientes de Active Directory.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6637y94e19okmbpgjnb8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6637y94e19okmbpgjnb8.png" alt=" " width="736" height="736"&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;&lt;code&gt;#Cloud #AWS #gt #IAM #CloudComputing #CloudArchitecture hashtag#Architecture #SSO #IdentityCenter #AWSCognito #AWSDirectoryService&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

</description>
      <category>aws</category>
      <category>cloud</category>
      <category>security</category>
      <category>spanish</category>
    </item>
    <item>
      <title>Localstack</title>
      <dc:creator>Luis Fernando de León Ramírez</dc:creator>
      <pubDate>Wed, 04 Mar 2026 23:53:50 +0000</pubDate>
      <link>https://dev.to/luisferdeleon/localstack-1kbk</link>
      <guid>https://dev.to/luisferdeleon/localstack-1kbk</guid>
      <description>&lt;p&gt;💡¿Te encuentras iniciando en el mundo de AWS? &lt;/p&gt;

&lt;p&gt;😱 Muchos consideran que iniciar puede ser complicado al no contar con herramientas que permitan realizar pruebas antes de llevar a cabo  las pruebas en la capa gratuita, sin embargo actualmente existen herramientas que permiten emular diversos servicios de AWS en ambiente local, esto con la finalidad de reducir los costos en pruebas e implementar aplicaciones que se encuentren totalmente funcionales.&lt;/p&gt;

&lt;p&gt;Localstack✌️&lt;br&gt;
Es una herramientas que permite poder tener acceso a los recursos de diversas plataformas en ambiente local, teniendo control total de tu infraestructura, en la sección de AWS ofrece diversos planes los cuales ofrecen hasta 100 servicios para utilizar de forma local.&lt;/p&gt;

&lt;p&gt;En el plan básico se ofrecen hasta 30 servicios los cuales pueden ser utilizados para pruebas de los servicios.&lt;/p&gt;

&lt;p&gt;🛠 Un ejemplo rápido utilizando el método de instalación de docker compose&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Sigue estos pasos para la instalación descargando el archivo de docker-compose.yml : &lt;br&gt;
&lt;code&gt;https://docs.localstack.cloud/aws/getting-started/installation/&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Ten en cuenta que al utilizar el método de docker compose, debes indicar los servicios que utilizarás en las variables de ambiente&lt;br&gt;
&lt;code&gt;SERVICES: s3 ,sqs,dynamodb,lambda,iam,cloudwatch&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Inicia el contenedor&lt;br&gt;
        &lt;code&gt;docker compose up&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Crea un archivo denominado index.js y realiza lo que necesitas en tu función lambda&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fosrdy42fc5ephvfxvysy.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fosrdy42fc5ephvfxvysy.png" alt=" " width="769" height="179"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Compilar y generar la función para su creación&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvopowu4yz52em04b3n8p.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvopowu4yz52em04b3n8p.png" alt=" " width="473" height="144"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Probar las función creada.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frfwxfxhvvh2c94055hfa.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frfwxfxhvvh2c94055hfa.png" alt=" " width="644" height="65"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Ver la respuesta de la ejecución.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjt40hr2j1t7sc9gpo7ac.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjt40hr2j1t7sc9gpo7ac.png" alt=" " width="537" height="44"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;¿Ya habías probado esta herramienta?&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;&lt;code&gt;#Cloud #AWS #localstack #gt #CI/CD #Lambda&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

</description>
      <category>aws</category>
      <category>spanish</category>
      <category>localstack</category>
      <category>lambda</category>
    </item>
  </channel>
</rss>
