<?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: Laura Bolaños</title>
    <description>The latest articles on DEV Community by Laura Bolaños (@reinalau).</description>
    <link>https://dev.to/reinalau</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%2F3629379%2F49e3cfe8-aac1-4f47-b540-d042f1e6d241.jpg</url>
      <title>DEV Community: Laura Bolaños</title>
      <link>https://dev.to/reinalau</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/reinalau"/>
    <language>en</language>
    <item>
      <title>Graph en Strands: Parallel + Aggregation y Feedback Loop para construir Knowledge Graphs</title>
      <dc:creator>Laura Bolaños</dc:creator>
      <pubDate>Wed, 12 Aug 2026 15:19:12 +0000</pubDate>
      <link>https://dev.to/aws-builders/graph-en-strands-parallel-aggregation-y-feedback-loop-para-construir-knowledge-graphs-22n0</link>
      <guid>https://dev.to/aws-builders/graph-en-strands-parallel-aggregation-y-feedback-loop-para-construir-knowledge-graphs-22n0</guid>
      <description>&lt;p&gt;Siguiendo con la serie de artículos sobre la orquestación de multiagentes en Strands, le toca el turno a &lt;em&gt;Graph Multi-Agent Pattern&lt;/em&gt;, ejemplificado con la construcción de un knowledge graph en base a un input de texto (abstract), donde los nodos de un grafo determinista tienen las responsabilidades divididas para lograrlo. Se probó de dos maneras: con Gemma4 + Ollama y con la API de Gemini en su capa gratuita.&lt;/p&gt;

&lt;h2&gt;
  
  
  Introducción
&lt;/h2&gt;

&lt;p&gt;La información del presente artículo la podés seguir teniendo alguna noción sobre agentes y grafos. Pero te propongo hacer un curso de fundamentos del framework &lt;em&gt;Strands Agents&lt;/em&gt;, para que en futuros proyectos puedas dar mayor complejidad a tus agentes. La idea principal es experimentar con el patrón sin gastar en suscripciones pagas de tokens, dejando la implementación en AWS para otra instancia. &lt;/p&gt;

&lt;p&gt;✳ &lt;strong&gt;El caso de uso&lt;/strong&gt; que elegí para representar el patrón &lt;strong&gt;&lt;em&gt;Graph&lt;/em&gt;&lt;/strong&gt; es &lt;strong&gt;la Extracción de entidades/relaciones para formar un &lt;em&gt;Knowledge Graph&lt;/em&gt; con validación&lt;/strong&gt;.  Se me ocurrió hacer algo útil para la comunidad académica, un mecanismo de extracción de conocimiento que sea capaz de tomar parte de un artículo científico e ingestar lo más importante en un documento json, que pueda ser legible por humanos y sistemas. La solución es un pipeline de construcción de &lt;em&gt;knowledge graph&lt;/em&gt; a partir de un texto (ej. un abstract), usando la topología &lt;strong&gt;Parallel Processing→ with Aggregation→ Feedback Loop&lt;/strong&gt;.&lt;br&gt;
El diseño es una versión reducida de arquitecturas multi-agente real para enriquecimiento de &lt;em&gt;knowledge graph&lt;/em&gt; descritos en:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;a href="https://www.researchgate.net/publication/389031530_Revolutionizing_Knowledge_Graphs_with_Multi-Agent_Systems_AI-Powered_Construction_Enrichment_and_Applications" rel="noopener noreferrer"&gt;Revolutionizing Knowledge Graphs with Multi-Agent Systems: AI-Powered Construction, Enrichment, and Applications&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;
  
  
  Conceptos Claves
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;➡ Graph es un patrón de orquestación de agentes determinista&lt;/strong&gt; &lt;br&gt;
El desarrollador define explícitamente la topología de ejecución: qué nodos existen, en qué orden corren, y bajo qué condiciones se transita de uno a otro. Cada nodo es un agente y a diferencia de otros patrones como Swarm, donde el flujo surge de la negociación entre agentes, en Graph el flujo está fijado de antemano como un grafo dirigido (DAG o con ciclos controlados).&lt;/p&gt;

&lt;p&gt;Graph es apropiado cuando:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;La estructura de dependencias es conocida de antemano&lt;/strong&gt;: sabés qué pasos necesitan el resultado de otros antes de poder ejecutarse.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Hay paralelismo real que después converge&lt;/strong&gt;: varios agentes pueden trabajar al mismo tiempo sobre partes independientes del problema, y sus resultados se consolidan en un punto de agregación explícito.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Se necesita revisión con ciclos controlados&lt;/strong&gt;: un resultado puede requerir corrección y volver a un paso anterior (feedback loop), con límites de seguridad (&lt;code&gt;set_max_node_executions&lt;/code&gt;) que garantizan que el proceso termine.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;La trazabilidad y el control son prioritarios&lt;/strong&gt;: como cada nodo y cada transición son explícitos, es más fácil auditar, debuggear y predecir el comportamiento, es bueno en contextos con validación humana o compliance.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;➡ Conceptos genéricos de Grafos Agenticos&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;El framework propone una interfaz sencilla para la construcción de grafos, con 3 componentes base: &lt;strong&gt;GraphNode&lt;/strong&gt;, &lt;strong&gt;GraphEdge&lt;/strong&gt;, &lt;strong&gt;GraphBuilder&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;1.Los nodos representan agentes, nodos personalizados o sistemas multiagente. Ej:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;strands&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Agent&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;strands.multiagent&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;GraphBuilder&lt;/span&gt;

&lt;span class="c1"&gt;# Build the graph
&lt;/span&gt;&lt;span class="n"&gt;builder&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;GraphBuilder&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="c1"&gt;# Add nodes
&lt;/span&gt;&lt;span class="n"&gt;builder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add_node&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;agent_1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;[node_id_1]&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;builder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add_node&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;agent_2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;[node_id_2]&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;2.Las aristas definen las dependencias y el flujo de información entre los nodos. Además se puede agregar lógica condicional (no lo utilicé en el caso de uso analizado):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# Add edges (dependencies)
&lt;/span&gt;&lt;span class="n"&gt;builder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add_edge&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;[node_id_1]&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;[node_id_2]&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;3.La ejecución sigue la estructura del grafo, respeta dependencias, la salida de un nodo se convierte en la entrada de su dependiente. Y en el caso de que varios nodos tienen aristas hacia un nodo de destino, el comportamiento predeterminado para la ejecución del destino puede variar según el SDK (Python utiliza semánticas &lt;strong&gt;OR&lt;/strong&gt;: el nodo destino se dispara en cuanto &lt;strong&gt;cualquiera&lt;/strong&gt; de sus dependencias completa).&lt;br&gt;
4.Compatibilidad con patrones anidados, un grafo como nodo dentro de otro grafo.&lt;br&gt;
5.&lt;strong&gt;Remote Agents vía A2A&lt;/strong&gt;: Graph soporta agentes remotos como nodos a través de &lt;code&gt;A2AAgent&lt;/code&gt;, para arquitecturas distribuidas donde la orquestación corre localmente pero tareas especializadas se ejecutan en servicios remotos.&lt;br&gt;
6.&lt;strong&gt;Cyclic graph&lt;/strong&gt; permite que un nodo sea revisitado dentro del mismo flujo, con límites de ejecución y gestión de estado.&lt;br&gt;
7.&lt;strong&gt;Custom Node Types&lt;/strong&gt;: Graph permite extender &lt;code&gt;MultiAgentBase&lt;/code&gt; para crear nodos que ejecutan funciones Python deterministas en lugar de llamar a un LLM, útil para lógica de negocio, validaciones y pipelines de procesamiento de datos dentro del mismo grafo.&lt;br&gt;
8.&lt;strong&gt;Graphs as a Tool&lt;/strong&gt;: mediante el paquete &lt;code&gt;strands_tools&lt;/code&gt;, un agente puede recibir el &lt;code&gt;graph&lt;/code&gt; como tool y construir/ejecutar su propia topología de nodos en tiempo real, dejando que el LLM decida dinámicamente la orquestación en lugar de definirla de antemano con &lt;code&gt;GraphBuilder&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;➡ Topologías comunes&lt;/strong&gt;&lt;br&gt;
Strands documenta 4 topologías base que cubren la mayoría de casos de uso, y se pueden combinar según la complejidad del problema. &lt;strong&gt;Sequential Pipeline&lt;/strong&gt; sirve cuando cada paso depende estrictamente del anterior. &lt;strong&gt;Parallel + Aggregation&lt;/strong&gt; es ideal cuando hay trabajo independiente que puede correr simultáneamente y luego converger en un solo resultado. &lt;strong&gt;Branching Logic&lt;/strong&gt; permite que el flujo tome caminos distintos según el contenido generado en un paso previo. Y &lt;strong&gt;Feedback Loop&lt;/strong&gt; habilita ciclos de revisión con vuelta atrás, para casos donde un resultado necesita validación antes de darse por definitivo.&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%2Fmteh9ei94hn319omma04.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%2Fmteh9ei94hn319omma04.png" alt="graph_common_topologies" width="800" height="741"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;➡ Evaluaciones (Evals)&lt;/strong&gt;  Strands cuenta con una &lt;a href="https://strandsagents.com/docs/user-guide/evals-sdk/quickstart/" rel="noopener noreferrer"&gt;marco oficial&lt;/a&gt; para realizar evaluaciones de resultados simples hasta el análisis de interacciones de multiagentes complejos. &lt;br&gt;
En el caso de uso para la creación de &lt;em&gt;Knowledge Graph&lt;/em&gt;  se realizaron 6 evaluaciones (3 sin utilizar el framework). &lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Evaluación / Métrica&lt;/th&gt;
&lt;th&gt;Tipo / Origen&lt;/th&gt;
&lt;th&gt;¿Qué evalúa?&lt;/th&gt;
&lt;th&gt;Escala&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;OutputEvaluator&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;LLM-as-a-Judge (&lt;code&gt;strands-agents-evals&lt;/code&gt;)&lt;/td&gt;
&lt;td&gt;Verifica que la salida del nodo &lt;em&gt;Publisher&lt;/em&gt; sea un JSON válido (&lt;code&gt;entities&lt;/code&gt; y &lt;code&gt;relations&lt;/code&gt;) y que las relaciones estén fundamentadas fácticamente en el texto original.&lt;/td&gt;
&lt;td&gt;0 / 0.5 / 1&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;SemanticCorrectnessEvaluator&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;LLM-as-a-Judge (&lt;code&gt;strands-agents-evals&lt;/code&gt;)&lt;/td&gt;
&lt;td&gt;Compara semánticamente el &lt;em&gt;knowledge graph&lt;/em&gt; generado contra las relaciones esperadas (&lt;em&gt;ground truth&lt;/em&gt;), dando crédito parcial a triples con distinto wording pero igual significado. Implementado como un segundo &lt;code&gt;OutputEvaluator&lt;/code&gt; con rúbrica de referencia, ya que el &lt;code&gt;CorrectnessEvaluator&lt;/code&gt; oficial requiere un objeto &lt;code&gt;Session&lt;/code&gt; de Strands (incompatible con grafos multi-agente).&lt;/td&gt;
&lt;td&gt;0 / 0.5 / 1&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Exact-Match (P / R / F1)&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Métrica Determinista (&lt;code&gt;metrics.py&lt;/code&gt;)&lt;/td&gt;
&lt;td&gt;Mide la coincidencia exacta (normalizada a minúsculas/espacios) entre las triples extraídas y las triples de referencia del caso de prueba.&lt;/td&gt;
&lt;td&gt;0.0 – 1.0&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Loop Iterations Count&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Métrica de Topología (&lt;code&gt;metrics.py&lt;/code&gt;)&lt;/td&gt;
&lt;td&gt;Cuenta cuántas iteraciones de revisión ocurrieron en el &lt;em&gt;feedback loop&lt;/em&gt; entre el &lt;strong&gt;Validator&lt;/strong&gt; y el &lt;strong&gt;Aggregator&lt;/strong&gt; antes de la aprobación final.&lt;/td&gt;
&lt;td&gt;entero ≥ 0&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Bias-Flag Rate&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Métrica Determinista (&lt;code&gt;metrics.py&lt;/code&gt;)&lt;/td&gt;
&lt;td&gt;Detecta si la respuesta del nodo &lt;strong&gt;Validator&lt;/strong&gt; levantó alguna objeción o alerta de sesgo/desbalance en las relaciones o entidades analizadas.&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;true&lt;/code&gt; / &lt;code&gt;false&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Compound Entity Check&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Métrica Determinista (&lt;code&gt;metrics.py&lt;/code&gt;)&lt;/td&gt;
&lt;td&gt;Chequeo de regresión: detecta entidades compuestas (ej. "entities and relations") que deberían haberse dividido en dos nodos separados, según la regla en &lt;code&gt;extractor_agent.py&lt;/code&gt;/&lt;code&gt;aggregator_agent.py&lt;/code&gt;.&lt;/td&gt;
&lt;td&gt;lista de entidades detectadas&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Para clarificar: una  &lt;strong&gt;triple&lt;/strong&gt;  es la unidad básica de información que compone un  &lt;em&gt;&lt;em&gt;Knowledge Graph&lt;/em&gt;&lt;/em&gt;. Representa una afirmación o hecho estructurado combinando tres elementos:&lt;/p&gt;

&lt;p&gt;$$\text{(Sujeto)} \xrightarrow{\quad\text{Relación / Predicado}\quad} \text{(Objeto)}$$&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;Sujeto (&lt;em&gt;source&lt;/em&gt;)&lt;/strong&gt;: La entidad de origen (ej.  &lt;code&gt;"Laura Bolaños"&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Relación (&lt;em&gt;relation&lt;/em&gt;)&lt;/strong&gt;: El tipo de vínculo o conector (ej.  &lt;code&gt;"born_in"&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Objeto (&lt;em&gt;target&lt;/em&gt;)&lt;/strong&gt;: La entidad de destino (ej.  &lt;code&gt;"Argentina"&lt;/code&gt;).&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  Descripción de la solución
&lt;/h2&gt;

&lt;p&gt;📦 &lt;strong&gt;Repositorio GitHub:&lt;/strong&gt;  &lt;a href="https://github.com/reinalau/strands-graph" rel="noopener noreferrer"&gt;github.com/reinalau/strands-graph&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;⭐ El caso de uso combina dos topologías: &lt;strong&gt;paralelismo con agregación, seguido de un ciclo de feedback antes de publicar el resultado final&lt;/strong&gt;. Notar en la representación que Extractor es un agente que se instancia 3 veces, una única definición de agente, instanciada 3 veces (una por &lt;code&gt;chunk_number&lt;/code&gt;) dentro del loop en &lt;code&gt;builder.py&lt;/code&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F488r9eq02an0u0emeams.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%2F488r9eq02an0u0emeams.png" alt="Use Case Graph MultiAgent" width="800" height="771"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Para la prueba de concepto utilicé dos opciones locales de ejecución que me permitió analizar sus resultados, pero podes utilizar solo una:&lt;br&gt;
a. Ollama + el pequeño modelo &lt;strong&gt;gemma4:e2b-it-qat&lt;/strong&gt; (que pesa poco mas de 4gb) ejecutando en Docker:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Start the Ollama server with a persistent volume&lt;/span&gt;
docker run &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="nt"&gt;--name&lt;/span&gt; ollama &lt;span class="nt"&gt;-p&lt;/span&gt; 11434:11434 &lt;span class="nt"&gt;-v&lt;/span&gt; ollama_data:/root/.ollama ollama/ollama

&lt;span class="c"&gt;# Download the model&lt;/span&gt;
docker &lt;span class="nb"&gt;exec&lt;/span&gt; &lt;span class="nt"&gt;-it&lt;/span&gt; ollama ollama pull gemma4:e2b-it-qat

&lt;span class="c"&gt;# Test that the model responds&lt;/span&gt;
&lt;span class="c"&gt;# If the container has already been created and &lt;/span&gt;
&lt;span class="c"&gt;# is currently stopped, simply use: docker start ollama&lt;/span&gt;
docker &lt;span class="nb"&gt;exec&lt;/span&gt; &lt;span class="nt"&gt;-it&lt;/span&gt; ollama ollama run gemma4:e2b-it-qat

&lt;span class="c"&gt;# Verify that the model is running&lt;/span&gt;
docker &lt;span class="nb"&gt;exec&lt;/span&gt; &lt;span class="nt"&gt;-it&lt;/span&gt; ollama ollama ps
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;b. Api de gemini. La api key se puede generar de manera gratuita desde &lt;a href="https://aistudio.google.com/" rel="noopener noreferrer"&gt;aquí&lt;/a&gt; y utilizar al menos estos modelos (experimentar con los que te permita):&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;gemini-2.5-flash-lite
gemini-2.5-flash
gemini-3.5-flash
gemini-3.5-flash-lite
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;El código del multiagente Graph está en Python&lt;/strong&gt; y la estructura del proyecto se diseñó de manera que sea más explicativo su lógica:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;strands-graph/
├── README.md                        # Project overview, setup, and usage instructions
├── requirements.txt                  # Python dependencies (strands-agents[gemini,ollama], strands-agents-evals, pydantic, etc.)
├── .env.example                      # Template for API keys (GEMINI_API_KEY) and Ollama config
├── .gitignore
│
├── src/
│   ├── __init__.py
│   ├── config.py                     # Model configs: role -&amp;gt; provider mapping (Gemini/Ollama), get_model()
│   ├── main.py                       # Entry point: builds graph, runs on input, prints/exports result, saves run log
│   │
│   ├── agents/
│   │   ├── __init__.py               # Re-exports all create_*_agent() factories
│   │   ├── coordinator_agent.py      # Entry point: splits input text into chunks for parallel extraction
│   │   ├── extractor_agent.py        # Shared extractor logic, instantiated 3x (one per chunk); no compound entities
│   │   ├── aggregator_agent.py       # Conflict resolution: merges, deduplicates, splits any compound entities
│   │   ├── validator_agent.py        # structured_output_model: checks format, consistency, completeness, bias
│   │   └── publisher_agent.py        # Formats and exports the final validated KG
│   │
│   ├── graph/
│   │   ├── __init__.py
│   │   ├── builder.py                # GraphBuilder setup: 7 nodes, edges (incl. aggregator-&amp;gt;publisher), entry point
│   │   └── conditions.py             # Edge conditions: needs_revision, is_approved, all_dependencies_complete
│   │
│   ├── models/
│   │   └── schemas.py                # Pydantic schemas: Relation, KnowledgeGraph, ValidatorOutput
│   │
│   └── utils/
│       ├── logging_config.py         # Debug logging + tee_console_to_file (saves full run output to logs/)
│       └── kg_export.py              # Parses and exports final KG to JSON
│
├── tests/
│   ├── __init__.py
│   ├── test_conditions.py            # Unit tests for all_dependencies_complete, needs_revision, is_approved
│   ├── test_kg_export.py             # Unit tests for parse_publisher_output (valid/invalid JSON, schema mismatch)
│   ├── test_metrics.py               # Unit tests for evals/metrics.py, incl. find_compound_entities regression check
│   ├── test_schemas.py               # Unit tests for Relation/KnowledgeGraph/ValidatorOutput validation
│   └── test_settings.py              # Unit tests for get_model role/provider resolution and missing API key error
│
├── examples/
│   └── sample_input.txt              # Short input text used as the default demo run
│
├── evals/
│   ├── __init__.py
│   ├── test_cases/
│   │   └── kg_extraction_cases.json  # Input texts + expected relations for evaluation
│   ├── evaluators.py                 # Custom Strands Evals SDK evaluators (precision/recall, feedback loop)
│   ├── evaluate_graph.py             # Strands Evals SDK runner: Case/Experiment against test cases
│   └── metrics.py                    # Domain metrics: precision/recall, loop iterations, bias-flag rate, compound entities
│
├── logs/
│   └── .gitkeep                      # Full console output per run (logs/run_&amp;lt;timestamp&amp;gt;.log), gitignored otherwise
│
└── outputs/
    └── .gitkeep                      # Generated KG JSON + eval reports land here, gitignored otherwise

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  Ejecución Local
&lt;/h3&gt;

&lt;p&gt;Una vez que tenemos el repositorio del código fuente clonado y el docker de ollama con el modelo gemma 4 o la api key de gemini generada, pasamos armar el ambiente.&lt;/p&gt;

&lt;p&gt;Los requerimientos que vamos a encontrar en  &lt;code&gt;requirements.txt&lt;/code&gt;:&lt;br&gt;
strands-agents[gemini,ollama]&amp;gt;=1.0.0&lt;br&gt;
strands-agents-tools&amp;gt;=0.1.0&lt;br&gt;
strands-agents-evals&lt;br&gt;
python-dotenv&amp;gt;=1.0.0&lt;br&gt;
pydantic&amp;gt;=2.0.0&lt;br&gt;
pytest&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pip &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-r&lt;/span&gt; requirements.txt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;En &lt;code&gt;.env&lt;/code&gt; se necesitan estos valores. Notar que depende el modelo que elegimos podemos intercambiar:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;#Gemini (required if any role uses provider="gemini") ---
GEMINI_API_KEY=your_gemini_api_key_here
GEMINI_MODEL_ID=gemini-2.5-flash
#Ollama (required if any role uses provider="ollama") ---
OLLAMA_HOST=http://localhost:11434
OLLAMA_MODEL_ID=gemma4:e2b-it-qat
#Per-role provider overrides (optional) ---
#Values: "gemini" or "ollama". Defaults are set in src/config.py.
MODEL_PROVIDER_COORDINATOR=ollama
MODEL_PROVIDER_EXTRACTOR=ollama
MODEL_PROVIDER_AGGREGATOR=ollama
MODEL_PROVIDER_VALIDATOR=ollama
MODEL_PROVIDER_PUBLISHER=ollama
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cp&lt;/span&gt; .env.example .env
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;En &lt;code&gt;src/config.py&lt;/code&gt;&lt;/strong&gt; está la configuración de despliegue, en este caso de ejecución local se encuentran parámetros como la &lt;code&gt;temperature&lt;/code&gt;, &lt;code&gt;top_p,&lt;/code&gt; &lt;code&gt;max_output_tokens&lt;/code&gt; (muy importante porque limita los tokens que pueden gastar los agentes).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Las constantes estructurales del grafo a nivel módulo&lt;/strong&gt;, se encuentran en &lt;strong&gt;&lt;code&gt;src/graph/builder.py&lt;/code&gt;&lt;/strong&gt; :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;NUM_EXTRACTORS&lt;/code&gt;&lt;/strong&gt; → cantidad de nodos extractores paralelos (y de chunks que pide el Coordinator). Cambiarlo requiere que coincida con el &lt;code&gt;num_chunks&lt;/code&gt; pasado a &lt;code&gt;create_coordinator_agent()&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;MAX_NODE_EXECUTIONS&lt;/code&gt;&lt;/strong&gt; → límite global de ejecuciones de nodos en todo el grafo, la salvaguarda contra el feedback loop infinito Validator↔Aggregator.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;EXECUTION_TIMEOUT_SECONDS&lt;/code&gt;&lt;/strong&gt; → timeout global del grafo completo.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;NUM_EXTRACTORS&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;
&lt;span class="n"&gt;MAX_NODE_EXECUTIONS&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;15&lt;/span&gt;
&lt;span class="n"&gt;EXECUTION_TIMEOUT_SECONDS&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1200&lt;/span&gt; &lt;span class="c1"&gt;# (For local execution, it's advisable to have a high value)
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Las pruebas&lt;/strong&gt; están organizadas en &lt;code&gt;tests/&lt;/code&gt; en &lt;strong&gt;un solo nivel: ejecución rápida y determinista&lt;/strong&gt;. Validan la lógica de las funciones de condición de Graph (&lt;code&gt;needs_revision&lt;/code&gt;, &lt;code&gt;is_approved&lt;/code&gt;, &lt;code&gt;all_dependencies_complete&lt;/code&gt;), el parsing/validación de schemas (&lt;code&gt;Relation&lt;/code&gt;, &lt;code&gt;KnowledgeGraph&lt;/code&gt;, &lt;code&gt;ValidatorOutput&lt;/code&gt;).&lt;br&gt;
Se testea, además de los posibles errores del runtime,  la resolución de provider/modelo por rol de &lt;code&gt;src/config.py&lt;/code&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;&lt;code&gt;_resolve_provider()&lt;/code&gt;&lt;/strong&gt; — que cada rol (&lt;code&gt;coordinator&lt;/code&gt;, &lt;code&gt;extractor&lt;/code&gt;, &lt;code&gt;aggregator&lt;/code&gt;, &lt;code&gt;validator&lt;/code&gt;, &lt;code&gt;publisher&lt;/code&gt;) resuelva al provider correcto: el default (&lt;code&gt;ROLE_PROVIDER_DEFAULTS&lt;/code&gt;) cuando no hay override, y la variable de entorno (&lt;code&gt;MODEL_PROVIDER_VALIDATOR=ollama&lt;/code&gt;, etc.) cuando sí la hay.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;&lt;code&gt;get_model()&lt;/code&gt;&lt;/strong&gt; — que devuelva una instancia de &lt;code&gt;OllamaModel&lt;/code&gt; cuando el provider es &lt;code&gt;"ollama"&lt;/code&gt;, y &lt;code&gt;GeminiModel&lt;/code&gt; cuando es &lt;code&gt;"gemini"&lt;/code&gt;.
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;python &lt;span class="nt"&gt;-m&lt;/span&gt; pytest
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;&lt;strong&gt;Procedemos a ejecutar el Graph principal.&lt;/strong&gt; En &lt;code&gt;examples/sample_input.txt&lt;/code&gt;está el input de ejemplo.&lt;br&gt;
Se puede ejecutar contra el modelo ollama local o vía api de gemini comentado más arriba.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;python &lt;span class="nt"&gt;-m&lt;/span&gt; src.main
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;El log&lt;/strong&gt; de las llamadas entre el pipeline de agentes se visualiza en la carpeta &lt;code&gt;logs/&lt;/code&gt;. Contiene la data cruda que permite comparar comportamiento del modelo (cuántos turnos internos hace cada uno, cuánto tarda, si usa tool calls, etc.).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;El resultado final&lt;/strong&gt; &lt;br&gt;
Es un  Knowledge graph y  se guarda en un &lt;code&gt;.json&lt;/code&gt; en&lt;code&gt;outputs/&lt;/code&gt;.&lt;br&gt;
Se visualiza la &lt;strong&gt;representación estructurada&lt;/strong&gt; del texto de entrada, describiendo: qué conceptos existen (&lt;code&gt;entities&lt;/code&gt;) y cómo se relacionan entre sí (&lt;code&gt;relations&lt;/code&gt;), en formato sujeto-predicado-objeto.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Por último, hacemos una evaluación de pruebas sobre el grafo multiagente real con el concepto de &lt;em&gt;"Evals".&lt;/em&gt;&lt;/strong&gt; Esto es importante para todos los agentes futuros que construyas, tomar la documentación de Strands y descubrir cómo y para qué tenemos que evaluar nuestros agentes. El resultado se guarda en &lt;code&gt;outputs/eval_report.json&lt;/code&gt; (el detalle de las evaluaciones están en "&lt;em&gt;Conceptos Claves&lt;/em&gt;"):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;python  &lt;span class="nt"&gt;-m&lt;/span&gt;  evals.evaluate_graph
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;📝 &lt;strong&gt;Nota:&lt;/strong&gt; La explicación del código fuente y paso a paso de la ejecución se encuentra detallado en el &lt;code&gt;README.md&lt;/code&gt; en el repositorio de &lt;a href="https://github.com/reinalau/strands-graph" rel="noopener noreferrer"&gt;github&lt;/a&gt; .&lt;/p&gt;




&lt;h2&gt;
  
  
  Conclusiones y lecciones aprendidas
&lt;/h2&gt;

&lt;p&gt;Construir este pipeline con Graph me dejó varias lecciones que van más allá de la forma de crearlo según su documentación:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Las constantes estructurales del grafo no son de uso de común para todos los modelos.&lt;/strong&gt; &lt;code&gt;NUM_EXTRACTORS&lt;/code&gt;, &lt;code&gt;MAX_NODE_EXECUTIONS&lt;/code&gt; y &lt;code&gt;EXECUTION_TIMEOUT_SECONDS&lt;/code&gt; en &lt;code&gt;builder.py&lt;/code&gt; parecen valores de infraestructura, pero en la práctica están acoplados al comportamiento del modelo elegido. Con Gemma4 local, el cuello de botella fue el tiempo (&lt;code&gt;EXECUTION_TIMEOUT_SECONDS&lt;/code&gt; tuvo que subir a 1800s). Con Gemini, el cuello de botella fue la convergencia del feedback loop: con &lt;code&gt;temperature=0.3&lt;/code&gt; y &lt;code&gt;top_p=0.9&lt;/code&gt; el Aggregator regeneraba las triples con variación de wording en cada ronda, y el Validator nunca encontraba dos corridas iguales para aprobar, agotando &lt;code&gt;MAX_NODE_EXECUTIONS&lt;/code&gt; sin converger. Solución: bajar a &lt;code&gt;temperature=0&lt;/code&gt; y &lt;code&gt;top_p=0.5&lt;/code&gt; .&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Análisis del input propagation de Graph&lt;/strong&gt; Un nodo sólo recibe el resultado de sus dependencias directas + el input original con el que comienza el grafo. El Publisher, dependiendo solo del Validator, se quedó sin las triples reales porque el Validator fue instruido a responder con una confirmación corta, no a repetir los datos. La solución fue agregar &lt;code&gt;aggregator → publisher&lt;/code&gt; como dependencia adicional. Hay que diseñar edges, pensando qué datos necesita cada nodo, no solo qué controla el flujo.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Las semánticas OR de Python son una fuente de bugs silenciosos.&lt;/strong&gt; Sin &lt;code&gt;all_dependencies_complete()&lt;/code&gt;, el Aggregator se hubiera ejecutado 3 veces (una por extractor) en lugar de una vez con los 3 resultados completos. Cualquier nodo con múltiples edges de entrada en Python necesita esta verificación explícita si queremos esperar a todas las dependencias.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;La granularidad de extracción es responsabilidad del prompt, no del framework.&lt;/strong&gt; Ver entidades compuestas como "entities and relations" en lugar de dos nodos separados es variabilidad normal de un LLM con temperatura &amp;gt; 0. Hay que reforzar reglas en el prompt del Extractor y del Aggregator.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;&lt;code&gt;structured_output_model&lt;/code&gt; requiere que el modelo soporte tool calling&lt;/strong&gt; (este parámetro se pasa en la creación del Agent. Hay que verificarlo (&lt;code&gt;ollama show &amp;lt;model&amp;gt;&lt;/code&gt; → &lt;code&gt;Capabilities: tools&lt;/code&gt;) antes de asumir que cualquier modelo local lo soporta.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Exact-match y LLM-as-judge miden cosas distintas.&lt;/strong&gt; En una corrida, el mismo caso obtuvo F1 exact-match = 0.0 pero SemanticCorrectnessEvaluator = 1.0, el pipeline había extraído el 100% del conocimiento correcto, solo con sinónimos distintos ("Aggregator node" vs "Aggregator"). Confiar solo en exact-match hubiera hecho pensar que el pipeline falló por completo.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Recursos
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Curso Fundamentos&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://skillbuilder.aws/learn/CFBFZNS11J/building-ai-agent-harnesses-with-strands-agents/D6YG8S6N7M" rel="noopener noreferrer"&gt;Building AI Agent Harnesses with Strands Agents&lt;/a&gt;&lt;br&gt;
&lt;a href="https://builder.aws.com/content/3GYPrAplMhl2IAl7jJW0yeKzXrR/building-ai-agent-harnesses-with-strands-agents-a-free-14-video-course/" rel="noopener noreferrer"&gt;Building AI Agent Harnesses – Video Course&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Documentación Strands Agents&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://strandsagents.com/docs/user-guide/concepts/multi-agent/graph/" rel="noopener noreferrer"&gt;Graph&lt;/a&gt;&lt;br&gt;
&lt;a href="https://strandsagents.com/docs/user-guide/evals-sdk/evaluators/" rel="noopener noreferrer"&gt;Evals&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Otros&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://builder.aws.com/content/35nhh8YGNRwWHFhHL6zXPrOYzY3/multi-agent-systems-with-graph-pattern" rel="noopener noreferrer"&gt;Multi-Agent Systems with Graph Pattern&lt;/a&gt;&lt;br&gt;
&lt;a href="https://dev.to/aws-espanol/como-detener-la-inyeccion-de-prompts-en-agentes-de-ia-que-leen-contenido-no-confiable-10h2"&gt;Inyección de prompts en agentes de IA&lt;/a&gt;&lt;br&gt;
&lt;a href="https://builder.aws.com/content/3Ecodd9aFqsG1SAkQKmqZ2KxPiP/5-multi-agent-patterns-in-strands-agents-which-one-and-when" rel="noopener noreferrer"&gt;5 Multi-Agent Patterns in Strands&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>ai</category>
      <category>agents</category>
      <category>strandsagents</category>
      <category>python</category>
    </item>
    <item>
      <title>Swarm en Strands: orquestación autónoma mediante handoffs emergentes</title>
      <dc:creator>Laura Bolaños</dc:creator>
      <pubDate>Mon, 03 Aug 2026 14:55:38 +0000</pubDate>
      <link>https://dev.to/aws-builders/swarm-en-strands-orquestacion-autonoma-mediante-handoffs-emergentes-11a9</link>
      <guid>https://dev.to/aws-builders/swarm-en-strands-orquestacion-autonoma-mediante-handoffs-emergentes-11a9</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Siguiendo con la serie de artículos sobre la orquestación de multiagentes en Strands, en estas notas le toca turno a Swarm o Enjambre explicado con un ejemplo gamificado de cinco agentes especializados, donde cada uno es responsable de  diseñar una dimensión distinta de un videojuego. Testeado de dos maneras con Gemma4 + Ollama  y con la api de Gemini.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Introducción
&lt;/h2&gt;

&lt;p&gt;Para desarrollar y comprender agentes con el framework&amp;nbsp;Strands Agents&amp;nbsp;te propongo hacer un curso de fundamentos o leer su documentación (que es extensa). Los fundamentos son importantes! Es primordial conocer cómo dar complejidad a nuestros agentes, no esperar delegar toda la responsabilidad del diseño a la IA (recursos al pie de estas notas).&lt;br&gt;
Para la prueba de concepto utilicé dos opciones locales de ejecución que me permitió analizar sus resultados:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Ollama + el pequeño modelo&amp;nbsp;&lt;strong&gt;gemma4:e2b-it-qat&lt;/strong&gt;&amp;nbsp;(que pesa poco mas de 4gb) ejecutando en Docker.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Con la Api de gemini. La api key se puede generar de manera gratuita y utilizar el modelo &lt;strong&gt;"Gemini 2.5 Flash"&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;🎮 &lt;strong&gt;El caso de uso que tomé para desarrollar el patrón&amp;nbsp;Swarm&lt;/strong&gt; es la creación de un Game Design Document (GDD) a partir de una premisa: "roguelike de cocina en un castillo maldito..."&lt;br&gt;
Participan cinco agentes especializados, cada uno responsable de una dimensión diferente del diseño del videojuego: mecánicas, narrativa, niveles, lore (historias, mitos, reglas, datos del pasado) y experiencia de juego. Todos colaboran para transformar una premisa simple en un &lt;strong&gt;Game Design Document (GDD)&lt;/strong&gt; coherente. &lt;/p&gt;

&lt;p&gt;A diferencia de un pipeline lineal, los agentes pueden detectar fricciones entre sus decisiones (una mecánica que contradice la narrativa, una regla de lore que rompe el balance) y reabrir la conversación con el agente correspondiente hasta llegar a un resultado consensuado.&lt;/p&gt;
&lt;h2&gt;
  
  
  Conceptos Claves
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;➡ Swarm es un patrón de orquestación de agentes colaborativo&lt;/strong&gt;, donde múltiples agentes trabajan juntos como un equipo para resolver tareas complejas. A diferencia de los sistemas multiagente tradicionales, ya sean secuenciales o jerárquicos, un enjambre permite la coordinación autónoma entre agentes con &lt;strong&gt;contexto y memoria de trabajo compartidos&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Swarm es apropiado cuando:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;La secuencia de pasos no se puede predefinir:&lt;/strong&gt; de antemano no sabés qué agente necesitará intervenir, porque depende del contenido que se vaya generando.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Puede haber correcciones o retrocesos:&lt;/strong&gt; el problema requiere ciclos de ida y vuelta entre especialistas (ejemplo: una decisión de un agente invalida el trabajo de otro).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Hay múltiples dimensiones de expertise en tensión:&lt;/strong&gt; cada agente defiende una perspectiva distinta y el valor está justamente en que negocien entre sí, no en que trabajen aislados uno de otro.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Se necesita razonamiento colectivo emergente:&lt;/strong&gt; la solución final surge de la interacción entre agentes, no de que un solo agente (o un humano) coordine todo desde arriba.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;❗ No es el patrón ideal cuando el flujo de trabajo es fijo y predecible.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;➡ Memoria / Contexto&lt;/strong&gt; &lt;br&gt;
Poseen memoria de trabajo compartida y contexto completo. Cuando el enjambre se ejecuta, el historial completo de mensajes (propuestas, objeciones y razonamientos de de los agentes anteriores) se transmite al nuevo agente que toma el control (&lt;em&gt;handoff&lt;/em&gt;). &lt;br&gt;
&lt;em&gt;Payload del Handoff&lt;/em&gt;: además del historial acumulado, cuando un agente ejecuta la herramienta de handoff, puede adjuntar un mensaje o nota explícita (&lt;code&gt;message&amp;nbsp;&lt;/code&gt;/&amp;nbsp;&lt;code&gt;context&lt;/code&gt;) explicando&amp;nbsp;por qué&amp;nbsp;le transfiere la tarea y qué espera que haga.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;➡ Nodos vs. Agentes&lt;/strong&gt;&lt;br&gt;
En Swarm, cada agente se registra como un "nodo" (&lt;code&gt;SwarmNode&lt;/code&gt;) que envuelve al &lt;code&gt;Agent&lt;/code&gt;. Esta distinción importa porque el swarm no razona en términos de "quién es quién" sino de "qué nodo ejecuta a continuación". El resultado final expone esto como &lt;code&gt;node_history&lt;/code&gt;, una lista de nodos ejecutados, no una conversación: es lo que permite reconstruir después la topología real que se ejecutó, sin haberla tenido que diseñar de antemano.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;➡ El mecanismo de Handoff es tool-calling, no un cambio de contexto mágico&lt;/strong&gt; &lt;br&gt;
Vale la pena aclarar explícitamente que &lt;code&gt;handoff_to_agent&lt;/code&gt;no es una función especial del framework fuera del paradigma de LLMs: es una tool más, inyectada automáticamente por Strands en cada agente del swarm, con el mismo mecanismo de function-calling que cualquier otra tool. La consecuente es &lt;strong&gt;la fiabilidad del patrón Swarm depende enteramente de qué tan bien el modelo subyacente hace tool-calling&lt;/strong&gt;. No es una limitación de Strands, es una dependencia estructural del patrón. Por eso, acompañando este artículo el caso de uso se testeo de dos maneras: con el pequeño modelo &lt;em&gt;Gemma4&lt;/em&gt; y con el modelo &lt;em&gt;Gemini 2.5 Flash&lt;/em&gt;. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;➡ Topología emergente vs. predefinida (el argumento central de "por qué Swarm")&lt;/strong&gt;&lt;br&gt;
En Swarm, la topología es un &lt;strong&gt;resultado&lt;/strong&gt;, no una entrada. Se descubre recién en la ejecución, y puede variar entre corridas con la misma premisa (ejemplo: tengo 5 agentes y sólo intervienen 4). Esto es una ventaja de adaptabilidad y un riesgo no-determinista al mismo tiempo.&lt;br&gt;
Se necesita indicar donde comienza el enjambre y cada punto de decisión lo toma el propio agente en base al contexto acumulado. Aquí un topología de ejemplo del caso de uso:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;mechanic_designer
      ↓
level_architect ←──────────┐
      ↓                    │
playtest_simulator ─────────┤ (iteration 1: objection → adjustment)
      ↓                    │
level_architect ──────────→┘
      ↓
playtest_simulator ─────────┐ (iteration 2: objection → adjustment)
      ↓                    │
level_architect ←───────────┘
      ↓
narrative_weaver
      ↓
lore_keeper
      ↓
playtest_simulator ─────────┐ (iteration 1: objection → adjustment)
      ↓                    │
level_architect ←───────────┘
      ↓
playtest_simulator
      ↓
[VERDICT: NO FRICTION DETECTED] → END
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;➡ Guardrails como parte del diseño&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;max_handoffs&lt;/code&gt;: Máximo de transferencias entre agentes permitidos en todo el swarm antes de forzar el corte. Es el límite global de "pasos" de la ejecución completa.&lt;br&gt;
&lt;code&gt;max_iterations&lt;/code&gt;: Máximo de iteraciones del swarm (ejecuciones de nodo) permitidas. En la práctica actúa junto con &lt;code&gt;max_handoffs&lt;/code&gt; como segunda red de seguridad contra ejecuciones descontroladas.&lt;br&gt;
&lt;code&gt;execution_timeout&lt;/code&gt;: Tiempo total en segundos que puede durar la ejecución completa del swarm, sumando todos los agentes y handoffs. Si se supera, el swarm corta con Status.FAILED aunque esté en medio de un turno.&lt;br&gt;
&lt;code&gt;node_timeout&lt;/code&gt;: Tiempo máximo (en segundos) que un agente individual puede tardar en un solo turno (una llamada al modelo + su respuesta). Protege contra que un nodo puntual se cuelgue sin afectar el límite global.&lt;br&gt;
&lt;code&gt;repetitive_handoff_detection_window&lt;/code&gt;: Tamaño de la "ventana" (cantidad de handoffs recientes) que Strands analiza para detectar patrones repetitivos. Con 6, mira los últimos 6 handoffs para decidir si hay un loop.&lt;br&gt;
&lt;code&gt;min_unique_agents&lt;/code&gt;: Dentro de esa ventana, cantidad mínima de agentes distintos que deben haber participado para considerar el flujo "sano". Si en los últimos 6 handoffs participaron menos de 3 agentes únicos (ej. solo 2 rebotando entre sí), Strands lo detecta como ping-pong y corta el swarm.&lt;br&gt;
Todos los guardrails anteriores no son opcionales para un swarm en producción, son necesarios para limitar la autonomía de los agentes y que el costo de tokens, tiempo o dinero en APIs pagas no se descontrole.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;➡ La importancia del diseño de prompts&lt;/strong&gt;&lt;br&gt;
Strands provee el mecanismo de handoff (la tool, el hook, los guardrails), pero no decide cuándo usarlo, eso está en el &lt;em&gt;system prompt&lt;/em&gt; de cada agente. En este caso de uso, cada uno de los 5 prompts define explícitamente tres cosas: el rol y criterios de evaluación del agente, a quién y bajo qué condición debe transferir el control, y reglas de convergencia para evitar que vuelva a objetar lo mismo una vez resuelto ("Convergence rule").&lt;/p&gt;

&lt;p&gt;Esta última fue necesaria escribirla ya que en las primeras ejecuciones algunos agentes re-abrían el mismo desacuerdo varias veces con distintas palabras, generando ciclos improductivos que ni los guardrails ni el hook podían distinguir de una negociación legítima. La solución fue de prompt, instruir explícitamente a cada agente a aceptar una corrección después de la primera vuelta, salvo que aparezca un motivo nuevo. Los guardrails protegen contra loops estructurales; esto resuelve los loops semánticos.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;➡ Hooks como punto de extensión para mitigar limitaciones del modelo elegido&lt;/strong&gt;&lt;br&gt;
Strands permite engancharse al ciclo de ejecución del agente mediante &lt;em&gt;hooks&lt;/em&gt;, interceptando eventos como una llamada a herramienta exitosa. En el caso de uso se implementó &lt;code&gt;StopAfterHandoffHook&lt;/code&gt;, que fuerza al agente a detener su turno inmediatamente después de un handoff exitoso.&lt;/p&gt;

&lt;p&gt;Este mecanismos sirve para  cuando el prompt no alcanza para garantizar un comportamiento, evita que el modelo llame a la herramienta de handoff más de una vez por turno. Es una intervención determinista a nivel de código, sin depender del prompt engineering. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;➡ Evaluaciones (Evals)&lt;/strong&gt;&lt;br&gt;
Existe el package &lt;code&gt;strands-agents-evals&lt;/code&gt; que provee evaluadores reutilizables (por salida, por trayectoria de tool-calls, por trazas de ejecución, etc). En este caso de uso se implementaron dos evaluadores:&lt;br&gt;
&lt;strong&gt;- Evaluación por Trayectoria (Trajectory Evaluation)&lt;/strong&gt;. En vez de exigir una secuencia exacta de handoffs, valida propiedades estructurales de la ejecución. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;que el punto de entrada haya sido el correcto. &lt;/li&gt;
&lt;li&gt;que haya participado una cantidad mínima de agentes únicos, y que los agentes indispensables (como &lt;code&gt;mechanic_designer&lt;/code&gt;) hayan intervenido.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;- Evaluación por Salida (Output Evaluation)&lt;/strong&gt;. Verifica que el GDD final contenga las palabras clave esperadas del dominio del juego (ej. "curse", "ingredient", "castle"), como chequeo básico de que el contenido generado es relevante a la premisa de origen.&lt;/p&gt;

&lt;p&gt;⭐ Este enfoque refleja una diferencia clave frente a patrones más deterministas como agents-as-tools donde se puede evaluar contra un resultado esperado preciso (si se delegó al agente correcto); en cambio en Swarm hay que evaluar la &lt;strong&gt;forma&lt;/strong&gt; del comportamiento, no una secuencia fija.&lt;/p&gt;
&lt;h2&gt;
  
  
  Descripción de la solución
&lt;/h2&gt;

&lt;p&gt;📦&amp;nbsp;Repositorio GitHub:&amp;nbsp;&lt;a href="https://github.com/reinalau/strands-swarm" rel="noopener noreferrer"&gt;github.com/reinalau/strands-swarm&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Feyb3nt953zbb9q9gzxd8.jpg" 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%2Feyb3nt953zbb9q9gzxd8.jpg" alt=" " width="800" height="567"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Como comenté más arriba, utilicé 2 opciones de modelos para la ejecución y analizar el comportamiento, pero podes usar solo una de ellas:&lt;/p&gt;

&lt;p&gt;a. Docker Desktop, luego descargué la imagen de Ollama e instalé&amp;nbsp;gemma4:e2b-it-qat&amp;nbsp;(que pesa poco mas de 4GB). Todos los modelos gemma los podés encontrar&amp;nbsp;&lt;a href="https://ollama.com/library/gemma4/tags" rel="noopener noreferrer"&gt;aquí&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Start the Ollama server with a persistent volume&lt;/span&gt;
docker run &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="nt"&gt;--name&lt;/span&gt; ollama &lt;span class="nt"&gt;-p&lt;/span&gt; 11434:11434 &lt;span class="nt"&gt;-v&lt;/span&gt; ollama_data:/root/.ollama ollama/ollama

&lt;span class="c"&gt;# Download the model&lt;/span&gt;
docker &lt;span class="nb"&gt;exec&lt;/span&gt; &lt;span class="nt"&gt;-it&lt;/span&gt; ollama ollama pull gemma4:e2b-it-qat

&lt;span class="c"&gt;# Test that the model responds&lt;/span&gt;
docker &lt;span class="nb"&gt;exec&lt;/span&gt; &lt;span class="nt"&gt;-it&lt;/span&gt; ollama ollama run gemma4:e2b-it-qat

&lt;span class="c"&gt;# Verify that the model is running&lt;/span&gt;
docker &lt;span class="nb"&gt;exec&lt;/span&gt; &lt;span class="nt"&gt;-it&lt;/span&gt; ollama ollama ps
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;b. Generé una api key de gemini de capa gratuita, desde &lt;a href="https://aistudio.google.com/" rel="noopener noreferrer"&gt;aquí&lt;/a&gt;. Te permite usar el modelo &lt;strong&gt;Gemini 2.5 Flash&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;El código del multiagente está en Python&lt;/strong&gt; y la estructura del proyecto se diseñó de manera que sea más explicativo su lógica:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;strands-swarm/
├── README.md
├── requirements.txt
├── .env.example
├── .gitignore
│
├── src/
│   ├── __init__.py
│   ├── main.py                  # entry point, builds and runs the swarm
│   ├── config.py                # model provider config, timeouts, swarm limits
│   │
│   ├── agents/
│   │   ├── __init__.py
│   │   ├── _common.py           # shared model factory + prompt loader
│   │   ├── _hooks.py            # StopAfterHandoffHook
│   │   ├── mechanic_designer.py
│   │   ├── narrative_weaver.py
│   │   ├── level_architect.py
│   │   ├── lore_keeper.py
│   │   └── playtest_simulator.py
│   │
│   ├── prompts/
│   │   ├── mechanic_designer.md
│   │   ├── narrative_weaver.md
│   │   ├── level_architect.md
│   │   ├── lore_keeper.md
│   │   └── playtest_simulator.md
│   │
│   ├── swarm/
│   │   ├── __init__.py
│   │   └── build_swarm.py       # instantiates agents + configures Swarm (max_handoffs, etc.)
│   │
│   └── output/
│       ├── __init__.py
│       └── gdd_builder.py       # consolidates node_history/results into the final GDD
│
├── evals/
│   ├── __init__.py
│   ├── eval_cases.py            # EvalCase definitions (premise, expected agents, keywords)
│   └── run_evals.py             # trajectory + output evaluators over the swarm
│
├── examples/
│   └── example_premise.txt      # "cooking roguelike in a cursed castle"
│
├── outputs/
│   └── .gitkeep                 # generated GDDs land here after each run
│
├── logs/
│   └── .gitkeep                 # execution logs / handoff events
│
└── tests/
    ├── __init__.py
    └── test_swarm_flow.py

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  Ejecución Local
&lt;/h3&gt;

&lt;p&gt;Una vez que tenemos el repositorio del código fuente clonado y el docker de ollama con el modelo gemma 4 o la api key de gemini generada, pasamos armar el ambiente.&lt;br&gt;
Los requerimientos que vamos a encontrar en &lt;code&gt;requirements.txt&lt;/code&gt;:&lt;br&gt;
strands-agents[ollama]&lt;br&gt;
strands-agents[gemini]&lt;br&gt;
strands-agents-evals&lt;br&gt;
python-dotenv&lt;br&gt;
pytest&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pip &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-r&lt;/span&gt; requirements.txt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;En &lt;code&gt;.env&lt;/code&gt; necesitamos:&lt;br&gt;
OLLAMA_HOST=&lt;a href="http://localhost:11434" rel="noopener noreferrer"&gt;http://localhost:11434&lt;/a&gt;&lt;br&gt;
MODEL_NAME=gemma4:e2b-it-qat&lt;br&gt;
MODEL_PROVIDER=gemini   # ollama&lt;br&gt;
GEMINI_API_KEY=tuapikeyOpcional&lt;br&gt;
GEMINI_MODEL_NAME=gemini-2.5-flash&lt;br&gt;
LOG_LEVEL=INFO&lt;br&gt;
MODEL_TEMPERATURE=0.5&lt;br&gt;
MODEL_MAX_TOKENS=3500&lt;br&gt;
MODEL_NUM_CTX=4096&lt;br&gt;
MAX_HANDOFFS=12&lt;br&gt;
MAX_ITERATIONS=12&lt;br&gt;
EXECUTION_TIMEOUT=5000&lt;br&gt;
NODE_TIMEOUT=1500&lt;br&gt;
REPETITIVE_HANDOFF_DETECTION_WINDOW=6&lt;br&gt;
REPETITIVE_HANDOFF_MIN_UNIQUE_AGENTS=3&lt;br&gt;
ENTRY_POINT_AGENT=mechanic_designer&lt;br&gt;
LOG_DIR=logs&lt;br&gt;
OUTPUT_DIR=outputs&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   &lt;span class="nb"&gt;cp&lt;/span&gt; .env.example .env
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Las pruebas&lt;/strong&gt; están organizadas en un enfoque de 2 niveles (&lt;code&gt;tests/&lt;/code&gt;):&lt;br&gt;
&lt;strong&gt;Nivel 1 (Rápidas y deterministas):&lt;/strong&gt; Valida la estructura del swarm, la configuración de nodos/límites, la extracción de texto y la consolidación del GDD sin realizar llamadas reales al modelo. Usa cadenas simuladas como "Cooking roguelike in a cursed castle." o "Test Premise".&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   python &lt;span class="nt"&gt;-m&lt;/span&gt; pytest
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Nivel 2 (Test de integración end-to-end):&lt;/strong&gt; Ejecuta el swarm completo contra el modelo real (Gemma4 en Ollama o Gemini). Está deshabilitado por default, pytest lo salta automáticamente, y se activa así en esta ejecución:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   &lt;span class="nv"&gt;RUN_INTEGRATION_TESTS&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;1 python &lt;span class="nt"&gt;-m&lt;/span&gt; pytest &lt;span class="nt"&gt;-m&lt;/span&gt; integration
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;📝 &lt;strong&gt;Nota:&lt;/strong&gt; el comportamiento de activación/desactivación explícita para tests que dependen de un LLM real es una práctica común cuando se integran estos flujos a pipelines de CI/CD, donde ejecutar llamadas reales a un modelo en cada commit sería muy lento.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Procedemos a ejecutar el Swarm principal&lt;/strong&gt;. Se puede ejecutar contra el modelo ollama local o vía api de gemini. Se configura en &lt;code&gt;.env&lt;/code&gt; , tener en cuenta de cambiar &lt;code&gt;MODEL_PROVIDER&lt;/code&gt; a "gemini" u "ollama". También recomiendo revisar valores default de &lt;code&gt;src/config.py&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;python &lt;span class="nt"&gt;-m&lt;/span&gt; src.main
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;El log&lt;/strong&gt; de las llamadas entre agentes se visualiza en la carpeta &lt;code&gt;logs/&lt;/code&gt;. &lt;br&gt;
&lt;strong&gt;El resultado final&lt;/strong&gt; del intercambio de mensajes entre los agentes del enjambre es el Game Design Document y se guarda en un documento markdown en la carpeta &lt;code&gt;outputs/&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;⭐ Te invito analizar la topología de handoffs después de las ejecuciones para entender si los agentes necesitan ajustes ya sea de prompts, hooks o parámetros de configuración.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Por último, hacemos una evaluación de pruebas  sobre el agente real con el concepto de&amp;nbsp;"Evals"&lt;/strong&gt;.&amp;nbsp;Esto es importante para todos los agentes futuros que construyas, tomar la documentación de Strands y descubrir cómo y para qué tenemos que evaluar nuestros agentes.&lt;br&gt;
Se desactiva el recolector de telemetría&amp;nbsp;OpenTelemetry: &lt;code&gt;OTEL_SDK_DISABLED=true&lt;/code&gt;&amp;nbsp;para evitar cuelgues en un entorno local con el modelo en ollama (si internamente no alcanza un endpoint se cuelga indefinidamente).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;OTEL_SDK_DISABLED&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"true"&lt;/span&gt;
python &lt;span class="nt"&gt;-m&lt;/span&gt; evals.run_evals
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;📝&amp;nbsp;Nota-2:&amp;nbsp;La explicación del código y paso a paso de la ejecución se encuentra detallado en el README.md en el repositorio de &lt;a href="https://github.com/reinalau/strands-swarm" rel="noopener noreferrer"&gt;github&lt;/a&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  Conclusiones
&lt;/h2&gt;

&lt;p&gt;El patrón *&lt;em&gt;Swarm *&lt;/em&gt; cede el control del flujo al propio modelo. Una corrida puede resolverse en 4 pasos o en 11, en un minuto o en dos horas, según decisiones que toman los agentes que intervienen. &lt;br&gt;
Con un modelo chico experimenté loops de handoff, ping-pong entre agentes, transferencias narradas en texto en lugar de ejecutadas y para resolverlo tuve que agregar controles explícitos: límites de iteración, detección de repetición y un hook que corta el turno apenas el handoff se confirma.&lt;br&gt;
La autonomía de un swarm no reemplaza los guardarraíles de ingeniería, los vuelve indispensables.&lt;/p&gt;

&lt;p&gt;⭐ Y como trabajo futuro hay que pensar cómo implementar un proyecto multiagente Swarm productivo. El presente proyecto es educativo y sirve para entender el funcionamiento del patrón, pero es insuficiente para producción. AWS ya tiene un camino natural para eso: &lt;strong&gt;Amazon Bedrock AgentCore&lt;/strong&gt;, un runtime serverless que ejecuta agentes Strands con aislamiento por sesión, observabilidad, memoria administrada y escalado automático. Queda para un próximo artículo explorar esa migración.&lt;/p&gt;




&lt;h2&gt;
  
  
  Recursos
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Curso Fundamentos&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://skillbuilder.aws/learn/CFBFZNS11J/building-ai-agent-harnesses-with-strands-agents/D6YG8S6N7M" rel="noopener noreferrer"&gt;Building AI Agent Harnesses with Strands Agents&lt;/a&gt;&lt;br&gt;
&lt;a href="https://builder.aws.com/content/3GYPrAplMhl2IAl7jJW0yeKzXrR/building-ai-agent-harnesses-with-strands-agents-a-free-14-video-course/" rel="noopener noreferrer"&gt;Building AI Agent Harnesses – Video Course&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Documentación Strands Agents&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://strandsagents.com/docs/user-guide/concepts/multi-agent/swarm/" rel="noopener noreferrer"&gt;Swarm&lt;/a&gt;&lt;br&gt;
&lt;a href="https://strandsagents.com/docs/user-guide/evals-sdk/evaluators/" rel="noopener noreferrer"&gt;Evals&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Otros&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://builder.aws.com/content/3GJxKulvQXV120QgfCSaq4QzG4I/blog-writer-agent-using-swarm-pattern/" rel="noopener noreferrer"&gt;Blog Writer Agent using Swarm Pattern&lt;/a&gt;&lt;br&gt;
&lt;a href="https://builder.aws.com/content/3GYPrAplMhl2IAl7jJW0yeKzXrR/building-ai-agent-harnesses-with-strands-agents-a-free-14-video-course/" rel="noopener noreferrer"&gt;Building AI Agent Harnesses – Video Course&lt;/a&gt;&lt;br&gt;
&lt;a href="https://dev.to/aws-espanol/detener-alucinaciones-de-agentes-de-ia-validar-antes-de-que-el-agente-escriba-en-memoria-2ad3/"&gt;Detener alucinaciones de agentes de IA&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>ai</category>
      <category>agents</category>
      <category>strandsagents</category>
      <category>python</category>
    </item>
    <item>
      <title>Agents as Tools en Strands: orquestación jerárquica en local con Gemma 4 y Ollama</title>
      <dc:creator>Laura Bolaños</dc:creator>
      <pubDate>Mon, 27 Jul 2026 16:33:25 +0000</pubDate>
      <link>https://dev.to/aws-builders/agents-as-tools-en-strands-orquestacion-jerarquica-en-local-con-gemma-4-y-ollama-db4</link>
      <guid>https://dev.to/aws-builders/agents-as-tools-en-strands-orquestacion-jerarquica-en-local-con-gemma-4-y-ollama-db4</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Hace tiempo vengo consumiendo cursos de orquestación de agentes de distintos frameworks y me propuse navegar por los diferentes patrones de Strands Agents de complejidad media, ejecutados localmente (con la idea de encarar más adelante el deploy en AWS). Este artículo está dedicado a Agents-as-Tools, corriendo con Ollama en una laptop con solo 16GB de RAM 💻.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Introducción
&lt;/h2&gt;

&lt;p&gt;Para desarrollar y comprender agentes con el framework Strands Agents  te propongo hacer un curso de fundamentos o leer su documentación (que es extensa). Los fundamentos son importantes! Es primordial conocer cómo dar complejidad a nuestros agentes, no esperar delegar toda la responsabilidad del diseño a la IA (recursos al pie de estas notas).&lt;/p&gt;

&lt;p&gt;Para que la prueba de concepto se pueda ejecutar localmente, utilicé Ollama +  el pequeño modelo &lt;strong&gt;gemma4:e2b-it-qat&lt;/strong&gt; (que pesa poco mas de 4gb) ejecutando en Docker. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;El caso de uso que tomé para desarrollar el patrón&lt;/strong&gt; es la automatización del soporte básico de TI:&lt;br&gt;
🛠 Se recibe un ticket de soporte y se determina si es un ticket de facturación, técnico o seguridad. Luego se envía al agente especializado para que lo resuelva.&lt;/p&gt;
&lt;h2&gt;
  
  
  Conceptos claves
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;➡ Agents As Tools es un patrón de orquestación multiagente&lt;/strong&gt; que como se describe en la documentación es jerárquico (hub and spooke), donde un orquestador delega tareas a agentes especializados que tienen diferentes tools para resolver. El orquestador y cada agente poseen contexto aislado, no se contaminan entre sí. &lt;/p&gt;

&lt;p&gt;Para clarificar el funcionamiento: al delegar, &lt;strong&gt;hay dos agents loops anidados, no uno compartido:&lt;/strong&gt; el orquestador no "pausa" su razonamiento en espera del especialista, simplemente visualiza una tool call que devuelve texto, por detrás, esa tool call disparó un loop completo e independiente que ya terminó antes de volver.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;Orchestrator loop
   └─ calls billing_agent&lt;span class="o"&gt;(&lt;/span&gt;query&lt;span class="o"&gt;)&lt;/span&gt; → triggers a new, isolated loop
         └─ Billing loop: check_invoice_status → process_refund → final response
   ← receives only the final string &lt;span class="o"&gt;(&lt;/span&gt;doesn&lt;span class="s1"&gt;'t see the internal tool calls)
   └─ continues its own loop: delegates to another specialist or replies to the user
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;➡&lt;/strong&gt; &lt;code&gt;@tool&lt;/code&gt; no distingue entre &lt;strong&gt;operación simple o integración vía APis y agente completo&lt;/strong&gt; , el patrón Agents-as-Tools explota que un agente &lt;strong&gt;cumpla la misma interfaz&lt;/strong&gt; que una tool (recibe input, devuelve output), para que se pueda componer recursivamente. Es lo que permite anidar agentes dentro de agentes sin que el nivel superior necesite saber la complejidad interna del nivel inferior.&lt;/p&gt;

&lt;p&gt;⭐ La descripción (docstring) de cada función &lt;code&gt;@tool&lt;/code&gt; no es un comentario decorativo: es el input que el LLM orquestador lee en tiempo de ejecución para decidir a qué especialista delegar. Distinto del parámetro &lt;code&gt;description=&lt;/code&gt; del propio &lt;code&gt;Agent&lt;/code&gt;, que es metadata informativa y no interviene en el routing.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;➡ Memoria del orquestador (ConversationManager)&lt;/strong&gt;. Utilicé el concepto de compresión al hacer que el agente recuerde los últimos 10 mensajes o tickets de la sesión para mantener contexto entre interacciones consecutivas con &lt;code&gt;SlidingWindowConversationManager(window_size=10)&lt;/code&gt; &lt;br&gt;
Mantiene los mensajes en una lista dentro del objeto Python en RAM durante la ejecución del proceso.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;➡ Hook de dominio (SteeringHandler)&lt;/strong&gt;. Implementa el "&lt;em&gt;HookProvider&lt;/em&gt;" de Strands, en este caso de uso fuerza el orden de pasos del protocolo de respuesta ante incidentes de Seguridad. Si el LLM intenta llamar por ejemplo a &lt;code&gt;revoke_access_token&lt;/code&gt; sin haber auditado primero la IP, el hook lo bloquea con &lt;code&gt;event.cancel_tool&lt;/code&gt; antes de que la función se ejecute. El framework impone la lógica de negocio determinista, sin depender del criterio del modelo. Describe con precisión los tres eventos &lt;code&gt;BeforeInvocationEvent&lt;/code&gt;,&amp;nbsp;&lt;code&gt;AfterToolCallEvent&lt;/code&gt;,&amp;nbsp;&lt;code&gt;BeforeToolCallEvent&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Los hooks sirven en general para:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Prevenir loops infinitos o excesivos de tool calls (control de costos/tokens)&lt;/li&gt;
&lt;li&gt;Guardrails de seguridad/negocio (ej. no permitir más de n transacciones, n consultas a una API con rate limit, etc.)&lt;/li&gt;
&lt;li&gt;Es el mecanismo estándar de Strands para inyectar lógica de control &lt;strong&gt;sin modificar el core del agent loop.&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;➡ Evaluaciones (Evals):&lt;/strong&gt; evaluación de comportamiento del agente (con &lt;code&gt;Contains&lt;/code&gt;, no asserts tradicionales). &lt;/p&gt;

&lt;p&gt;Algunas consideraciones que tomé para poder ejecutar los evals sin que se cuelguen en un entorno local con el modelo en ollama: Desactivé OTLP de Opentelemetry,  este si internamente no alcanza un endpoint (&lt;code&gt;localhost:4318&lt;/code&gt;) se cuelga indefinidamente. &lt;/p&gt;

&lt;p&gt;En el caso de uso del repositorio se hacen evaluaciones deterministas ya que se utiliza solo un LLM, no se abarcan todas las evaluaciones pero sí dos importantes descritas debajo.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Output Evaluation&lt;/strong&gt;. Evalúa el &lt;strong&gt;resultado final&lt;/strong&gt; (el texto que recibe el usuario), sin importar el camino interno que tomó el agente para llegar ahí. Es un chequeo determinista de &lt;strong&gt;keyword matching&lt;/strong&gt;: la respuesta debe contener ciertas palabras clave esperadas (&lt;code&gt;INV-1002&lt;/code&gt;, &lt;code&gt;USR-884&lt;/code&gt;, etc.).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Trajectory Evaluation&lt;/strong&gt;. No evalúa qué respondió el agente, sino cómo llegó ahí, &lt;strong&gt;qué tools/sub-agentes invocó durante su razonamiento&lt;/strong&gt;. En el código, &lt;code&gt;extract_called_tools()&lt;/code&gt; inspecciona &lt;code&gt;agent.messages&lt;/code&gt; buscando bloques &lt;code&gt;toolUse&lt;/code&gt;, y &lt;code&gt;evaluate_trajectory()&lt;/code&gt; verifica que el sub-agente esperado (ej. &lt;code&gt;BillingAgent&lt;/code&gt;) haya sido efectivamente el delegado. Para la ejecución en entorno local con Ollama, la función &lt;code&gt;extract_called_tools&lt;/code&gt; extrae directamente los nombres de las herramientas en agent.messages y comprueba en milisegundos si se invocó a &lt;code&gt;case.expected_agent&lt;/code&gt;, sin necesidad de instanciar un modelo juez adicional ni hacer peticiones extra a Bedrock/Ollama (sin cuelgues asíncronos).&lt;/p&gt;

&lt;p&gt;⭐ &lt;strong&gt;PASS / FAIL a nivel dimensión, en el output:&lt;/strong&gt; cada &lt;code&gt;EvalCase&lt;/code&gt; se marca como aprobado (&lt;code&gt;case_passed&lt;/code&gt;) solo si ambas dimensiones pasan (&lt;code&gt;traj_eval.test_pass&lt;/code&gt; and &lt;code&gt;out_eval.test_pass&lt;/code&gt;).  Un agente puede delegar al especialista correcto (trayectoria OK) pero responder sin las keywords esperadas (output FAIL), y el caso se marca como fallido igual. &lt;strong&gt;Una sola dimensión de evaluación no alcanza&lt;/strong&gt;: el agente puede "hacer lo correcto" pero "comunicarlo mal", o viceversa.&lt;/p&gt;
&lt;h2&gt;
  
  
  Descripción de la solución
&lt;/h2&gt;

&lt;p&gt;📦 Repositorio GitHub: &lt;a href="https://github.com/reinalau/strands-agents-as-tools" rel="noopener noreferrer"&gt;github.com/reinalau/strands-agents-as-tools&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fquhnii87fqcf4urzghj4.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%2Fquhnii87fqcf4urzghj4.png" alt="Soporte TI - Agents-as-Tools" width="800" height="468"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Para alojar el LLM utilicé Docker Desktop, luego descargué la imagen de Ollama e instalé &lt;strong&gt;gemma4:e2b-it-qat&lt;/strong&gt; (que pesa poco mas de 4GB). Todos los modelos gemma los podés encontrar &lt;a href="https://ollama.com/library/gemma4/tags" rel="noopener noreferrer"&gt;aquí&lt;/a&gt; pero este en particular funciona OK en una laptop con 16GB de RAM. &lt;/p&gt;

&lt;p&gt;Como condición necesaria asegurate de dar memoria suficiente a Docker.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Start the Ollama server with a persistent volume&lt;/span&gt;
docker run &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="nt"&gt;--name&lt;/span&gt; ollama &lt;span class="nt"&gt;-p&lt;/span&gt; 11434:11434 &lt;span class="nt"&gt;-v&lt;/span&gt; ollama_data:/root/.ollama ollama/ollama
&lt;span class="c"&gt;# Download the model&lt;/span&gt;
docker &lt;span class="nb"&gt;exec&lt;/span&gt; &lt;span class="nt"&gt;-it&lt;/span&gt; ollama ollama pull gemma4:e2b-it-qat
&lt;span class="c"&gt;# Test that the model responds&lt;/span&gt;
docker &lt;span class="nb"&gt;exec&lt;/span&gt; &lt;span class="nt"&gt;-it&lt;/span&gt; ollama ollama run gemma4:e2b-it-qat
&lt;span class="c"&gt;# Verify that the model is running&lt;/span&gt;
docker &lt;span class="nb"&gt;exec&lt;/span&gt; &lt;span class="nt"&gt;-it&lt;/span&gt; ollama ollama ps
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Importante!&lt;/strong&gt; Testear el modelo gemma 4 en la terminal haciendo alguna pregunta para corroborar que responda.&lt;/p&gt;

&lt;p&gt;El código del multiagente está en Python y la estructura del proyecto se diseñó de manera que sea más explicativo su lógica:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;strands-agents-as-tools
├── README.md
├── requirements.txt
├── .env.example
├── .gitignore
│
├── src/
│   ├── __init__.py
│   ├── main.py
│   ├── config.py
│   │
│   ├── agents/
│   │   ├── __init__.py
│   │   ├── orchestrator.py
│   │   ├── billing_agent.py
│   │   ├── technical_agent.py
│   │   └── security_agent.py
│   │
│   ├── tools/
│   │   ├── __init__.py
│   │   ├── billing_tools.py
│   │   ├── technical_tools.py
│   │   └── security_tools.py
│   │
│   └── hooks/
│       ├── __init__.py
│       └── security_verification_hook.py   # Domain SteeringHandler
│
├── examples/
│   └── sample_tickets.py
│
├── evals/
│   ├── __init__.py
│   ├── eval_cases.py                 # Cases with inputs, expected agent and keywords
│   └── run_evals.py                  # Dual evaluator: Trajectory (Tool Call) + Output (Keywords)
│
└── tests/
    └── test_agents.py                # Unit tests for tools (no LLM)

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  Ejecución local
&lt;/h3&gt;

&lt;p&gt;Una vez que tenemos el repositorio del código fuente clonado y el docker de ollama con el modelo gemma 4 ejecutando, pasamos armar el ambiente.&lt;/p&gt;

&lt;p&gt;Los requerimientos que vamos a encontrar en &lt;code&gt;requirements.txt&lt;/code&gt;:&lt;br&gt;
strands-agents&lt;br&gt;
strands-agents-evals&lt;br&gt;
ollama&lt;br&gt;
python-dotenv&lt;br&gt;
pytest&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pip &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-r&lt;/span&gt; requirements.txt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;En el .env vamos a necesitar:&lt;br&gt;
OLLAMA_HOST=&lt;a href="http://localhost:11434" rel="noopener noreferrer"&gt;http://localhost:11434&lt;/a&gt;&lt;br&gt;
MODEL_NAME=gemma4:e2b-it-qat&lt;br&gt;
LOG_LEVEL=INFO&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cp&lt;/span&gt; .env.example .env
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Los test son &lt;strong&gt;pruebas unitarias deterministas&lt;/strong&gt; (&lt;code&gt;tests/&lt;/code&gt;).&amp;nbsp;Permite validar rápidamente y de forma aislada la lógica de código puro de las herramientas (tools) de negocio (facturación, soporte técnico y seguridad), sin requerir inferencia de LLM. Garantizan que las funciones auxiliares retornen los estados y formatos esperados antes de ser expuestas como capacidades&amp;nbsp;&lt;code&gt;@tool&lt;/code&gt;&amp;nbsp;al sistema multiagente.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;python &lt;span class="nt"&gt;-m&lt;/span&gt; pytest tests/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Procedemos a ejecutar el flujo principal demostrativo donde se ve al orquestador delegar tickets&lt;/strong&gt; a los especialistas procesados por Ollama. Puede ser algo lento debido al modelo de ollama elegido pero finalmente termina el flujo con los ejemplos de tickets. Se utilizan ejemplos de soportes dentro de main con &lt;code&gt;from examples.sample_tickets import SAMPLE_TICKETS&lt;/code&gt; ...te invito a cambiarlos!&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;python &lt;span class="nt"&gt;-m&lt;/span&gt; src.main
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Por último, hacemos una evaluación de pruebas de calidad y precisión ejecutadas sobre el agente real con el concepto de &lt;em&gt;"Evals"&lt;/em&gt;. Esto es importante para todos los agentes futuros que construyas: hay que tomar la documentación de Strands y descubrir cómo y para qué tenemos que evaluar nuestros agentes.&lt;/p&gt;

&lt;p&gt;También recomiendo establecer &lt;code&gt;OTEL_SDK_DISABLED=true&lt;/code&gt; para desactivar el recolector de telemetría OpenTelemetry (explicado en Conceptos Claves)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;OTEL_SDK_DISABLED&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"true"&lt;/span&gt;
python &lt;span class="nt"&gt;-m&lt;/span&gt; evals.run_evals
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Este último script ejecuta dos metodologías de evaluación según las especificaciones de &lt;strong&gt;Strands Agents: Output / Keyword Evaluation y Tool-Call Trajectory Evaluation&lt;/strong&gt; (explicado en Conceptos Claves) &lt;/p&gt;

&lt;p&gt;📝 &lt;strong&gt;Nota:&lt;/strong&gt; Todo la explicación del código del repositorio y paso a paso de la ejecución se encuentra en el &lt;code&gt;README.md&lt;/code&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Conclusiones
&lt;/h2&gt;

&lt;p&gt;Implementar Agents-as-Tools con un modelo local vía Ollama fue una buena forma de entender el patrón de orquestación sin gastar, pero también descubrí que modelos chicos como &lt;code&gt;gemma4:e2b-it-qat&lt;/code&gt; pueden ser inconsistentes en su razonamiento (llamadas duplicadas a una misma tool, dudas antes de delegar) a diferencia de un modelo más grande (Bedrock/Claude/GPT-4) que probablemente sea más preciso. Esto no invalida el patrón, todo lo contrario: reafirma por qué los guardrails deterministas (el hook de seguridad) y las evaluaciones automáticas es la forma de detectar el comportamiento errático antes de que llegue a producción.&lt;/p&gt;

&lt;h3&gt;
  
  
  Limitaciones del ejemplo
&lt;/h3&gt;

&lt;p&gt;Este repositorio es educativo, y tiene varias simplificaciones:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Tools hardcodeadas con datos mock:&lt;/strong&gt; &lt;code&gt;check_invoice_status&lt;/code&gt;, &lt;code&gt;check_system_status&lt;/code&gt;, &lt;code&gt;audit_ip_address&lt;/code&gt;, etc. devuelven datos fijos en el código, no consultan ningún sistema real.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Un solo LLM local:&lt;/strong&gt; no se probó el comportamiento con otros modelos para comparar consistencia de routing/tool-calling entre modelos de distinto tamaño.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Evaluación:&lt;/strong&gt; solo se cubrieron Output y Trajectory de forma determinista; no se probó chaos testing, LLM-as-judge, ni simulación multi-turno (mirar la documentación oficial). &lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Pensando en este mismo Multiagente productivo 🤯
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Conectar tools a APIs/sistemas reales:&lt;/strong&gt; reemplazar los mocks por llamadas a una API de facturación real, un endpoint de status de infraestructura (ej. AWS CloudWatch, Datadog), y un servicio real de gestión de identidad (ej. IAM, Okta) para revocación de tokens. Varios de estos ya existen como servidores MCP mantenidos por la comunidad/AWS (conectarlos vía &lt;code&gt;MCPClient&lt;/code&gt; sería más rápido que escribir cada tool a mano).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Persistencia real de sesión:&lt;/strong&gt; en este ejemplo cada ticket es stateless entre ejecuciones de &lt;code&gt;main.py&lt;/code&gt;; sumar un &lt;code&gt;SessionManager&lt;/code&gt;(&lt;code&gt;FileSessionManager&lt;/code&gt;o &lt;code&gt;DynamoDBSessionManager&lt;/code&gt;) para simular conversaciones multi-turno reales de un mismo usuario.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Comparar modelos:&lt;/strong&gt; correr el mismo test suite contra un modelo de Bedrock o la API de Anthropic, y comparar tasa de errores de routing/tool-calling contra el modelo local, cuantificar el trade-off costo/latencia vs. confiabilidad.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;&lt;a href="https://strandsagents.com/docs/user-guide/evals-sdk/chaos_testing/" rel="noopener noreferrer"&gt;Chaos testing&lt;/a&gt;:&lt;/strong&gt; simular caídas de las APIs reales (una vez conectadas) con &lt;code&gt;ChaosPlugin&lt;/code&gt;, para validar que el agente degrada con gracia en vez de alucinar una respuesta. &lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;⭐ &lt;strong&gt;Migrar a &lt;a href="https://strandsagents.com/docs/user-guide/deploy/deploy_to_bedrock_agentcore/" rel="noopener noreferrer"&gt;Bedrock AgentCore&lt;/a&gt;&lt;/strong&gt;: envolver el orquestador con &lt;code&gt;BedrockAgentCoreApp&lt;/code&gt;para exponerlo vía el runtime administrado de AWS, adicionando &lt;code&gt;AgentCoreMemorySessionManager&lt;/code&gt;para memoria semántica de usuario (facts/preferences) en vez de solo &lt;code&gt;SlidingWindowConversationManager&lt;/code&gt; &lt;/p&gt;




&lt;h2&gt;
  
  
  Recursos
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Cursos Fundamentos&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://skillbuilder.aws/learn/CFBFZNS11J/building-ai-agent-harnesses-with-strands-agents/D6YG8S6N7M" rel="noopener noreferrer"&gt;Building AI Agent Harnesses with Strands Agents&lt;/a&gt;&lt;br&gt;
&lt;a href="https://builder.aws.com/content/3GYPrAplMhl2IAl7jJW0yeKzXrR/building-ai-agent-harnesses-with-strands-agents-a-free-14-video-course/" rel="noopener noreferrer"&gt;Building AI Agent Harnesses – Video Course&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Documentación Strands Agents&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://strandsagents.com/docs/user-guide/concepts/multi-agent/agents-as-tools/" rel="noopener noreferrer"&gt;Agents as Tools&lt;/a&gt;&lt;br&gt;
&lt;a href="https://strandsagents.com/docs/user-guide/evals-sdk/evaluators/trajectory_evaluator/" rel="noopener noreferrer"&gt;Trajectory Evaluator&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Artículos de Builders y AWS Developer Advocate&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://builder.aws.com/content/3AUxm8HafsZjZiOb3qrPDIH2MlD/aws-strands-agents-simplifica-la-creacion-de-agentes-de-ia" rel="noopener noreferrer"&gt;AWS Strands Agents: simplifica la creación de agentes de IA&lt;/a&gt;&lt;br&gt;
&lt;a href="https://dev.to/aws-espanol/detener-alucinaciones-de-agentes-de-ia-validar-antes-de-que-el-agente-escriba-en-memoria-2ad3/"&gt;Detener alucinaciones de agentes de IA&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>ai</category>
      <category>agents</category>
      <category>strandsagents</category>
      <category>python</category>
    </item>
    <item>
      <title>Apuntes para la certificación AWS CloudOps Engineer Associate (SOA-C03) - Parte 2</title>
      <dc:creator>Laura Bolaños</dc:creator>
      <pubDate>Thu, 04 Jun 2026 13:41:05 +0000</pubDate>
      <link>https://dev.to/aws-builders/apuntes-para-la-certificacion-aws-cloudops-engineer-associate-soa-c03-parte-2-2e04</link>
      <guid>https://dev.to/aws-builders/apuntes-para-la-certificacion-aws-cloudops-engineer-associate-soa-c03-parte-2-2e04</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Segunda parte de las notas de examen. La idea es que identifiques los principales temas para el examen de certificación y conocer algunos tips de estudio para alcanzar con éxito tu meta 🎓&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;⬅&lt;/strong&gt; &lt;a href="https://dev.to/reinalau/apuntes-para-la-certificacion-aws-cloudops-engineer-associate-soa-c03-parte-1-2dji"&gt;&lt;strong&gt;&lt;em&gt;Apuntes para la certificación AWS CloudOps Engineer Associate (SOA-C03) - Parte 1&lt;/em&gt;&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;Temas que son claves conocer para el examen - Segunda Parte&lt;/strong&gt;
&lt;/h2&gt;

&lt;h3&gt;
  
  
  AWS Config
&lt;/h3&gt;

&lt;p&gt;Es prioritario revisar todas sus casos de uso y su integración con acciones de remediación con SSM y sus runbook. La remediación puede ser manual o automática.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;La integración importante es con EventBridge para realizar una acción. Algo a saber es que los avisos a un equipo de soporte se hacen a través de SNS.
&lt;/li&gt;
&lt;li&gt;Data Aggregation for AWS Config (Multi-Account - Multi-Region) ➡  recopila datos de configuración y cumplimiento de varias cuentas y varias regiones de AWS. Una organización en AWS Organizations y todas las cuentas de esa organización que tengan AWS Config habilitado.
&lt;/li&gt;
&lt;li&gt;Reglas de configuración comunes en AWS Config:&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Rule&lt;/th&gt;
&lt;th&gt;Qué chequea&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;cloudtrail-enabled&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;CloudTrail habilitado en la cuenta&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;mfa-enabled-for-iam-console-access&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Los usuarios de IAM con acceso a la consola tienen MFA habilitado&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;s3-bucket-public-read-prohibited&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Los buckets de S3 no permiten acceso de lectura pública&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;encrypted-volumes&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Los volúmenes de EBS están encriptados&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;rds-storage-encrypted&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Las instancias RDS tienen encriptación del storage habilitada&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;iam-password-policy&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;La política de contraseñas cumple con los requisitos especificados&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;restricted-ssh&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Los Security Groups no permiten acceso SSH sin restricciones (puerto 22)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;root-account-mfa-enabled&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;La cuenta root tiene MFA habilitado&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;vpc-flow-logs-enabled&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;VPC Flow Logs está activado&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;cloud-trail-encryption-enabled&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Los logs de CloudTrail están encriptados con KMS&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;s3-bucket-ssl-requests-only&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;S3 solo acepta requests HTTPS&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;ec2-instances-in-vpc&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Las instancias EC2 están dentro de una VPC&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;access-keys-rotated&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Las access keys de IAM se rotan dentro de N días&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Control Tower
&lt;/h3&gt;

&lt;p&gt;Relacionado con casos de uso de Organization ➡ Proporciona una landing zone para múltiples cuentas. Automatiza la configuración de AWS Organizations, la venta de cuentas, las medidas de seguridad (controles preventivos y de detección) y un registro de auditoría centralizado.&lt;/p&gt;

&lt;h3&gt;
  
  
  Security Hub - WAF - Detective - Inspector -  GuardDuty
&lt;/h3&gt;

&lt;p&gt;Es útil realizar cuadro comparativo con los servicios Detective, Inspector y GuardDuty para visualizar sus diferencias y en qué casos de uso son más adecuados. La mayoría se utilizan para controles de detección.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Security Hub:&lt;/strong&gt; gestiona la postura o posición de seguridad de una Organización. Automatiza las comprobaciones de mejores prácticas y agrega alertas de Seguridad.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;WAF:&lt;/strong&gt; los casos de uso referidos son sencillos de identificar, detección de ataques sql injection - bloqueo de ip de países-rate limiting por IP, etc. Se gestiona mediante &lt;strong&gt;Web ACLs&lt;/strong&gt; con reglas propias o &lt;strong&gt;AWS Managed Rules&lt;/strong&gt; (reglas preconfiguradas por AWS)
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Inspector:&lt;/strong&gt; Evalúa automáticamente vulnerabilidades en EC2, ECR y funciones Lambda ➡ prevención y detección proactiva.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Detective:&lt;/strong&gt; simplifica el proceso de &lt;strong&gt;analizar, investigar e identificar la causa raíz&lt;/strong&gt; de los hallazgos de seguridad o actividades sospechosas en las cuentas de AWS. Recopila registros de CloudTrail (frase clave es log de APIs), VPC Flows, GuardDuty, entre otros  ➡ Actúa en el post-incidente.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;GuardDuty:&lt;/strong&gt; Detección de amenazas continua mediante análisis de &lt;strong&gt;CloudTrail, VPC Flow Logs y DNS logs&lt;/strong&gt;. Usa ML para identificar comportamiento anómalo (ej: instancia EC2 haciendo crypto mining, credenciales filtradas usadas desde IP sospechosa). Es el &lt;strong&gt;detector en tiempo real,&lt;/strong&gt; genera findings que pueden disparar acciones en EventBridge → Lambda/SNS.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Conceptos básicos de Networking
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;NACL&lt;/strong&gt;: Actúan a nivel de subnet y no tienen estado. Hay que agregar reglas de entrada y de salida. Las reglas se evalúan de manera ascendente. Es el primer mecanismo de defensa a nivel subred, útil para &lt;strong&gt;bloquear IPs específicas.&lt;/strong&gt; Ejemplo de resolución de problema: una instancia EC2 (en una private subnet) no tiene salida a internet? ➡ Las reglas de entrada y salida deben permitir el tráfico (incluidos los puertos de retorno efímeros 1024–65535).
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Security groups&lt;/strong&gt;: Actúan a nivel de instancia o servicio. Tienen estado, todo lo que se permite entrar- se permite salir (salvo que indiques lo contrario en las reglas de salida).

&lt;ul&gt;
&lt;li&gt;Resolución de conexiones vía SSH o RDP a instancias EC2. Qué revisar? En principio las reglas de entrada del Security Group a los puertos correspondientes.
&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Nat Gateway:&lt;/strong&gt; es escalable mejor que &lt;em&gt;Instance Nat Gateway.&lt;/em&gt; Asociada a una subnet pública. Solo para IPV4. Asegurar que la &lt;em&gt;Private subnet route table&lt;/em&gt; debe tener
&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Egress-Only Internet Gateway (EIGW):&lt;/strong&gt;  permite que los recursos en una subred privada se comuniquen con el exterior a través de &lt;strong&gt;IPv6&lt;/strong&gt;
&lt;/li&gt;

&lt;/ul&gt;

&lt;h3&gt;
  
  
  VPC FlowLogs
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;VPC &amp;gt; Your VPCs &amp;gt; Flow logs &amp;gt; Create Flow Logs (se necesita un rol para escribir en CloudWatch). Monitorea todo el trafico de la VPC determinada aparece en &lt;strong&gt;&lt;em&gt;CloudWatch &amp;gt; Logs &amp;gt; Log Management&lt;/em&gt;&lt;/strong&gt; .
&lt;/li&gt;
&lt;li&gt;Otros destinos de logs son S3 y Kinesis Data Firehose. Se puede realizar consultas sql mediante &lt;strong&gt;Athena&lt;/strong&gt; tomando como fuente S3.
&lt;/li&gt;
&lt;li&gt;Conocer el formato de los registros Default VPC Flow Logs y Custom VPC Flow Log Format. Cómo configurar y qué soportes permite resolver.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Ejemplo cuando falta una regla en Nacl o Security Group para permitir una conexión:&lt;/p&gt;

&lt;p&gt;2 123456789012 eni-abc123 10.0.1.4 10.0.2.5 43234 443 6 12 1400 1624387215 1624387275 ACCEPT OK&lt;/p&gt;

&lt;p&gt;2 123456789012 eni-abc123 172.31.16.139 172.31.16.21 80 42333 6 24 2456 1624387215 1624387275 REJECT OK&lt;/p&gt;

&lt;h3&gt;
  
  
  Route 53
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Hosted zone ➡ pública y privada. Comprender el concepto de casos de uso: El cliente externo consulta la &lt;strong&gt;zona pública&lt;/strong&gt; de Route 53 y llega a la &lt;strong&gt;versión pública&lt;/strong&gt; de la app y el cliente interno dentro de la VPC consulta la &lt;strong&gt;zona privada&lt;/strong&gt; de Route 53 y llega a la &lt;strong&gt;versión interna&lt;/strong&gt; de la app ➡ ambos pueden tener el mismo nombre laub.com pero devuelven destinos diferentes de acuerdo de donde se lo consulte.
&lt;/li&gt;
&lt;li&gt;Es primordial conocer los tipos de registros y casos de usos:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Tipo&lt;/th&gt;
&lt;th&gt;Qué contiene&lt;/th&gt;
&lt;th&gt;Uso&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;A&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;IPv4&lt;/td&gt;
&lt;td&gt;
&lt;a href="http://www.laub.com" rel="noopener noreferrer"&gt;www.laub.com&lt;/a&gt; → 52.10.1.100&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;AAAA&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;IPv6&lt;/td&gt;
&lt;td&gt;
&lt;a href="http://www.laub.com" rel="noopener noreferrer"&gt;www.laub.com&lt;/a&gt; → 2001:db8::1&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;CNAME&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Otro hostname&lt;/td&gt;
&lt;td&gt;www → otro.dominio.com&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Alias&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Recurso AWS&lt;/td&gt;
&lt;td&gt;laub.com → mi-alb.us-east-1.elb.amazonaws.com&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;NS&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Name servers de la zona&lt;/td&gt;
&lt;td&gt;Delegación de subdominios&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;SOA&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Metadatos de la zona&lt;/td&gt;
&lt;td&gt;Se crea automático&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;MX&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Servidor de correo&lt;/td&gt;
&lt;td&gt;laub.com → mail.empresa.com&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;TXT&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Texto libre&lt;/td&gt;
&lt;td&gt;Verificación de dominio, SPF&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;SRV&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Servicio + puerto&lt;/td&gt;
&lt;td&gt;Usado por algunos protocolos&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;PTR&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;DNS inverso&lt;/td&gt;
&lt;td&gt;IP → hostname&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Route 53 Resolver:&lt;/strong&gt; define cómo y hacia dónde se hacen las consultas DNS.

&lt;ul&gt;
&lt;li&gt;En esta feature se da la relación de entornos híbridos, DNS de on-premises resuelto por Route 53 (Outbound endpoint) o un DNS en AWS (en VPC) que lo resuelve on-premises (Inbound endpoint).
&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Route 53 routing policies&lt;/strong&gt;, hay preguntas de examen sobre estas features relacionados con estrategias de deployment o failover:&lt;/li&gt;

&lt;/ul&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Política&lt;/th&gt;
&lt;th&gt;Descripción&lt;/th&gt;
&lt;th&gt;Health Checks&lt;/th&gt;
&lt;th&gt;Caso de Uso&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Simple&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Un único servidor. Sin lógica ni failover.&lt;/td&gt;
&lt;td&gt;No soporta&lt;/td&gt;
&lt;td&gt;Un solo recurso sin redundancia&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Weighted&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Distribución de tráfico por pesos.&lt;/td&gt;
&lt;td&gt;Soportado — si falla un destino su peso es ignorado&lt;/td&gt;
&lt;td&gt;Deployment canary, A/B testing&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Latency&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Dirige el tráfico al recurso con menor latencia.&lt;/td&gt;
&lt;td&gt;Soportado&lt;/td&gt;
&lt;td&gt;Usuarios globales que necesitan baja latencia&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Geolocation&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Enruta según la ubicación geográfica del origen de la consulta DNS (continente, país o estado).&lt;/td&gt;
&lt;td&gt;Soportado&lt;/td&gt;
&lt;td&gt;Contenido regionalizado, cumplimiento normativo&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Geoproximity&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Enruta según ubicación geográfica de los recursos con valor de sesgo opcional. Requiere &lt;strong&gt;Route 53 Traffic Flow&lt;/strong&gt;.&lt;/td&gt;
&lt;td&gt;Soportado&lt;/td&gt;
&lt;td&gt;Balanceo geográfico con control fino de fronteras&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Failover&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Enruta a recurso principal; si falla va al secundario. Recursos en VPC privada requieren CloudWatch Alarm como intermediario.&lt;/td&gt;
&lt;td&gt;Requerido&lt;/td&gt;
&lt;td&gt;Alta disponibilidad activo-pasivo&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;IP-Based&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Enruta según la IP del remitente de la consulta DNS.&lt;/td&gt;
&lt;td&gt;Soportado&lt;/td&gt;
&lt;td&gt;Segmentación por ISP o rango de IPs corporativas&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Multivalue Answer&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Devuelve hasta 8 registros saludables al azar.&lt;/td&gt;
&lt;td&gt;Soportado&lt;/td&gt;
&lt;td&gt;Distribución simple sin necesidad de ELB&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Cross Account&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;La zona padre delega un subdominio creando registros NS que apuntan a la zona hija en otra cuenta.&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;td&gt;Gestión de DNS entre múltiples cuentas AWS&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Query Logging:&lt;/strong&gt; Registra todas las consultas DNS está disponible para zonas públicas., con esto podemos resolver problemas.  Auditar consultas DNS de una zona privada ➡ no es Route 53 query logging, es &lt;em&gt;Route 53 Resolver Query Logs&lt;/em&gt; (servicio diferente).
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Tipos de Health checks:&lt;/strong&gt; Es un concepto básico a retener ➡Endpoint health check, Calculated health check y CloudWatch alarm health check.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Cálculo de CIDR para un Subnet
&lt;/h3&gt;

&lt;p&gt;En una VPC no se puede superponer el bloque de direcciones cidr de sus subnet ➡ ejemplo encontrar el tamaño mínimo de la subred que tenga 30 direcciones IP disponibles.&lt;/p&gt;

&lt;p&gt;Total de direcciones IP disponibles = 2^(32-X) – 5 (Reservadas por AWS)&lt;/p&gt;

&lt;p&gt;Donde X es la notación CIDR.&lt;/p&gt;

&lt;p&gt;Para el bloque CIDR 192.168.1.0/&lt;strong&gt;26&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Total de direcciones IP disponibles = 2^(32-26) – 5 = 59 direcciones IP.&lt;/p&gt;

&lt;h3&gt;
  
  
  AWS Global Accelerator
&lt;/h3&gt;

&lt;p&gt;Si enfrentas alguna pregunta que necesitas tiempos de milisegundos con direcciones IP anycast estáticas ➡ la respuesta seguramente es Global Accelerator.&lt;/p&gt;

&lt;p&gt;Frases claves para este servicio: aceleración  del tráfico TCP/UDP.&lt;/p&gt;

&lt;h3&gt;
  
  
  VPC Peering - Transit Gateway
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;VPC peering:&lt;/strong&gt;  Conocer las limitaciones de  ➡ hasta 10 interconexiones de VPC es potable. No hay transitividad en las conexiones. Es conveniente realizar laboratorio para entender cómo se configuran las Route Tables. Tener presente que se puede realizar conexiones entre diferentes regiones y cuentas.

&lt;ul&gt;
&lt;li&gt;Solucionar conexion de VPC Peering entre dos instancias de EC2 en dos VPC diferentes. Se configuró correctamente el VPC peering entre ambas. Una instancia A puede hacer ping a instancia B. Pero la instancia B no puede hacer ping a la instancia A ➡ Posiblemente para solucionar este problema es necesario actualizar el grupo de seguridad de la instancia A para permitir el tráfico ICMP entrante.
&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Transit Gateway:&lt;/strong&gt; actúa como una hub de redes eliminando la necesidad de complejas redes de interconexión. A diferencia de VPC peering tiene ruteo transitivo. Importante! conocer el concepto de adjuntar una VPC (Attach a VPC).

&lt;ul&gt;
&lt;li&gt;Soporta &lt;strong&gt;multicast&lt;/strong&gt;.
&lt;/li&gt;
&lt;li&gt;Se puede usar con &lt;strong&gt;VPN y Direct Connect&lt;/strong&gt; como hub central, simplificando arquitecturas híbridas.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;TGW Route Tables&lt;/strong&gt; permiten segmentar el tráfico entre VPCs conectadas.Ejemplo ➡ aislar producción de desarrollo.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;h3&gt;
  
  
  Cloudfront
&lt;/h3&gt;

&lt;p&gt;Comprender cómo configurar los diferentes &lt;strong&gt;orígenes.&lt;/strong&gt; El más sencillo y natural que conocemos, si has rendido alguna certificación, es S3. Pero vas a tener que preparar ELB y el caso especial de EC2:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Origin Type&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;th&gt;Clave para el examen&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Amazon S3&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Contenido estático&lt;/td&gt;
&lt;td&gt;OAC reemplaza OAI (legacy). Sin OAC, el bucket puede quedar público&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Application Load Balancer&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Contenido dinámico&lt;/td&gt;
&lt;td&gt;El ELB debe ser &lt;strong&gt;público&lt;/strong&gt;. CloudFront no puede llegar a un ALB interno. Usá &lt;strong&gt;security group del ALB restringido a los IPs de CloudFront&lt;/strong&gt; para que el tráfico solo entre por CloudFront&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;EC2 instance&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Servidores web custom&lt;/td&gt;
&lt;td&gt;La instancia debe ser &lt;strong&gt;pública&lt;/strong&gt; y con security group que permita IPs de CloudFront&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;API Gateway&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;REST o HTTP APIs&lt;/td&gt;
&lt;td&gt;Podés deshabilitar el endpoint público de APIGW y forzar acceso solo vía CloudFront&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Custom HTTP origin&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Servidores on-premise u otros&lt;/td&gt;
&lt;td&gt;Requiere HTTPS con certificado válido si usás HTTPS entre CloudFront y el origen&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;ul&gt;
&lt;li&gt;Qué pasa cuando hay pocos cache hit (&lt;strong&gt;Cache Hit bajo&lt;/strong&gt;)?

&lt;ul&gt;
&lt;li&gt;Revisar el &lt;strong&gt;TTL&lt;/strong&gt; , si es muy bajo, los objetos expiran rápido y van al origen frecuentemente.
&lt;/li&gt;
&lt;li&gt;Revisar la &lt;strong&gt;Cache Key&lt;/strong&gt; , si incluye headers, cookies o query strings innecesarios, fragmenta el caché y baja el hit rate. La solución es usar &lt;strong&gt;Cache Policies&lt;/strong&gt; para controlar qué forma parte de la cache key.
&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;Qué hacer cuando lo cacheado quedó antiguo, cómo resolver inmediatamente sin esperar que expire el TTL?

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Invalidación de caché&lt;/strong&gt; (&lt;code&gt;CreateInvalidation&lt;/code&gt;) hace que CloudFront descarte el objeto antes del TTL.
&lt;/li&gt;
&lt;li&gt;Alternativa más eficiente para el examen: &lt;strong&gt;versionado de archivos&lt;/strong&gt; en el nombre (&lt;code&gt;app.v2.js&lt;/code&gt;),  evita invalidaciones y es la práctica recomendada por AWS.
&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;Behavior (comportamiento): analizar las variantes. Es útil realizar laboratorios.

&lt;ul&gt;
&lt;li&gt;Permiten definir reglas distintas por &lt;strong&gt;path pattern&lt;/strong&gt; (&lt;code&gt;/api/*&lt;/code&gt;, &lt;code&gt;/images/*&lt;/code&gt;, &lt;code&gt;/static/*&lt;/code&gt;).
&lt;/li&gt;
&lt;li&gt;Cada behavior puede tener su propio origen, TTL, política de caché y restricciones de acceso.
&lt;/li&gt;
&lt;li&gt;Caso de uso común: &lt;code&gt;/api/*&lt;/code&gt; apunta a ALB (dinámico, sin caché) y &lt;code&gt;/*&lt;/code&gt; apunta a S3 (estático, con caché larga).&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;h3&gt;
  
  
  VPC Endpoints
&lt;/h3&gt;

&lt;p&gt;Es clave conocer los tipos de punto final para aplicar seguridad a la conexión de servicios aws (sin pasar por internet).&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Gateway Endpoint :&lt;/strong&gt; Es sin costo, solo para conectar con S3, DynamoDB. Importante para sortear preguntas, solo tiene utilidad dentro de una VPC, no tiene la capacidad de acceso externo. También admite políticas de punto final para controlar el acceso.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Interface Endpoint (PrivateLink):&lt;/strong&gt; Tiene costo. Crea una ENI con IP privada en tu VPC para conectarse a servicios de AWS (y servicios de terceros). Permite el acceso desde on-premise si existe conectividad previa (VPN/Direct Connect). Admite políticas de punto final para controlar qué entidades principales pueden usarlo.

&lt;ul&gt;
&lt;li&gt;Al crearlo AWS genera DNS privados para el servicio, si &lt;strong&gt;Enable Private DNS&lt;/strong&gt; está activado, las llamadas al endpoint público se resuelven automáticamente a la ENI privada. Resolución de problemas: si el tráfico sigue saliendo a internet a pesar de tener un Interface Endpoint → verificar que &lt;strong&gt;Enable Private DNS&lt;/strong&gt; esté activado.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;




&lt;p&gt;&lt;strong&gt;⬅&lt;/strong&gt; &lt;a href="https://dev.to/reinalau/apuntes-para-la-certificacion-aws-cloudops-engineer-associate-soa-c03-parte-1-2dji"&gt;&lt;strong&gt;&lt;em&gt;Apuntes para la certificación AWS CloudOps Engineer Associate (SOA-C03) - Parte 1&lt;/em&gt;&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>sysops</category>
      <category>aws</category>
      <category>certification</category>
    </item>
    <item>
      <title>Apuntes para la certificación AWS CloudOps Engineer Associate (SOA-C03) - Parte 1</title>
      <dc:creator>Laura Bolaños</dc:creator>
      <pubDate>Thu, 04 Jun 2026 03:00:00 +0000</pubDate>
      <link>https://dev.to/aws-builders/apuntes-para-la-certificacion-aws-cloudops-engineer-associate-soa-c03-parte-1-2dji</link>
      <guid>https://dev.to/aws-builders/apuntes-para-la-certificacion-aws-cloudops-engineer-associate-soa-c03-parte-1-2dji</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Primera parte de los apuntes del examen. La idea es que identifiques los principales temas para el examen de certificación y conocer algunos tips de estudio para alcanzar con éxito tu meta 🎓&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Características generales&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;La complejidad es de &lt;strong&gt;nivel medio&lt;/strong&gt;. A mi criterio lo más complejo son las diferentes formas de soporte vía SSM.&lt;/p&gt;

&lt;p&gt;Consta de &lt;a href="https://docs.aws.amazon.com/es_es/aws-certification/latest/sysops-administrator-associate-03/sysops-administrator-associate-03.html" rel="noopener noreferrer"&gt;5 dominios&lt;/a&gt; y toda la información detallada la podemos encontrar &lt;a href="https://aws.amazon.com/certification/certified-cloudops-engineer-associate/" rel="noopener noreferrer"&gt;aquí&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Solo se puede rendir en inglés, con lo cual es prioritario estudiar con apuntes, entrenamiento de preguntas y laboratorios en este idioma. Se aprueba con 720 puntos.&lt;/p&gt;

&lt;p&gt;Es una certificación que te invita a conocer en profundidad las arquitecturas mas tradicionales de AWS , la resolución de problemas en producción y el mantenimiento evolutivo al momento de actualizar infraestructura para la continuidad del negocio.&lt;/p&gt;

&lt;p&gt;⭐ Se superponen varios temas con Solutions Architect Associate y Developer Associate. Si ya rendiste alguna, te va a resultar familiar un % del contenido.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Método de estudio&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Estudiar para una certificación no tiene fórmulas mágicas, se necesita apartar tiempo de nuestro dia y constancia. Tener en claro que nos permite profundizar en conceptos o prácticas que tal vez no vemos en el trabajo diario...esa será nuestras motivación.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Tu punto de partida debe ser la &lt;a href="https://docs.aws.amazon.com/es_es/aws-certification/latest/sysops-administrator-associate-03/sysops-administrator-associate-03.html" rel="noopener noreferrer"&gt;guia de examen&lt;/a&gt; siempre.
&lt;/li&gt;
&lt;li&gt;Conviene hacer la &lt;a href="https://skillbuilder.aws/learning-plan/S427S3T7B5/exam-prep-plan-aws-certified-cloudops-engineer--associate-soac03--english/" rel="noopener noreferrer"&gt;preparación de examen de SkillBuilder&lt;/a&gt;, te da un paneo general de temas y asi podes identificar las brechas de conocimientos en las que debes profundizar.
&lt;/li&gt;
&lt;li&gt;Mi forma favorita de estudiar es hacer una especie de RAG con &lt;em&gt;NotebookLM&lt;/em&gt; con la documentación oficial de AWS pertinente (aws permite  bajar los pdf).
&lt;/li&gt;
&lt;li&gt;La novedad es que hay mcp de AWS disponibles referidos a la documentación. Por ejemplo, utilizando los temas de la guia de examen como contexto, se puede generar apuntes. Utilice &lt;a href="https://awslabs.github.io/mcp/servers/aws-documentation-mcp-server" rel="noopener noreferrer"&gt;este mcp&lt;/a&gt; , pero tambien hay uno que no he probado que es mucho más amplio y contiene temas de arquitectura &lt;a href="https://awslabs.github.io/mcp/servers/aws-knowledge-mcp-server" rel="noopener noreferrer"&gt;aquí&lt;/a&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;⭐ &lt;a href="https://github.com/reinalau/AWS-Certified/tree/main/SOA-C03" rel="noopener noreferrer"&gt;Resumen de los Dominios&lt;/a&gt; de examen generado por kiro con el mcp de la documentación de AWS.&lt;/p&gt;

&lt;p&gt;⭐ Utilicé &lt;em&gt;Tutorials Dojo&lt;/em&gt; como banco de preguntas para practicar, pero mi percepción es que las preguntas en el examen eran más difíciles.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Arquitecturas importantes&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Te invito a pensar en sus variantes para lograr alta disponibilidad, escalabilidad y resiliencia. Los temas de networking son importantes en el examen: configuración de VPC, subnet,  tablas de ruteo, Security Groups entre otros, especialmente troubleshooting de conectividad.&lt;/p&gt;

&lt;h3&gt;
  
  
  High Available (Route53)
&lt;/h3&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%2F6pxvkecvcbk261xjtr9x.jpg" 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%2F6pxvkecvcbk261xjtr9x.jpg" alt="High Available (Route53)" width="800" height="674"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  High Available and Scalable Web App (Cloudfront - ALB)
&lt;/h3&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%2F07tv409rfqmmofmwby85.jpg" 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%2F07tv409rfqmmofmwby85.jpg" alt="High Available and Scalable Web App (Cloudfront - ALB)" width="800" height="249"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Worker Fleet - SQS
&lt;/h3&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%2Fw929qpaixg5uymehebtd.jpg" 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%2Fw929qpaixg5uymehebtd.jpg" alt="Worker Fleet and SQS" width="799" height="409"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  VPC Peering
&lt;/h3&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%2Foytcdcx1ziccwewrus2o.jpg" 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%2Foytcdcx1ziccwewrus2o.jpg" alt="VPC Peering" width="800" height="835"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Transit Gateway
&lt;/h3&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%2F6yc5hz6wi6yylky0wd9n.jpg" 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%2F6yc5hz6wi6yylky0wd9n.jpg" alt="Transit Gateway" width="800" height="835"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Cloudfront - OAC
&lt;/h3&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%2F3vpon37thqefrpuhu9f9.jpg" 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%2F3vpon37thqefrpuhu9f9.jpg" alt="Cloudfront - OAC" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Config
&lt;/h3&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%2Fyhwaqua5spp8bl15y6ld.jpg" 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%2Fyhwaqua5spp8bl15y6ld.jpg" alt="Config" width="800" height="468"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Temas que son claves conocer para el examen&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Las preguntas de examen se centran en la resolución de problemas con menos carga operativa  y  la elección de arquitecturas más lógica.&lt;/p&gt;

&lt;h3&gt;
  
  
  CloudWatch
&lt;/h3&gt;

&lt;p&gt;Familiarizarse con las features de la consola de CloudWatch porque vas a enfrentarte a varias preguntas sobre la administración de logs.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Cómo visualizó los logs comunes? &lt;em&gt;**CloudWatch &amp;gt; Logs &amp;gt; Log Management&lt;/em&gt;&lt;em&gt;. Aquí se encuentran todos los "Logs Groups" como aws/lambda/..., aws/apigateway/...,ecs/..., ec2..&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;Cómo creo un Log Group? Desde la CLI de AWS. Cómo inserto Log en CloudWatch? Desde la Api con Create
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;CloudWatch metrics&lt;/strong&gt;, tener en claro las diferentes tipos y circunstancias a utilizar. Cada métrica tiene un nombre, namespace y dimensiones (opcional).

&lt;ul&gt;
&lt;li&gt;Basic Monitoring (5 min, default).
&lt;/li&gt;
&lt;li&gt;Detailed Monitoring (1 min, se habilita manualmente)
&lt;/li&gt;
&lt;li&gt;High Resolution para métricas custom (hasta 1 segundo).
&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Metric Filters&lt;/strong&gt; ➡ Definís un patrón de búsqueda sobre un Log Group y CloudWatch genera una métrica custom a partir de las coincidencias.

&lt;ul&gt;
&lt;li&gt;El caso de uso típico a resolver: detectar cantidad de errores 500 en logs de una aplicación. Metric Filter sobre el Log Group (métrica custom) → alarma de CloudWatch sobre esa métrica y acción de remediación automática.
&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;CloudWatch Agent&lt;/strong&gt; ➡ es uno de las features más importantes que nos va a permitir enviar Logs a CloudWatch desde las instancias de EC2, server onprem, EKS cluster (recopilar métricas y registros a nivel de nodo de los contenedores).

&lt;ul&gt;
&lt;li&gt;Comprender cómo se configura y se modifica el archivo de configuración del agente (sin reiniciar las instancias de EC2): &lt;strong&gt;amazon-cloudwatch-agent-ctl command with the fetch-config&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;CloudWatch Logs Insights:&lt;/strong&gt; sintaxis y comandos para el análisis de logs ➡ &lt;code&gt;fields&lt;/code&gt; , &lt;code&gt;display&lt;/code&gt; , &lt;code&gt;filter&lt;/code&gt; , &lt;code&gt;stats&lt;/code&gt; , &lt;code&gt;sort&lt;/code&gt; , &lt;code&gt;limit&lt;/code&gt; ...&lt;/li&gt;

&lt;/ul&gt;

&lt;h3&gt;
  
  
  Escalabilidad y Elasticidad
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Administración de Fleet de EC2:  Estrategias para continuar procesamiento de trabajos minimizando las interrupciones de form costo-efectiva ➡ &lt;strong&gt;capacity-optimized&lt;/strong&gt; para minimizar interrupciones o &lt;strong&gt;price-capacity-optimized&lt;/strong&gt; para balance entre costo y disponibilidad. (Combinando instancias Spot y On-Demand con el parámetro  &lt;code&gt;OnDemandBaseCapacity&lt;/code&gt; se especifica cuántas instancias base On-Demand y el resto se cubre con Spot).
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;EC2 Auto Scaling Group:&lt;/strong&gt; puede aparecer pregunta puntual sobre administrar ASG, pero por lo general no aparece como concepto aislado sino asociado a un balanceador de carga (&lt;strong&gt;ALB/NLB&lt;/strong&gt;) y en arquitecturas multi-región con &lt;strong&gt;Route 53&lt;/strong&gt;.

&lt;ul&gt;
&lt;li&gt;Capacidad mínima, máxima y deseada.
&lt;/li&gt;
&lt;li&gt;Definición de Launch template, cómo aplicar una nueva configuración a todas las instancias del ASG sin &lt;em&gt;downtime&lt;/em&gt;? ➡ Cuando se actualiza un Launch Template, las instancias existentes &lt;strong&gt;no se reemplazan automáticamente,&lt;/strong&gt; siguen ejecutando la versión anterior. Las nuevas instancias que escalen usarán la versión nueva. Para forzar el reemplazo se usa &lt;strong&gt;Instance Refresh&lt;/strong&gt;.
&lt;/li&gt;
&lt;li&gt;Distribución en AZ.
&lt;/li&gt;
&lt;li&gt;Health Checks de EC2 o si health checks desde un ELB  determina que las instancias que no están en buen estado se reemplazan automáticamente. &lt;strong&gt;Profundizar en este punto&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Es clave entender las siguientes políticas de escalamiento para responder sobre mejora de performance. &lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Tipo de Política&lt;/th&gt;
&lt;th&gt;Cómo Funciona&lt;/th&gt;
&lt;th&gt;Caso de Uso&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Target Tracking&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Mantiene una métrica en un valor objetivo (ej: CPU al 50%). AWS gestiona las alarmas de CloudWatch automáticamente.&lt;/td&gt;
&lt;td&gt;Aplicaciones web generales donde querés simplicidad sin configuración compleja.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Step Scaling&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Ajusta la capacidad en pasos según cuánto se desvía una métrica del umbral. Permite diferentes tamaños de paso según la magnitud.&lt;/td&gt;
&lt;td&gt;Workloads con picos abruptos donde necesitás agregar más instancias cuanto mayor es el desvío.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Simple Scaling&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Agrega o quita una cantidad fija de instancias cuando se dispara una alarma. Incluye período de cooldown antes de la siguiente acción.&lt;/td&gt;
&lt;td&gt;Legacy, no recomendada. Target Tracking la reemplaza en casi todos los casos.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Scheduled Scaling&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Escala la capacidad en un horario específico usando expresiones cron.&lt;/td&gt;
&lt;td&gt;Cargas predecibles: horario comercial, cierre de mes, campañas programadas.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Predictive Scaling&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Usa ML para predecir la carga futura y ajusta la capacidad de forma proactiva.&lt;/td&gt;
&lt;td&gt;E-commerce con patrones cíclicos (ej: picos semanales o estacionales recurrentes).&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;LifeCycle Hooks:&lt;/strong&gt; En Auto Scaling Group para analizar errores de las instancias antes de que se finalicen para ser reemplazadas se puede pausar la finalización de la instancia. También, este mecanismo, al inicio permite acciones como instalación de software. La instancia permanece en estado Pendiente
&lt;/li&gt;
&lt;li&gt;Conocer el término &lt;strong&gt;Warmup,&lt;/strong&gt; define un tiempo de calentamiento de la instancia. Es el período posterior al lanzamiento de una nueva instancia antes de que sus métricas contribuyan a la métrica de escalado. Evita el escalado por falsas métricas hasta que la instancia se estabilice.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Application AutoScaling (no confundir con ASG):&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;ECS, cantidad de task.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Lambda&lt;/strong&gt;. Entender la diferencia entre Provisioned Concurrency y Reserved Concurrency. La primera es la que permite "autoescalar" ➡ muy probable que te planteen una situación con Lambda para resolver temas de concurrencia.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Aurora réplicas&lt;/strong&gt;. Permite liberar la instancia del cluster, teniendo réplicas de lectura (no de escrituras).
&lt;/li&gt;
&lt;li&gt;DynamoDB, puede crear una política de AutoScaling. Luego DynamoDB pública métricas de capacidad consumida CloudWatch ➡ La alarma de CloudWatch invoca a AutoScaling de aplicaciones para evaluar la política de escalado, emite una solicitud &lt;code&gt;UpdateTable&lt;/code&gt; para ajustar el rendimiento aprovisionado de la tabla.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;h3&gt;
  
  
  ELB - High availability
&lt;/h3&gt;

&lt;p&gt;Con el siguiente cuadro podés responder varios casos de uso:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Load Balancer&lt;/th&gt;
&lt;th&gt;Capa&lt;/th&gt;
&lt;th&gt;Protocolos&lt;/th&gt;
&lt;th&gt;Características Clave&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Application Load Balancer (ALB)&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Layer 7 (HTTP/HTTPS)&lt;/td&gt;
&lt;td&gt;HTTP, HTTPS, gRPC, WebSocket&lt;/td&gt;
&lt;td&gt;Enrutamiento basado en contenido (path, host, headers, query strings), targets Lambda, integración con WAF, sticky sessions.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Network Load Balancer (NLB)&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Layer 4 (TCP/UDP)&lt;/td&gt;
&lt;td&gt;TCP, UDP, TLS&lt;/td&gt;
&lt;td&gt;Ultra-baja latencia, IP estática por AZ, soporte Elastic IP, preserva la IP de origen, maneja millones de requests/segundo.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Gateway Load Balancer (GWLB)&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Layer 3 (IP)&lt;/td&gt;
&lt;td&gt;IP&lt;/td&gt;
&lt;td&gt;Despliega, escala y gestiona appliances virtuales de terceros (firewalls, IDS/IPS). Usa protocolo GENEVE.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Classic Load Balancer (CLB)&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Layer 4 y 7&lt;/td&gt;
&lt;td&gt;HTTP, HTTPS, TCP, SSL&lt;/td&gt;
&lt;td&gt;Legacy; no recomendado para nuevos despliegues.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;ul&gt;
&lt;li&gt;Dónde encontrar información detallada como la &lt;strong&gt;dirección IP del cliente, latencias, rutas de solicitud y respuestas del servidor? ➡&lt;/strong&gt; La respuesta es habilitar los &lt;strong&gt;ELB Access Logs&lt;/strong&gt; y almacenarlos en un bucket de S3.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Problemas de conectividad.&lt;/strong&gt; Una web inalcanzable con grupos de seguridad correctos ➡ La solución es &lt;strong&gt;permitir puertos efímeros (1024-65535)&lt;/strong&gt; en la &lt;strong&gt;Network ACL (NACL)&lt;/strong&gt;, porque ELB utiliza este rango para comunicarse con los clientes.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Sticky Sessions:&lt;/strong&gt; Caso de uso donde una sola instancia EC2 tiene un uso de CPU del 95% mientras las otras están al 10% ➡ ajustar la expiración de las &lt;strong&gt;cookies de la aplicación&lt;/strong&gt; para rebalancear la carga.
&lt;/li&gt;
&lt;li&gt;Conocer &lt;strong&gt;Cross-Zone Load Balancing p&lt;/strong&gt;ara asegurar una distribución uniforme del tráfico en todas las zonas de disponibilidad habilitadas.
&lt;/li&gt;
&lt;li&gt;Integración de ALB con WAF pero no así con NLB.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Placement Group&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Cluster:&lt;/strong&gt; Agrupa las instancias muy cerca unas de otras en &lt;strong&gt;una única zona de disponibilidad&lt;/strong&gt;. Proporciona una red de baja latencia y alto ancho de banda (hasta 100 Gbps con EFA). &lt;strong&gt;Casos de uso ➡ HPC, Machine Learning,&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Partition:&lt;/strong&gt; Divide las instancias en particiones lógicas, cada una en racks separados con alimentación y red independientes. Hasta 7 particiones por zona de disponibilidad. Caso de uso ➡ base de datos Distribuidas: Cassandra,HDFS, Kafka&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Spread:&lt;/strong&gt; Cada instancia se ubica en un hardware distinto (racks separados). Máximo 7 instancias por zona de disponibilidad por grupo. Caso de Uso ➡ grupos de instancias  que deben aislarse entre sí en hardware separado.&lt;/p&gt;

&lt;h3&gt;
  
  
  Estrategias de Disaster Recovery
&lt;/h3&gt;

&lt;p&gt;Conceptos principales RTO (Recovery Time Objective), RPO (Recovery Point Objective) ➡ mientras mas pequeños mas costosos. &lt;a href="https://docs.aws.amazon.com/whitepapers/latest/disaster-recovery-workloads-on-aws/disaster-recovery-options-in-the-cloud.html" rel="noopener noreferrer"&gt;&lt;strong&gt;Este enlace&lt;/strong&gt;&lt;/a&gt; tiene información detallada que vale la pena revisar de las siguientes estrategias:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Estrategia&lt;/th&gt;
&lt;th&gt;RTO&lt;/th&gt;
&lt;th&gt;RPO&lt;/th&gt;
&lt;th&gt;Costo&lt;/th&gt;
&lt;th&gt;Caso de Uso&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Backup and Restore&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Horas&lt;/td&gt;
&lt;td&gt;Horas&lt;/td&gt;
&lt;td&gt;$&lt;/td&gt;
&lt;td&gt;Dev/test, no-crítico&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Pilot Light&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Varios minutos&lt;/td&gt;
&lt;td&gt;Minutos&lt;/td&gt;
&lt;td&gt;$$&lt;/td&gt;
&lt;td&gt;Apps internas, criticidad moderada&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Warm Standby&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Minutos&lt;/td&gt;
&lt;td&gt;Segundos–minutos&lt;/td&gt;
&lt;td&gt;$$$&lt;/td&gt;
&lt;td&gt;Apps de negocio críticas&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Multi-Site Active/Active&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Segundos&lt;/td&gt;
&lt;td&gt;Segundos&lt;/td&gt;
&lt;td&gt;$$$$&lt;/td&gt;
&lt;td&gt;Crítico, zero-downtime&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Clases de S3 -  Versiones - Eventos
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Hacer un pequeño cuadro comparativo de versiones de S3 y que casos de uso se utiliza para cada uno. Ejemplo ➡ cuando los patrones de acceso son &lt;strong&gt;impredecibles o cambiantes&lt;/strong&gt; y no querés gestionar manualmente las políticas de ciclo de vida: S3 Intelligent-Tiering
&lt;/li&gt;
&lt;li&gt;S3 Object Lock ➡ cuando se usa Governance mode o Compliance mode.
&lt;/li&gt;
&lt;li&gt;Activación de versionado. Relación con CRR (&lt;em&gt;Cross Region Replication&lt;/em&gt;) y SRR (replicación en misma región pero diferentes cuentas).

&lt;ul&gt;
&lt;li&gt;Resolución de problemas de &lt;strong&gt;latencia o errores&lt;/strong&gt; cuando el S3 es origen de CloudFront: Si hay millones de versiones y las operaciones de listado o ciclo de vida se vuelven pesadas ➡ Configurar &lt;strong&gt;S3 Lifecycle Policies&lt;/strong&gt; para expirar versiones antiguas automáticamente, usando &lt;code&gt;NoncurrentVersionExpiration&lt;/code&gt; para eliminar versiones no actuales después de cierta cantidad de días.
&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;em&gt;Event notifications&lt;/em&gt; para creación, eliminación, update de objetos. Integración con Lambda, SNS y Eventbridge. &lt;strong&gt;EventBridge&lt;/strong&gt; permite filtrar eventos por prefijo, sufijo, tamaño, etc. y enrutarlos a más de 20 destinos distintos.
&lt;/li&gt;

&lt;li&gt;Conocer las políticas de bucket para responder preguntas sobre que habilita o deniega una policy. Su alcance. Entender que un &lt;strong&gt;Deny explícito siempre gana&lt;/strong&gt;, incluso si hay un Allow en otra política.&lt;/li&gt;

&lt;/ul&gt;

&lt;h3&gt;
  
  
  ElastiCache
&lt;/h3&gt;

&lt;p&gt;Conocer las llamadas básicas de la API es básico ➡ saber como crear un cluster &lt;em&gt;CreateCacheCluster&lt;/em&gt;, parámetros importantes como &lt;em&gt;CacheNodeType&lt;/em&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;ElastiCache - Memcached&lt;/strong&gt;:  caso de uso que recibe alertas relacionadas con un alto uso de CPU en un clúster de Amazon ElastiCache Memcached, cómo solucionarlo? ➡ Agregar nodos adicionales proporcionará mayor capacidad al clúster o bien según la versión de Memcached se puede escalar verticalmente cambiando el tipo de nodo sin necesidad de crear un nuevo cluster. &lt;strong&gt;No tiene replicación, ni persistencia.&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;ElastiCache - Redis:&lt;/strong&gt; El concepto más importante de esta opción es permitir &lt;strong&gt;Alta Disponibilidad&lt;/strong&gt; a través de sus réplicas: &lt;strong&gt;Multi-AZ con failover automático&lt;/strong&gt;. División en sharding. Compatible con PUB/SUB. Adecuado para conservar sesiones. El soporte más común a resolver por performance es cambiar el tipo de nodo.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  SSM (Simple Service Manager)
&lt;/h3&gt;

&lt;p&gt;Si no trabajas todos los días con este servicio, es necesario que no solo estudies teoría en cuanto a sus features, sino que también hagas laboratorios.&lt;/p&gt;

&lt;p&gt;Las preguntas que aparecen en el examen son muy variadas en cuanto a la administración de EC2, aplicación de parches, auto aprobaciones de releases y algunas que involucran webhooks con github.&lt;/p&gt;

&lt;p&gt;Recomiendo mirar la sintaxis de los documentos en JSON o Yaml que definen acciones y flujos de trabajo automatizados ➡ hay preguntas sencillas sobre este punto en el examen.&lt;/p&gt;

&lt;p&gt;Enumero algunas situaciones o casos de uso:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Un concepto sencillo útil: todas las ejecuciones se puede trackear su estatus y log de salidas desde la consola de &lt;em&gt;System Manager&lt;/em&gt;.
&lt;/li&gt;
&lt;li&gt;Se quiere automatizar la creación de Amazon Machine Images (AMIs) personalizadas. Se detecta errores timeout sobre el pipeline de EC2 Image Builder ➡ El agente de AWS Systems Manager (agente SSM) en la instancia de compilación no se está ejecutando o no está accesible.
&lt;/li&gt;
&lt;li&gt;¿Cómo dividimos los parches entre servidores de diferentes cuentas/entornos y SO? ➡ La solución combina &lt;strong&gt;Patch Baselines&lt;/strong&gt; (definen qué parches aplicar, con aprobaciones automáticas y listas de rechazo, por SO) + &lt;strong&gt;Patch Groups&lt;/strong&gt; (agrupan nodos mediante tags y los asocian a una Baseline específica).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Runbook&lt;/strong&gt;: Tipo específico de documento de Systems Manager (SSM) que define las acciones exactas que realiza el servicio Automation. Define yaml o json para orquestar un workflow de ejecución.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt; Por lo general, se usa para la remediación asociado con &lt;em&gt;AWS Config.&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;Usando AWS Organizations se necesita automatizar el proceso de stopping de instancias EC2 no productivas fuera del horario de negocio de todos las cuentas miembro ➡ Crear roles de IAM en cada cuenta con los permisos adecuados, utilizar Systems Manager Automation con una cuenta de administrador delegado para ejecutar un runbook que dirija los recursos de toda la organización según los tags.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Patch Policies:&lt;/strong&gt; se utiliza para Organizations. Tener en claro que centraliza el control para definir patching schedules y baselines para múltiples cuentas y regiones
&lt;/li&gt;
&lt;li&gt;Revisar los documentos de ejecuciones más importantes en SSM.
&lt;/li&gt;
&lt;li&gt;Integraciones por eventos externos, tener claro cómo trabaja en los diferentes casos webhooks (con avisos de software de terceros). Que flujos podemos tener:

&lt;ul&gt;
&lt;li&gt;Webhook → API GW → Lambda → SSM
&lt;/li&gt;
&lt;li&gt;GitHub Actions → SSM (puedes filtrar exactamente por eventos RELEASED o PRERELEASED).
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Amazon EventBridge Partner Events → GitHub&lt;/strong&gt; como fuente nativa de eventos → SSM Automation o Lambda como destino.
&lt;/li&gt;
&lt;li&gt;EventBridge Scheduler → Lambda consulta GitHub API → escribe versión en SSM Parameter Store (como fuente de verdad para actualizaciones)
&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;AWS RunRemoteScript: Documento SSM que permite ejecutar scripts alojados en S3 o GitHub directamente en los nodos, sin necesidad de copiarlos previamente.&lt;/li&gt;

&lt;/ul&gt;

&lt;h3&gt;
  
  
  Servicios y estrategias de Deployment
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Casos de uso de AWS Code Pipeline, y los otros servicios que involucra ➡ Code Commit o GitHUb, Code Build, Code Deploy o CloudFormation. Entender donde se integran los test y tener en cuenta que se puede agregar una &lt;strong&gt;aprobación&lt;/strong&gt; vía sns antes de realizar deploy.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;CodePipeline&lt;/strong&gt; puede implementar CloudFormation StackSets, lo que permite implementaciones en múltiples cuentas y regiones como parte de una canalización de CI/CD.
&lt;/li&gt;
&lt;li&gt;Estrategias de deployment:

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;In-place (All-at-once):&lt;/strong&gt; Implementa en todas las instancias simultáneamente. Downtime Posible. Es Lento (redeploy versión antigua). Se usa en entornos de desarrollo, cuando el downtime es aceptable
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Rolling:&lt;/strong&gt; Reemplazar instancias en lotes. Downtime Mínimo. Se usa cuando querés ahorrar costos sin aprovisionar nueva infraestructura.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Rolling with additional batch:&lt;/strong&gt; Agrega nuevas instancias antes de eliminar las antiguas. Downtime mejor que el anterior. Se usa cuando necesitas mantener capacidad completa durante el deploy
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Immutable:&lt;/strong&gt; Inicia instancias completamente nuevas; intercambia cuando estén en buen estado. Se usa en producción donde el rollback rápido es crítico.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Blue/Green:&lt;/strong&gt; Ejecuta dos entornos idénticos; cambia el tráfico. Downtime mínimo.  Se usa cuando necesitás rollback instantáneo y podés asumir el costo de doble infraestructura.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Canary:&lt;/strong&gt; Desvía primero un pequeño % del tráfico; lo va ampliando si todo está OK. Es rápido. Se usa para validar un release con un subconjunto de usuarios antes de rollout completo.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;h3&gt;
  
  
  Cloudformation
&lt;/h3&gt;

&lt;p&gt;Es un servicio fundamental en el examen. Conocer las secciones principales de la plantilla (JSON o YAmL) : Metadata, Parameters, Mappings (caso de uso de parametrización de Amazon Machine Images (AMIs) ), Conditions, Transform (SAM), Resources.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Una buena práctica para familiarizarse con la sintaxis de los templates es construir arquitecturas clásicas que utilicen EC2, ASG, ALB, RDS con Secret Manager, entre otras.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Comandos CLI importantes:&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;aws cloudformation create-stack&lt;/code&gt; ➡ crea un stack nuevo
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;aws cloudformation deploy&lt;/code&gt; ➡ crea o actualiza un stack usando un template empaquetado (más usado en CI/CD)
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;aws cloudformation detect-drift&lt;/code&gt; ➡ inicia la detección de drift en un stack
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;aws cloudformation describe-stack-drift-detection-status&lt;/code&gt; ➡ consulta el resultado de la detección
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;aws cloudformation cancel-update-stack&lt;/code&gt; ➡ cancela una actualización en curso
&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;StackSet&lt;/strong&gt; ➡ caso de uso importante de cuentas asociadas en Organizations. Gestiona de manera  centralizada para implementar cambios en las stack en varias cuentas. Se puede usar StackSets para crear, actualizar o eliminar stacks en varias cuentas y regiones de AWS con una sola operación.
&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Intrinsic functions:&lt;/strong&gt; comandos que se utilizan dentro de las plantillas para asignar valores a propiedades que no están disponibles hasta el momento de la implementación (en tiempo de ejecución) ➡ revisar implementaciones de las mas importantes: &lt;code&gt;Ref&lt;/code&gt; &lt;strong&gt;,&lt;/strong&gt; &lt;code&gt;Fn::GetAtt&lt;/code&gt;&lt;strong&gt;,&lt;/strong&gt; &lt;code&gt;Fn::ImportValue&lt;/code&gt;&lt;strong&gt;,&lt;/strong&gt; &lt;code&gt;Fn::FindInMap&lt;/code&gt;&lt;strong&gt;,&lt;/strong&gt; &lt;code&gt;Fn::ForEach&lt;/code&gt;&lt;strong&gt;,&lt;/strong&gt; &lt;code&gt;Fn::Transform ...&lt;/code&gt;
&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;NestedStack:&lt;/strong&gt; &lt;code&gt;AWS::CloudFormation::Stack&lt;/code&gt; &lt;strong&gt;➡ mecanismo&lt;/strong&gt; para crear infraestructura &lt;strong&gt;modular, reutilizable y gestionable&lt;/strong&gt; mediante la integración de una pila dentro de otra. En lugar de crear una plantilla única y masiva que resulta difícil de mantener, se puede dividir la arquitectura en componentes lógicos (por ejemplo, VPC, base de datos, capa de aplicación) y referenciarlos como pilas separadas dentro de una plantilla "raíz" o "padre".
&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Mecanismos de protección en CloudFormation:&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Stack Policy:&lt;/strong&gt; documento JSON que restringe qué recursos pueden ser actualizados. Ideal para proteger RDS de producción de cambios accidentales.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Termination Protection:&lt;/strong&gt; protección a nivel stack contra eliminación accidental. Se hereda a los nested stacks.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;DeletionPolicy:&lt;/strong&gt; &lt;code&gt;Retain&lt;/code&gt; conserva el recurso, &lt;code&gt;Snapshot&lt;/code&gt; genera snapshot antes de eliminar (soportado en RDS, EBS). La situación típica que se plantea, como conservar una RDS si se elimina el stack de cloudformation?
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;UpdateReplacePolicy:&lt;/strong&gt; igual que DeletionPolicy pero aplica cuando un update requiere reemplazar el recurso físico.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Drift Detection:&lt;/strong&gt; detecta recursos cuya configuración real difiere del template, útil para identificar cambios manuales que bypasearon el pipeline.
&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;Profundizar en los Script Auxiliares más importantes, mecanismos para sincronizar la creación o actualización de recursos, para que el stack espere hasta que la configuración esté lista antes de continuar.

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;cfn-init&lt;/code&gt; → lee y ejecuta la sección &lt;code&gt;AWS::CloudFormation::Init&lt;/code&gt; del template (instala paquetes, archivos, servicios). Se ejecuta durante el User Data.
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;cfn-signal&lt;/code&gt; ➡ Generalmente se implementa al final de un script de &lt;em&gt;User Data&lt;/em&gt;. Un patrón común es ejecutarlo después de &lt;code&gt;cfn-init&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Tener en cuenta los atributos que requieren señales como &lt;strong&gt;CreationPolicy&lt;/strong&gt; (puede estar asociados con &lt;code&gt;AWS::EC2::Instance&lt;/code&gt; o &lt;code&gt;AWS::AutoScaling::AutoScalingGroup&lt;/code&gt; ) y los tipos de &lt;a href="https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-attribute-updatepolicy.html" rel="noopener noreferrer"&gt;&lt;strong&gt;UpdatePolicy&lt;/strong&gt;&lt;/a&gt; &lt;strong&gt;(con WaitOnResourceSignals).&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;CloudFormation Traffic Shifting&lt;/strong&gt;  ➡ se implementa definiendo &lt;code&gt;DeploymentPreference&lt;/code&gt; en el template. CodeDeploy ejecuta el shifting según la estrategia elegida (Canary, Linear, AllAtOnce).&lt;/li&gt;

&lt;/ul&gt;

&lt;h3&gt;
  
  
  Storage
&lt;/h3&gt;

&lt;p&gt;Evaluar y seleccionar que tipo de Storage es adecuado a un caso de uso. Si estudiaste para la certificación de SAA son preguntas similares.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Storage en entornos híbridos ➡ &lt;strong&gt;Storage Gateway&lt;/strong&gt; y todas sus variantes

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;S3 File Gateway:&lt;/strong&gt; Acceso NFS/SMB a objetos en S3. Los archivos se almacenan como objetos nativos. Caso de uso: migración de archivos on-premise a S3.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Volume Gateway:&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Cached mode:&lt;/em&gt; datos principales en S3, caché local de los más accedidos.
&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Stored mode:&lt;/em&gt; datos principales on-premise, backup asíncrono a S3 como EBS snapshots.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Tape Gateway:&lt;/strong&gt; Reemplaza cintas físicas. Importante es que se expande automáticamente, esta última característica puede ser un caso de uso que aparezca en el examen.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;FSx File Gateway:&lt;/strong&gt; Caché local de FSx for Windows File Server para acceso de baja latencia desde on-premise.
&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;FSx for Windows FileServer y su otras variantes, cuando usarlo?

&lt;ul&gt;
&lt;li&gt;Es MultiAZ, es una feature importante.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Shadow Copies:&lt;/strong&gt; los usuarios finales puedan ver y restaurar por sí mismos versiones anteriores de archivos o carpetas individuales sin depender de otro mecanismo.
&lt;/li&gt;
&lt;li&gt;Usado con Windows SMB, Active Directory.
&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;FSx for Lustre ➡ HPC, ML, high throughput
&lt;/li&gt;

&lt;li&gt;EFS (Elastic File System) comprender el caso de uso que puede compartir storage entre varias EC2, Linux NFS.

&lt;ul&gt;
&lt;li&gt;Multi-AZ
&lt;/li&gt;
&lt;li&gt;Performance modes: general Purpose y MaxIO
&lt;/li&gt;
&lt;li&gt;Throughput Modes: Elastic (recomendado), Provisioned, Bursting.
&lt;/li&gt;
&lt;li&gt;Conocer qué EFS tiene Storage Class y  Lifecycle Policies ➡ aunque suele no aparecer en el examen.
&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;EBS&lt;/strong&gt; ➡ siempre en el contexto de EC2 y la elección del disco para optimizar las cargas de trabajo: &lt;strong&gt;gp3&lt;/strong&gt; sobre gp2 sin incrementar los costos, &lt;strong&gt;gp3&lt;/strong&gt; permite configurar IOPS y throughput &lt;strong&gt;independientemente&lt;/strong&gt; del tamaño del volumen. Para transacciones, persistencia y durabilidad es &lt;strong&gt;io2&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Amazon Data Lifecycle Manager (DLM)&lt;/strong&gt;: Automatiza la creación, retención y eliminación de instantáneas de EBS y AMI respaldadas por EBS mediante políticas de ciclo de vida.
&lt;/li&gt;
&lt;li&gt;EBS Snapshot: Una copia de seguridad puntual de un volumen EBS almacenado en S3 (gestionado por AWS). Los snapshot son incrementales.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;h3&gt;
  
  
  RDS y Aurora
&lt;/h3&gt;

&lt;p&gt;Los accesos se deben guardar en Secrets Manager y luego las aplicaciones acceden a eso. Característica importante &lt;em&gt;Cross-Region backup replication.&lt;/em&gt; Tanto RDS como Aurora tienen PITR (Point-in-Time Restore).&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;RDS Multi-AZ&lt;/strong&gt; ➡ standby síncrono en otra AZ, failover automático pero más lento &lt;em&gt;que Aurora.&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;Se puede asociar con el servicio &lt;strong&gt;RDS Proxy&lt;/strong&gt; para el manejo de conexiones.
&lt;/li&gt;
&lt;li&gt;Aurora ➡  Almacenamiento distribuido que se replica automáticamente en 3 AZs, hasta 15 réplicas de lectura, failover automático en segundos.
&lt;/li&gt;
&lt;li&gt;Aurora Serverless v2 ➡ la característica importante es que escala a "cero" y no genera costo.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  DynamoDB
&lt;/h3&gt;

&lt;p&gt;Las preguntas se centran en resolver problemas de performance; cómo volver a un recovery point. Ejemplo:  La tabla experimenta picos de tráfico incrementales durante el horario laboral, con patrones predecibles, cuando se producen millones de lecturas y escrituras. Hay que configurar una solución para aumentar la capacidad de procesamiento ➡ Habilitar el escalado automático en la tabla de DynamoDB. Configurar una política de escalado automático para ajustar el tamaño en función de las unidades de capacidad de lectura y escritura.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Point-in-Time Recovery (PITR) ➡&lt;/strong&gt; backup continuo, permite restaurar a cualquier &lt;strong&gt;segundo&lt;/strong&gt; de los últimos 35 días.
&lt;/li&gt;
&lt;li&gt;Para esto debemos conocer los tipos de Lectura &lt;em&gt;Eventually Consistent Read&lt;/em&gt; (por defecto) y &lt;em&gt;Strongly Consistent Read&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;Los diferentes modos de capacidad &lt;em&gt;On-Demand y Provisioned&lt;/em&gt; &lt;strong&gt;(profundizar en estos dos conceptos).&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;DynamoDB Global Tables&lt;/strong&gt; &lt;em&gt;➡&lt;/em&gt; replicación multirregional y multiactiva. Cada región puede aceptar lecturas y escrituras, y los cambios se replican de forma asíncrona. Esto permite la escalabilidad global y la recuperación ante desastres.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Encriptación en reposo, tránsito y uso de KMS
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Encriptación con S3 de KMS: &lt;strong&gt;SSE-S3&lt;/strong&gt; (clave gestionada por AWS), &lt;strong&gt;SSE-KMS&lt;/strong&gt; (usás una KMS key propia, permite auditoría via CloudTrail y control de acceso granular) y &lt;strong&gt;SSE-C&lt;/strong&gt; (el cliente provee la clave, AWS no la almacena). Si la pregunta menciona &lt;strong&gt;auditoría de uso de claves o control granular&lt;/strong&gt; ➡ SSE-KMS.
&lt;/li&gt;
&lt;li&gt;Clave simetrica y asimetrica son básicos. Aunque en el examen no hay preguntas profundas sobre este punto.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Key Policies:&lt;/strong&gt; Cada clave KMS tiene una política de claves. Una política basada en recursos que controla quién puede usar y administrar la clave. A diferencia de las políticas de IAM, la política de claves es el principal mecanismo de control de acceso para las claves KMS.
&lt;/li&gt;
&lt;li&gt;Rotación de Key, hay 3 variantes:

&lt;ul&gt;
&lt;li&gt;automática, para customer managed keys puede habilitar la rotación automática
&lt;/li&gt;
&lt;li&gt;manual u On-demand por medio de trigger.
&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;Importación de material de clave de un cliente en KMS, pero no rota automáticamente.
&lt;/li&gt;

&lt;li&gt;Replicación AWS KMS Multi-Region Keys: Una clave KMS que existe en una región diferente, pero comparte el mismo ID de clave y material de clave que su clave principal.&lt;/li&gt;

&lt;/ul&gt;

&lt;h3&gt;
  
  
  AWS Certificate Manager (ACM)
&lt;/h3&gt;

&lt;p&gt;Las preguntas son sencillas, si se habla que servicio proporciona  certificados SSL/TLS la respuesta es  ACM.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Revisar los casos de uso de como integrar ACM con ELB, CloudFront, ApiGateway, Elastic Beanstalk, Cognito.
&lt;/li&gt;
&lt;li&gt;Tipos de certificados ➡ públicos, privados e importación de terceros. Identificar los casos de uso para poder resolver situaciones.
&lt;/li&gt;
&lt;li&gt;Mecanismo de renovación e importación de certificados de terceros.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Seguridad IAM
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Pensar que todo servicio para ejecutar algo debe tener un rol de IAM asociado. En ciertas ocasiones para permitir que usuarios utilicen servicios o listen ciertas features de manera temporal podemos agregar inline policies y luego eliminarlas.
&lt;/li&gt;
&lt;li&gt;Casos de uso de &lt;code&gt;iam:PassRole&lt;/code&gt;. Entender por qué es una capa de seguridad importante para proteger el entorno de AWS de actividades no deseadas y de la escalada de privilegios.
&lt;/li&gt;
&lt;li&gt;Caso de uso de credenciales temporales&lt;code&gt;iam:AssumeRole.&lt;/code&gt; Ejemplo ➡ la entidad en la Cuenta A utiliza para ejecutar servicios en la Cuenta B como si fuera un usuario local en esa cuenta.
&lt;/li&gt;
&lt;li&gt;Federación de Identidades: Permite a los usuarios autenticados por un proveedor de identidad externo (IdP) acceder a AWS sin crear usuarios de IAM individuales. Conocer los casos de uso:

&lt;ul&gt;
&lt;li&gt;SAML 2.0: se integra con Microsoft Active Directory Federation Services (ADFS) u Okta. Los usuarios se autentican con sus credenciales corporativas y reciben credenciales temporales de AWS.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;OpenID Connect (OIDC): &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;para aplicaciones web y móviles&lt;/strong&gt;. Admite proveedores de identidad como Google, Facebook o cualquier proveedor compatible con OIDC. Solución de error "Not authorized to perform sts:AssumeRoleWithWebIdentity" ➡ agregar el ARN del proveedor de identidad en el elemento principal de la política de confianza (trust policy).&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  AWS Organizations
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;OU (Organizational Units):&lt;/strong&gt; las cuentas se agrupan en OUs y los SCPs se aplican a nivel OU o cuenta individual, heredando hacia abajo en la jerarquía.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Delegated Administrator:&lt;/strong&gt; permite que una cuenta miembro (no la cuenta de administración) gestione servicios específicos como Security Hub, GuardDuty o Config para toda la organización.
&lt;/li&gt;
&lt;li&gt;Relaciona el concepto de administrar muchas cuentas con &lt;strong&gt;Service control policies&lt;/strong&gt; (SCPs). Recordar que &lt;strong&gt;&lt;em&gt;afectan únicamente a los usuarios y roles de IAM&lt;/em&gt;&lt;/strong&gt; gestionados por las cuentas que forman parte de la organización. SCPs no afectan directamente a las políticas basadas en recursos.
&lt;/li&gt;
&lt;li&gt;Políticas de tagging. Se puede asegurar que los usuarios no puedan crear recursos sin una etiqueta específica.
&lt;/li&gt;
&lt;li&gt;Integración con &lt;strong&gt;&lt;em&gt;CloudFormation StackSet.&lt;/em&gt;&lt;/strong&gt; Definir un StackSet que implementa una plantilla base (almacenada en S3) en toda una Unidad Organizativa (OU) en varias regiones utilizando &lt;em&gt;Service-Managed permission model&lt;/em&gt;.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Consolidated Billing:&lt;/strong&gt; todas las cuentas miembro consolidan el pago en la cuenta de administración, permite aprovechar descuentos por volumen y Reserved Instances compartidas entre cuentas.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;AWS Artifact&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Su caso de uso es acceder &lt;strong&gt;a informes de auditoría.&lt;/strong&gt; Se puede descargar bajo demanda certificaciones de cumplimiento normativo (como SOC 1/2/3, ISO/IEC, y PCI DSS).&lt;/p&gt;




&lt;p&gt;Este apunte continua en &lt;strong&gt;➡&lt;/strong&gt; &lt;a href="https://dev.to/reinalau/apuntes-para-la-certificacion-aws-cloudops-engineer-associate-soa-c03-parte-2-2e04"&gt;&lt;strong&gt;&lt;em&gt;Apuntes para la certificación AWS CloudOps Engineer Associate (SOA-C03) - Parte 2&lt;/em&gt;&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>sysops</category>
      <category>aws</category>
      <category>certification</category>
    </item>
    <item>
      <title>Patrones de acceso seguro a S3 🌐</title>
      <dc:creator>Laura Bolaños</dc:creator>
      <pubDate>Mon, 27 Apr 2026 14:09:23 +0000</pubDate>
      <link>https://dev.to/aws-builders/patrones-de-acceso-seguro-a-s3-l7c</link>
      <guid>https://dev.to/aws-builders/patrones-de-acceso-seguro-a-s3-l7c</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Este análisis se propone clarificar algunos casos de uso donde se requiere servir contenido de S3 de manera segura, identificando las brechas de seguridad a las que debemos enfrentarnos y explorar posibles mejoras. El desafío real no está en analizar cada servicio por separado, sino en combinarlos correctamente.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  1. CloudFront + OAC con presigned url
&lt;/h2&gt;

&lt;p&gt;Caso de uso frecuente: Un sitio web que muestra imágenes/vídeos de una temática determinada. Una parte de los objetos multimedia puede restringirse a que solo lo vean usuarios que iniciaron sesión vía Cognito. Aquí la solución más sencilla:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Upload de Multimedia (escritura)&lt;/strong&gt;&lt;br&gt;
El frontend solicita una Presigned URL a un endpoint protegido por Cognito (una api). La api se integra con una función Lambda que genera una URL temporal (válida por x minutos) firmada con permisos de "s3:PutObject" para el bucket privado de imágenes.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Visualización de Multimedia (lectura)&lt;/strong&gt;&lt;br&gt;
El bucket de S3 tiene el bloqueo de acceso público activado.&lt;br&gt;
Los elementos multimedia se sirven a través de CloudFront, utilizando OAC (Origin Access Control) para firmar internamente la petición (usando el protocolo SigV4) y solicitar el objeto a S3 de forma segura.&lt;br&gt;
La política (Bucket Policy) del bucket S3 solo permite la acción "s3:GetObject" si la petición proviene específicamente del ARN de la distribución de CloudFront ("Condition: AWS:SourceArn").&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%2Fx0j2r3afdmhfgjhewpj5.jpg" 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%2Fx0j2r3afdmhfgjhewpj5.jpg" alt="CloudFront + OAC con presigned url" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Conceptualmente una &lt;strong&gt;Presigned URL&lt;/strong&gt; se puede utilizar tanto para cargar como para leer objetos, en el ejemplo anterior notar que solo se usa para cargar los objetos a S3*.* Una presigned URL es simplemente una URL con la firma embebida ➡ cualquiera que la tenga puede usarla hasta que expire, sin autenticación. Por eso debemos aplicar diferentes técnicas de seguridad.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;La url puede tener una duración desde 1 minuto hasta 12 horas, si alguien no autorizado consigue la url y ya caduco ➡ NO la puede utilizar.&lt;/li&gt;
&lt;li&gt;Con el uso de Cognito, el token JWT tiene una duración y se puede aplicar este control con &lt;strong&gt;Cognito JWT Authorizer&lt;/strong&gt; (nativo de API Gateway). La otra posibilidad es tener Lambda Authorizer en API Gateway. Esta última tiene lógica de autorización custom.&lt;/li&gt;
&lt;li&gt;Cuando generamos una presigned url para upload, se puede controlar que tipos de objetos cargar y su peso máximo. Algunos ejemplos:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# Generate presigned URL for PUT
# ContentType specifies the types of objects and controls their size on the frontend
&lt;/span&gt;&lt;span class="n"&gt;upload_url&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;s3_client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;generate_presigned_url&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;put_object&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;Params&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Bucket&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;      &lt;span class="n"&gt;IMAGES_BUCKET&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Key&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;         &lt;span class="n"&gt;imagen_key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;ContentType&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;expected_content_type&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="p"&gt;},&lt;/span&gt;
            &lt;span class="n"&gt;ExpiresIn&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;PRESIGNED_URL_TTL&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;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# the frontend makes a multipart POST request
&lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;s3_client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;generate_presigned_post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;Bucket&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;IMAGES_BUCKET&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;Key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;imagen_key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;Fields&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Content-Type&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;expected_content_type&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="n"&gt;Conditions&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Content-Type&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;expected_content_type&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;content-length-range&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;5242880&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;  &lt;span class="c1"&gt;# máx 5MB
&lt;/span&gt;    &lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="n"&gt;ExpiresIn&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;PRESIGNED_URL_TTL&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;
  
  
  1.2 Caso de uso complementario - Validación de acceso en el edge (Lambda@Edge)
&lt;/h3&gt;

&lt;p&gt;Podemos enfrentarnos a dos requerimientos no funcionales: minimizar la latencia y asegurar quién puede hacer request a Cloudfront.&lt;br&gt;
El caso anterior asegura que solo CloudFront puede acceder a S3, pero no controla quién puede hacer requests a CloudFront. Con Lambda@Edge es posible agregar lógica de autorización en los nodos de la CDN, antes de que el request llegue al origen. La secuencia es la siguiente:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Cuando un usuario solicita un objeto de un bucket, CloudFront invoca una función Lambda@Edge en el nodo más cercano geográficamente.&lt;/li&gt;
&lt;li&gt;La función valida el JWT de Cognito (o cualquier token de sesión) sin necesidad de redirigir el request al backend.&lt;/li&gt;
&lt;li&gt;Si el token es válido, el request continúa hacia S3 a través de OAC normalmente.&lt;/li&gt;
&lt;li&gt;Si no es válido, Lambda@Edge retorna un &lt;code&gt;401&lt;/code&gt; o redirige al login desde el edge.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;⭐ La ventaja es la &lt;strong&gt;baja latencia&lt;/strong&gt;, la validación ocurre en el edge node más cercano al usuario, sin necesidad de viajar hasta la región de AWS donde vive el backend. Cada request de contenido protegido se resuelve en milisegundos en lugar de sumar el tiempo de ida y vuelta a tu servidor.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Descarga temporal de un archivo privado - S3 Presigned URLs
&lt;/h2&gt;

&lt;p&gt;Para esta opción el casos de uso típico: Un usuario necesita descargar un reporte generado, una factura o un documento legal guardado en bucket S3. No se utiliza Cloudfront porque no necesitamos cachear contenido de la petición.&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%2Fougq75ayilzbgr5wpfaq.jpg" 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%2Fougq75ayilzbgr5wpfaq.jpg" alt="S3 Presigned URLs" width="800" height="249"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Se produce la petición del usuario, el backend valida que ese usuario tiene permiso sobre ese archivo específico.&lt;/li&gt;
&lt;li&gt;Lambda genera una &lt;strong&gt;presigned URL&lt;/strong&gt; con &lt;code&gt;GetObject&lt;/code&gt; que expire entre 5-15 min. La lógica de validación de lambda es idéntica del caso de uso 1 de Upload.&lt;/li&gt;
&lt;li&gt;El browser descarga directamente desde S3 usando esa URL.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;🔐 &lt;strong&gt;Brechas de seguridad detectadas&lt;/strong&gt;&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;strong&gt;Riesgos de seguridad&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;Mitigación posible&lt;/strong&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;El usuario la copia y la comparte intencionalmente o no.&lt;/td&gt;
&lt;td&gt;TTL muy corto (1-2 minutos si es descarga inmediata)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Queda en logs del browser, proxies o herramientas de red&lt;/td&gt;
&lt;td&gt;Generar la URL y redirigir directamente (&lt;code&gt;302&lt;/code&gt;) en lugar de devolverla al frontend (nunca queda expuesta en el browser)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Se filtra por un &lt;code&gt;Referer&lt;/code&gt; header en un redirect&lt;/td&gt;
&lt;td&gt;Incluir el &lt;code&gt;userId&lt;/code&gt; en la key del objeto (&lt;code&gt;uploads/{userId}/{filename}&lt;/code&gt;) para que aunque alguien obtenga la URL, solo pueda acceder al archivo de ese usuario específico.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  3. Distribución segura con cookies por sesión - CloudFront Signed Cookies
&lt;/h2&gt;

&lt;p&gt;Caso de uso típico: Una plataforma web con contenido que se accede por suscripción, los usuarios se loguean pero cada sesión debe tener acceso acotado en el tiempo. En lugar de firmar URL por URL, el backend emite una &lt;strong&gt;Signed Cookie de CloudFront&lt;/strong&gt; al momento del login, que el browser envía automáticamente en cada request de objetos multimedia.&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%2Fd4ofyfbqg1jfvgil5q39.jpg" 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%2Fd4ofyfbqg1jfvgil5q39.jpg" alt="CloudFront Signed Cookies" width="800" height="437"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;El backend verifica la sesión y envía tres headers &lt;code&gt;Set-Cookie&lt;/code&gt; al browser (CloudFront requiere exactamente tres pares clave-valor para una Signed Cookie). Estos headers deben enviarse &lt;strong&gt;antes&lt;/strong&gt; de que el usuario solicite el contenido privado.&lt;/li&gt;
&lt;li&gt;Si se configura un tiempo de expiración corto, el backend puede reenviar tres nuevos headers &lt;code&gt;Set-Cookie&lt;/code&gt; en requests posteriores para mantener el acceso activo.&lt;/li&gt;
&lt;li&gt;CloudFront valida las cookies en cada request antes de servir los objetos multimedia. La distribución debe tener al menos dos comportamientos de &lt;strong&gt;cache&lt;/strong&gt;: uno público y uno que requiere autenticación. La sección privada redirige al login si no hay cookie válida.&lt;/li&gt;
&lt;li&gt;Al cerrar sesión o expirar las cookies, el acceso se revoca sin cambiar las URLs.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;⭐ Esta opción es Ideal cuando un usuario accede a múltiples objetos multimedia de una misma sección sin generar una firma por cada archivo.&lt;br&gt;
⭐ Si CloudFront se configura para cachear basándose en cookies, NO generará entradas de caché separadas por los atributos de las &lt;em&gt;Signed Cookies&lt;/em&gt;. Es decir, todos los usuarios autorizados compartirán la misma entrada de caché para un objeto determinado— CloudFront valida la cookie para permitir o denegar el acceso, pero la ignora al construir la cache key.&lt;/p&gt;




&lt;h2&gt;
  
  
  Aspectos generales a tener en cuenta
&lt;/h2&gt;

&lt;p&gt;➡ &lt;strong&gt;Diseño&lt;/strong&gt;&lt;br&gt;
&lt;strong&gt;Considerar Patrón BFF (Backend for Frontend)&lt;/strong&gt;. Para el caso de descarga privada, se puede interponer una capa BFF entre el frontend y API Gateway. Esta capa maneja la sesión del usuario y puede ejecutar un redirect &lt;code&gt;302&lt;/code&gt; directo hacia S3, evitando que la presigned URL quede expuesta en el browser.&lt;/p&gt;

&lt;p&gt;➡ &lt;strong&gt;Performance/Costo&lt;/strong&gt;&lt;br&gt;
Invalidaciones de CloudFront (incurre costo después de 1000/mes). Además del costo analizar tiempo de cacheo de datos.&lt;/p&gt;

&lt;p&gt;S3 request rates (3500 PUT/5500 GET por segundo por prefix, si el volumen es alto distribuir con prefijos).&lt;/p&gt;

&lt;p&gt;Costo de Lambda por invocación para generar presigned URLs a escala.&lt;/p&gt;

&lt;p&gt;➡ &lt;strong&gt;Seguridad&lt;/strong&gt;&lt;br&gt;
Rotación de claves KMS si el bucket usa SSE-KMS.&lt;/p&gt;

&lt;p&gt;Versionado de objetos en S3 para evitar sobreescritura accidental.&lt;/p&gt;

&lt;p&gt;➡ &lt;strong&gt;Operacional&lt;/strong&gt;&lt;br&gt;
TTL de presigned URLs vs tiempo de expiración del JWT — si el JWT expira antes que la URL, tenemos un problema!&lt;/p&gt;

&lt;p&gt;Estrategia de nombres de objetos (&lt;code&gt;userId/filename&lt;/code&gt;) para evitar colisiones y facilitar políticas IAM por prefijo.&lt;/p&gt;

</description>
      <category>aws</category>
      <category>serverless</category>
      <category>cloudfront</category>
      <category>s3</category>
    </item>
    <item>
      <title>Pensar en Serverless para crear bellos sueños 🦋</title>
      <dc:creator>Laura Bolaños</dc:creator>
      <pubDate>Fri, 10 Apr 2026 12:56:18 +0000</pubDate>
      <link>https://dev.to/aws-builders/pensar-en-serverless-para-crear-bellos-suenos-390</link>
      <guid>https://dev.to/aws-builders/pensar-en-serverless-para-crear-bellos-suenos-390</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%2Fjkt4xky3sc2hei44br55.jpg" 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%2Fjkt4xky3sc2hei44br55.jpg" alt="Mariposa Monarca" width="688" height="742"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;En estas líneas te explico una sencilla arquitectura para desplegar un sitio web íntegramente utilizando servicios Serverless que podría servir, como en mi caso, para mostrarle al mundo mi interés por la ecología (con repositorio github incluido)&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;En un mundo digital donde se crean productos financieros, web que muestran dashboard de eficiencias, p&amp;amp;L y todo tipo de temáticas asociada al dinero ...y que está muy bien! olvidamos que nuestro hábitat natural necesita ayuda.&lt;br&gt;
Hace unos años me percate de esto y comencé a leer/hablar de árboles, arbustos y plantas mal llamadas malezas - nativas de mi región que son fuente de alimento de mariposas e insectos que son fundamentales para la biodiversidad - que están desapareciendo con el avance de las especies exóticas, los agroquímicos y la destrucción de humedales.&lt;br&gt;
La mayoría de las personas cuando comentas la problemática te dice "OK estoy de acuerdo contigo" pero no activan en tener un pequeño jardín de nativas o a la hora de elegir un árbol para su vereda priorizan especies exóticas solo por estetica, sin saber que muchas nativas son igual de hermosas y además sostienen la fauna local (hablo especialmente de la Provincia de Buenos Aires, Argentina).&lt;/p&gt;

&lt;p&gt;....Y qué pasaría si cambio mi discurso en mi afán de convencer y digo: &lt;strong&gt;"si no ayudamos plantando nativas en nuestros hogares las mariposas pueden desaparecer"&lt;/strong&gt; ¿Suena drástico? pero en gran parte es cierto. Estudios afirman que la población ha disminuido muy rápido, especialmente la mariposa &lt;strong&gt;Bandera Argentina&lt;/strong&gt; debido a que no encuentra su planta nutricia (Coronillo) donde desovar sus huevos 💔 Cabe aclarar que la disminución de mariposas afecta directamente a la polinización y con esto atenta contra la seguridad alimentaria.&lt;br&gt;
Por todo lo anterior y para bajar un poco el dramatismo decidí hacer algo: crear un proyecto web que muestre mariposas e indique la planta nativa nutricia que alimenta sus orugas! Y que los usuarios registrados puedan cargar avistamientos de mariposas en la región. Para acompañar esta idea pensé en una arquitectura Serverless, que reduce la huella de carbono y acompaña mi pensamiento ecológico 🌱.&lt;/p&gt;

&lt;h2&gt;
  
  
  Comencemos analizando la arquitectura
&lt;/h2&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%2Fksxqm8z5i19gaiscwxpi.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%2Fksxqm8z5i19gaiscwxpi.png" alt="Diagrama de Arquitectura" width="800" height="509"&gt;&lt;/a&gt;&lt;br&gt;
Como podés observar el laboratorio es de un nivel entre 100 y 200 (si necesitas ayuda me comentas).&lt;br&gt;
Implementa una arquitectura Serverless de &lt;strong&gt;3 capas&lt;/strong&gt;:&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Web Tier:&lt;/em&gt;&lt;br&gt;
&lt;strong&gt;S3-Sitio Web + CloudFront&lt;/strong&gt; ➡ contiene todo el sitio web creado con react. El código está preparado para integrar con los servicios &lt;strong&gt;Apigateway y Cognito&lt;/strong&gt;. Cloudfront servicio para servir el sitio web de S3. Este s3 no es público, solo se accede a través de Cloudfront.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;App Tier:&lt;/em&gt;&lt;br&gt;
&lt;strong&gt;Cognito + API Gateway + Lambda&lt;/strong&gt; ➡ Cognito realiza la autenticación del usuario que se inicia sesión. Se aclara que los usuarios se deben crear manualmente por la Consola de AWS o por cli (explicado en el Readme de repositorio). Las Lambdas de crear imagen, get imagen, presigned_URL y delete imagen(funcionalidad no desarrollada aún desde el frontend) se invocan via Apigateway. Solo los usuarios autorizados por Cognito pueden acceder a estas funcionalidades.&lt;br&gt;
Las lambdas están codificadas en Python.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Data Tier:&lt;/em&gt;&lt;br&gt;
&lt;strong&gt;DynamoDB + S3 - imágenes&lt;/strong&gt; ➡ Toda la información de la fichas de las imágenes de mariposas se guarda en DynamoDB incluyendo la presigned-URL de S3-imagenes. En este último bucket se guardarán las imágenes de mariposas subidas por el usuario.&lt;br&gt;
Aunque &lt;strong&gt;Route53&lt;/strong&gt; aparece en el diagrama, en el repo no lo vas a ver codificado en la IaC. Por qué? porque para el entorno educativo del laboratorio no es necesario, con la url de cloudfront el sitio web queda totalmente funcional.&lt;/p&gt;

&lt;p&gt;⭐ El objetivo es construir una aplicación real con autenticación, subida de archivos y CRUD completo utilizando solo servicios serverless de AWS, con la opción de deployar en CloudFormation o Terraform. Porque también es muy importante aprender las diferentes formas de desplegar sin tocar el Console Home.&lt;/p&gt;

&lt;h2&gt;
  
  
  Como utilizar el repositorio de código
&lt;/h2&gt;

&lt;p&gt;✅ Ten en cuenta que como requisito para comenzar con este ejercicio necesitas instalado Python, Terraform, AWS Cli (todo explicadisimo en el repo 🤓)&lt;/p&gt;

&lt;p&gt;El código se encuentra en una url de un repositorio padre &lt;strong&gt;labs-aws-llb&lt;/strong&gt; donde hay otros laboratorios, pero el que nos interesa es: &lt;a href="https://github.com/reinalau/labs-aws-llb/tree/main/webAppServerless" rel="noopener noreferrer"&gt;webAppServerles&lt;/a&gt;.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Comenzar leyendo Arquitectura.md que explica un poco la secuencia de las acciones en los componentes y las decisiones de Arquitectura, como por ejemplo por qué no pasar las imagenes por el payload de Lambda.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Leer el &lt;strong&gt;Readme.md&lt;/strong&gt; principal: contiene el paso a paso que debes hacer y si decides hacer el deploy con terraform o cloudformation te indicará ir a su correspondiente directorio. Cada directorio también contiene su Readme.md.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Leer &lt;strong&gt;Integration.md&lt;/strong&gt; : te vas a encontrar que una vez deployada la IaC en AWS, solo necesitarás tomar los outputs de terraform o el descripción del stack de cloudformation y configurar el archivo &lt;strong&gt;aws-config.ts&lt;/strong&gt; . Luego volverás al &lt;strong&gt;Readme principal&lt;/strong&gt; para seguir el paso a paso ➡ volver a subir la web buildeada a S3 y crear una invalidación de CloudFront para actualizar la web integrada con el backend.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;El laboratorio tiene un costo mínimo (si estás en la capa gratuita cero) Como siempre recomiendo limpiar todo lo desplegado. Si estas pensando en crear una web funcional estable ten en cuenta los costos. Información detallada en Readme principal.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Funcionalidades
&lt;/h2&gt;

&lt;p&gt;Una vez deployado el sitio web siguiendo las indicaciones, tenemos las siguientes funcionalidades.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Feature&lt;/th&gt;
&lt;th&gt;Usuario anónimo&lt;/th&gt;
&lt;th&gt;Usuario logueado&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Ver catálogo de mariposas precargadas&lt;/td&gt;
&lt;td&gt;🦋&lt;/td&gt;
&lt;td&gt;🦋&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Ver galería de avistamientos de usuarios&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;🦋&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Subir foto + metadata de avistamiento&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;🦋&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Filtrar por ecorregión&lt;/td&gt;
&lt;td&gt;🦋&lt;/td&gt;
&lt;td&gt;🦋&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Ver ficha detallada de mariposa&lt;/td&gt;
&lt;td&gt;🦋&lt;/td&gt;
&lt;td&gt;🦋&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Después de todo el trabajo... con la url de Cloudfront descubrirás esta hermosa web funcional de mariposas bonaerenses 💗 sustentada íntegramente con servicios serverless.&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%2Fmh01boamvwd9gosnvxog.jpg" 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%2Fmh01boamvwd9gosnvxog.jpg" alt="Imagen sitio web" width="800" height="953"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;En el título hablo de sueños porque realmente lo es, sueño que mis vecinos tengan aunque sea solo un ejemplar nativo. No hay estadística clara sobre la vegetación nativa, pero sabemos que las especies van retrocediendo y con esto también las mariposas.&lt;br&gt;
&lt;strong&gt;La foto principal es una Monarca del Sur recién nacida en mi jardín, ya que generé las condiciones para que eso pasara.&lt;/strong&gt;&lt;br&gt;
Este laboratorio sirve para mostrar que casi sin costo podemos difundir información sobre temas que nos favorecen a todos y a todas. Y en tu región, ¿qué mariposas habitan?&lt;/p&gt;

</description>
      <category>serverless</category>
      <category>aws</category>
      <category>architecture</category>
    </item>
    <item>
      <title>Claves para lograr la certificación AWS Data Engineer Associate</title>
      <dc:creator>Laura Bolaños</dc:creator>
      <pubDate>Fri, 20 Mar 2026 03:33:59 +0000</pubDate>
      <link>https://dev.to/aws-builders/claves-para-lograr-la-certificacion-aws-data-engineer-associate-bb7</link>
      <guid>https://dev.to/aws-builders/claves-para-lograr-la-certificacion-aws-data-engineer-associate-bb7</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;En este artículo encontrarás una guía para descubrir qué conocimientos necesitás antes de rendir el examen, identificar tus brechas y entender en qué temas profundizar. 🤓&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Información general del examen
&lt;/h3&gt;

&lt;p&gt;La certificación esta orientada los Ingenieros de datos pero también a todos aquellos que están construyendo su perfil de Arquitecto Cloud.&lt;br&gt;
&lt;a href="https://aws.amazon.com/es/certification/certified-data-engineer-associate/" rel="noopener noreferrer"&gt;Aquí&lt;/a&gt;  podes encontrar datos generales del examen, intuyo que ya conoces esta información.&lt;br&gt;
La guia de examen consta de 4 dominios, es super necesario leer y revisar continuamente mientras estudias para la certificación: &lt;a href="https://docs.aws.amazon.com/aws-certification/latest/data-engineer-associate-01/data-engineer-associate-01.html" rel="noopener noreferrer"&gt;link &lt;/a&gt;&lt;br&gt;
El dato importante: el examen no esta disponible en español. Para todos los que tenemos dificultad con el idioma puede parecer un impedimento pero no te preocupes! estudiando y armando apuntes en ingles lo puedes lograr 🏆 Las preguntas se pueden comprender perfectamente porque se alcanza un nivel de familiaridad con frases claves del examen.&lt;br&gt;
⭐ Tip: lengua no nativa ingles ➡ pedir los 30 minutos adicionales (Exam acommodations) en la plataforma &lt;a href="https://www.aws.training/certification" rel="noopener noreferrer"&gt;Training And Certificacion&lt;/a&gt;  antes de agendar el examen.&lt;/p&gt;

&lt;h3&gt;
  
  
  Complejidad
&lt;/h3&gt;

&lt;p&gt;Si no trabajas como Data Engineer pero contas con un background en bases de datos, consultas sql complejas y performance tuning los contenidos te van a resultar familiares y sencillos de incorporar. Además, si contás con la certificación Solutions Architect Associate una parte del contenido ya lo habrás estudiado.&lt;/p&gt;

&lt;p&gt;⭐ Es una certificación importante y muy amena para estudiar, de complejidad media.&lt;/p&gt;

&lt;h3&gt;
  
  
  Cursos de preparación y laboratorios básicos
&lt;/h3&gt;

&lt;p&gt;➡ Curso en Skillbuilder de &lt;em&gt;&lt;a href="https://skillbuilder.aws/learn/6BP61KB1FJ/data-engineering-on-aws--foundations/KXCN4PJD9Y?parentId=7UPVWWCC45" rel="noopener noreferrer"&gt;Data Engineer Foundations&lt;/a&gt;&lt;/em&gt; . Es gratis y básico para esta certificación.&lt;br&gt;
➡ Curso en &lt;a href="https://skillbuilder.aws/learning-plan/QYZWVSMX4B/exam-prep-plan-aws-certified-data-engineer--associate-deac01--english/YTMBK7R698" rel="noopener noreferrer"&gt;SkillBuilder de preparación del examen&lt;/a&gt;. Es esencial ya que explica en que consiste el examen y lo que debemos estudiar. Si no contas con la suscripción haz todo el contenido libre, basicamente es la explicación de los 4 dominios.&lt;br&gt;
➡ Es necesario hacer laboratorios de diferentes casos de uso, tanto de Data Lakes como de DataWarehouse. Los laboratorios los encontras en SkillBuilder (ejemplo CloudQuest Data Analytics) o invertir unos dolares en la consola. Comparto laboratorio básico de mi &lt;a href="https://github.com/reinalau/labs-aws-llb/tree/main/serverless-aws-datalake-1" rel="noopener noreferrer"&gt;github &lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Método de estudio sugerido
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Armar un NotebookLM con tus apuntes y links a pdf de la &lt;a href="https://docs.aws.amazon.com/" rel="noopener noreferrer"&gt;documentación oficial de AWS&lt;/a&gt;. Particularmente recomiendo Developer Guide y/o User Guide de servicios como Glue, Redshift, Kinesis, Athena, QuickSigth, OpenSearch, Amazon MSK, LakeFormation, DataSync y todas las url que consideres. De esta manera construyes una especie de RAG para tener precisión a la hora de preguntar dudas conceptuales o de casos de uso.&lt;/li&gt;
&lt;li&gt;En el momento de practicar preguntas no te fies ciegamente de las respuestas de las IA, el último tiempo noté que algunos modelos tienen dificultades con temas de elección de arquitecturas. Verificar siempre con la documentación oficial, por eso es importante el punto anterior.&lt;/li&gt;
&lt;li&gt;Buscar un banco de preguntas para entrenar y conocer el estilo de examen. En mi caso utilicé &lt;a href="https://tutorialsdojo.com/" rel="noopener noreferrer"&gt;Tutoriales Dojo&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Recursos útiles (lo utilicé en la preparación) :&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://www.youtube.com/watch?v=s2DzF8avQnY" rel="noopener noreferrer"&gt;video banco de preguntas &lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.youtube.com/watch?v=s2DzF8avQnY" rel="noopener noreferrer"&gt;video casos de uso &lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/reinalau/AWS-Certified/tree/main/DEA-C01" rel="noopener noreferrer"&gt;github llb&lt;/a&gt; &lt;/p&gt;

&lt;h3&gt;
  
  
  Conocimientos fundamentales para presentar el examen
&lt;/h3&gt;

&lt;p&gt;Durante el examen prestar atención a palabras claves, pensar cual solución es mas lógica, más costo- efectiva, con menor esfuerzo operacional y con performance aceptable.&lt;br&gt;
El listado a continuación no cubre todo el temario, pero dominar estos temas es fundamental para aprobar:&lt;/p&gt;

&lt;h4&gt;
  
  
  Generales
&lt;/h4&gt;

&lt;ol&gt;
&lt;li&gt;Datalake ➡ S3: raw, curation, consumption.&lt;/li&gt;
&lt;li&gt;DataWarehouse : Redshift. Siempre relacionado con queries complejas.&lt;/li&gt;
&lt;li&gt;Data Lakehouse.&lt;/li&gt;
&lt;li&gt;Patrones de ingesta de datos: Streaming y Batch.&lt;/li&gt;
&lt;li&gt;Atención en las preguntas donde se haga alusión a data lake o datawarehouse porque puede ser la clave para elegir el almacenamiento.&lt;/li&gt;
&lt;li&gt;Formatos de archivos para alimentar un Data Lake en S3: Json, Parquet, Avro, ORC, Csv. Sus casos de uso. Comprender mecanismo de construcción de su metadata. Formatos de Compresión gzip (ratio), snappy (rápidez), zlib.&lt;/li&gt;
&lt;li&gt;Elección de servicio para migrar archivos/datos desde el onprem. Probablemente la elección es DataSync.&lt;/li&gt;
&lt;li&gt;Data Skew: referido a una distribución desigual de los datos entre las diferentes unidades de procesamiento provocando un desequilibrio de carga.&lt;/li&gt;
&lt;li&gt;Métodos principales de orquestación de pipeline de datos: Step Functions, Glue Workflows (nativo para job de glue) y MWAA (dependencias complejas, portabilidad). Se pueden crear flujos y orquestarlos con Event Bridge.&lt;/li&gt;
&lt;li&gt;DynamoDb Stream. DynamoDB TTL.&lt;/li&gt;
&lt;li&gt;Conexion a RDS, Aurora, Redshift via api desde Lambda. Revisar ejemplos.&lt;/li&gt;
&lt;li&gt;Comprender el concepto DAGs (Directed Acyclic Graphs) y con qué servicios esta relacionado. Amazon MWAA&lt;/li&gt;
&lt;li&gt;Visualizacion-Dashboard ➡ QuickSigth . QuickSigth SPICE (relacion con Athena). Analizar diferentes casos de uso.&lt;/li&gt;
&lt;li&gt;QuickSigth librerias built-in functions and operators: utilidad en casos de uso que necesitamos Rolling Averages, Pivoting and Grouping y Machine Learning (ML) Insights.&lt;/li&gt;
&lt;li&gt;Opensearch: Creación de indices, monitorización de logs en tiempo real. UltraWarm en OpenSearch ➡ Conocer su caso de uso.&lt;/li&gt;
&lt;li&gt;Secrets Manager es nuestro servicio estrella para guardar accesos a base de dados de manera segura.&lt;/li&gt;
&lt;li&gt;Casos de uso de MSK (Kafka). Se asocia con Glue para transformar.&lt;/li&gt;
&lt;/ol&gt;

&lt;h4&gt;
  
  
  Amazon S3
&lt;/h4&gt;

&lt;ol&gt;
&lt;li&gt;S3 Storage Lens: Si tengo que hacer una auditoría de bucket, identificar versiones antiguas de objetos, partes incompletas, etc ➡ cuento con un dashboard para clarificar estas falencias.&lt;/li&gt;
&lt;li&gt;Tener claro todos los tipos o layers de S3, su tiempo de recuperación de datos y costos: S3 Standar, IA, Glacier Flexible, Glacier Deep Archive, Intelligent tearing y los otros que no son de alta disponibilidad. Ciclo de vida. Versionamiento. Dependiendo el caso de uso hay que optar.&lt;/li&gt;
&lt;li&gt;Cómo aplico encriptación en reposo en S3, DynamoDB. Siempre pensar en KMS pero NO con una clave proporcionada por el cliente porque es MÁS carga operacional (es lo que debemos evitar): en S3 ➡ SSE-KMS (claves gestionadas por AWS KMS con auditoría)&lt;/li&gt;
&lt;li&gt;Cifrado doble en S3 ➡ SE-KMS (cifrado de doble capa del lado del servidor con AWS KMS).&lt;/li&gt;
&lt;li&gt;VPC Endpoint GATEWAY . No tiene costo en S3 y otorga seguridad sin pasar por internet. Desde Glue se puede crear una conexión de red, especificar vpc/subnet. Mismo caso para conectar una lambda de manera segura a S3.&lt;/li&gt;
&lt;li&gt;Si tengo varias aplicaciones que consumen diferentes prefix de S3 cual es la mejor manera de brindar seguridad para que una aplicación no pueda ver los datos de otra? Probablemente la solución sea S3 Access Point&lt;/li&gt;
&lt;li&gt;Casos de uso de EDA (Event-Driven Architecture). Especialmente de S3, reconocer cuando conviene registrar un EventBridge y cuando reaccionar a una lambda (sin intermediarios).&lt;/li&gt;
&lt;li&gt;Modificación de objetos (datos) en S3 al momento de la recuperación, ejemplo: un caso de uso que deba enmascarar información ➡ Por medio de S3 Object Lambda.&lt;/li&gt;
&lt;li&gt;Técnicas de Performance en datos almacenados en S3: Bucketing y Partition (ver cardinalidades). Entender las diferencias y cuando se usa según el caso para poder responder con seguridad.&lt;/li&gt;
&lt;li&gt;Amazon Macie: tener claro que hace escaneo, descubrimiento y clasificacion de información sensible cuando los datos ya están alojados en S3. Puede integrarse con EventBridge para realizar acciones sobre los hallazgos.&lt;/li&gt;
&lt;li&gt;SQL S3 ➡ solo puede consultar un unico archivo. Util para consultas adhoc de un dato en particular.&lt;/li&gt;
&lt;/ol&gt;

&lt;h4&gt;
  
  
  Amazon Glue
&lt;/h4&gt;

&lt;ol&gt;
&lt;li&gt;Glue Engine: Spark, Ray (computación paralela/intensiva) y Python Shell (ejecuciones sencillas).&lt;/li&gt;
&lt;li&gt;Glue ETLs. Glue Crawler (identificación de metadata en varios origenes). Programación de cron. DynamicFrames.&lt;/li&gt;
&lt;li&gt;Glue Dynamic Schema (Schema Evolution). Relacion con AVRO.&lt;/li&gt;
&lt;li&gt;Glue Data Catalog (recordar que no solo se usa en el scope de Glue sino que también se integra con EMR). Schema version history.&lt;/li&gt;
&lt;li&gt;Glue DataBrew - relacionado con Data Quality pero es herramienta visual no-code. Conocer la sintaxis de rules. Conviene hacer laboratorios o al menos revisar la consola de AWS. En qué casos de uso podemos arreglar los datos. Recordar que está vinculado con SageMaker AI en la preparación de datos para entrenar modelos.&lt;/li&gt;
&lt;li&gt;Permite hacer Custom rules.&lt;/li&gt;
&lt;li&gt;AWS Glue Data Quality. Es una capacidad diferentes al punto anterior. Utiliza DQDL para definir reglas de validación.&lt;/li&gt;
&lt;li&gt;Glue Workflows (usar cuando orquestamos solo job de Glue, si vemos que tenemos que orquestar Lambdas la opción correcta probablemente sea Step Functions).&lt;/li&gt;
&lt;li&gt;Glue Bookmark. Si lo tengo activado y el job vuelve a procesar los datos nuevamente...que puede estar pasando? falta job.commit().&lt;/li&gt;
&lt;li&gt;Desde un bucket policy se puede denegar ejecuciones de glue que no esten desde un rango horario determinado, ejemplo: "StringNotEquals":{},"NumericGreaterThan":{"aws:CurrentTime":"11:00:00Z"},"NumericLessThan":{"aws:CurrentTime":"09:00:00Z"}} . Ver casos de policy en S3, es la parte de seguridad mas importante del examen.&lt;/li&gt;
&lt;li&gt;Comprender permisos de ejecucion en Glue mediante roles y politica de confianza (Trust Policy): AWSServiceRole (tiene las politicas básicas).&lt;/li&gt;
&lt;li&gt;Si tengo que monitorear job de Glue, a donde voy? lo hago en Glue Studio ➡Job monitoring dashboard (no desde Cloudwatch). Hacer laboratorio con Glue y revisar las métricas, ejecuciones anteriores. Este analisis sirve para ajustar dpu o workers.&lt;/li&gt;
&lt;li&gt;Glue transformación de datos JSON a Tabular : Relationalize Transform.&lt;/li&gt;
&lt;li&gt;Feature Transformación Detect PII (o Detect Sensitive Data): Accion de enmascarar, redactar o eliminar.&lt;/li&gt;
&lt;li&gt;Glue Interactive Sessions.&lt;/li&gt;
&lt;li&gt;Glue Flex. Usa capacidad de computación ociosa por lo tanto es menos costoso.&lt;/li&gt;
&lt;/ol&gt;

&lt;h4&gt;
  
  
  Amazon Redshift
&lt;/h4&gt;

&lt;ol&gt;
&lt;li&gt;Redshift sintaxis sql: practicar select, agrupaciones, rank() y funciones más comunes. Sintaxis UDF (se invocan en la proyeccción). Entender que las búsquedas con expresiones regulares son más lentas.&lt;/li&gt;
&lt;li&gt;Redshift comandos: COPY (se usa para traer rápidamente datos desde S3) ➡Option: PARALLEL y COMPUPDATE. Unload (se usa para descargar datos a S3, generalmente históricos).&lt;/li&gt;
&lt;li&gt;Redshift leader nodes y compute nodes. Entender cómo trabaja para tener la capacidad de responder preguntas de performance.&lt;/li&gt;
&lt;li&gt;Redshift Spectrum, está pensando para consultar S3 Y Redshift. No confundir con consultas federadas. Por lo general se usa Spectrum cuando redshift descarga registros antiguos en s3 para abaratar costos y se requiere algún informe que cruce con datos históricos.&lt;/li&gt;
&lt;li&gt;Redshift consultas federadas vs Athena federated queries. Se puede presentar una pregunta con estas dos opciones. Leer el caso de uso y tener en claro que soporta cada una. Ejemplo, Redshift queries federadas no soportas consultas en TimeStream.&lt;/li&gt;
&lt;li&gt;Redshift Distribution Style : entender que es Auto Distribution, ALL, Even, Key. Esto se aplica para hacer performantes las querys. Relacionar con Star Schemas.&lt;/li&gt;
&lt;li&gt;Redshift: Ingesta de datos en formato JSON, cómo se almacena/consulta de forma performante? Con el tipo de dato SUPER, se crea una tabla con una única columna y se puede realizar consultas anidadas (se usa PARTITION BY y funciones como like json_extract_path_text).&lt;/li&gt;
&lt;li&gt;Data Sharing: Redshift comparte información entre cluster. Ver casos de uso.&lt;/li&gt;
&lt;li&gt;Vistas materializadas. Como las construye. En qué casos de uso se utilizan. Cómo se refrescan.&lt;/li&gt;
&lt;li&gt;Redshift troubleshooting: Tabla de sistema STL_ALERT_EVENT_LOG. Maximum Transmission Unit (MTU). VACCUM, VACCUM FULL, VACCUM DELETE ONLY y VACCUM REINDEX.&lt;/li&gt;
&lt;li&gt;Redshift Workload Management. Determina como se ejecutan las consultas en el cluster (query queues and route queries).&lt;/li&gt;
&lt;li&gt;MPP (Massively Parallel Processing) y Windows Functions.&lt;/li&gt;
&lt;li&gt;Dynamic Data Masking - DDM (CREATE MASKING POLICY) ➡ Permite ocultar, ofuscar o seudonimizar datos. Se pueden restringir a usuarios o a roles específicos.&lt;/li&gt;
&lt;/ol&gt;

&lt;h4&gt;
  
  
  Kinesis Data Stream - Kinesis Firehose - Amazon Managed Service for Apache Flink (Ex Kinesis Data Analytics)
&lt;/h4&gt;

&lt;ol&gt;
&lt;li&gt;Tener claro conceptualmente los 3 servicios del título. Real time y Near real time.&lt;/li&gt;
&lt;li&gt;Amazon Managed Service for Apache Flink: Detectar anomalias o casos de uso de Fraude. Windows Operations (defining time-based or row-based windows to manage data streams)&lt;/li&gt;
&lt;li&gt;Mirar todos los casos de ingesta Kinesis Data Stream (pensar que siempre es real time). Puede ingestar a Redshift directamente con Redshift Streaming (es zero etl).&lt;/li&gt;
&lt;li&gt;Analizar Casos de Uso de streaming de IoT. Velocidad de Transmisión de datos- Registros por segundo.&lt;/li&gt;
&lt;li&gt;Performance en streaming de datos: Kinesis Producer Library (KPL) y Kinesis Client Library (KCL). Shared Fan-out&lt;/li&gt;
&lt;li&gt;Partition key de alta cardinalidad para distribuir la carga de forma equitativa en los diferentes shard.&lt;/li&gt;
&lt;li&gt;Resolución de problemas en Kinesis Data Stream ➡ si la velocidad de los datos supera la capacidad de los fragmentos actuales: ProvisionedThroughput - Exceeded Exception.&lt;/li&gt;
&lt;li&gt;Caso de uso Kinesis Firehose + Lambda para transformación de datos.&lt;/li&gt;
&lt;li&gt;Integración Kinesis Firehose con CloudTrail.&lt;/li&gt;
&lt;/ol&gt;

&lt;h4&gt;
  
  
  Lake Formation
&lt;/h4&gt;

&lt;ol&gt;
&lt;li&gt;Lake Formation, si hay preguntas sobre permisos granulares considerar que la respuesta es esta. Tener en cuenta todo lo que puede gobernar Lake Formation (qué fuentes de datos).&lt;/li&gt;
&lt;li&gt;Fine-Grained Access Control (FGAC). Tag-Based Access Control (LF-TBAC). Credential Vending.&lt;/li&gt;
&lt;li&gt;Blueprints and Workflows: Templates que ayudan a ingestar datos desde varias fuentes para crear automaticamente AWS Glue crawlers, jobs, and triggers.&lt;/li&gt;
&lt;li&gt;Auditoría via CloudTrail.&lt;/li&gt;
&lt;li&gt;CloudTrail Lake: observalidad de como interactúa el ecosistema de AWS. Centralidad de logs. SQL Engine. Seguridad Granular.&lt;/li&gt;
&lt;/ol&gt;

&lt;h4&gt;
  
  
  EMR
&lt;/h4&gt;

&lt;ol&gt;
&lt;li&gt;Comprender los casos de uso EMR. Es la opcion de procesamiento de datos mas costosa para mantener (para que viva la metadata hay que tener prendido el cluster). Puede ser la elección adecuado si se requiere control profundo sobre la infraestructura, configuraciones personalizadas (flexibilidad) o el uso del ecosistema completo de Hadoop para migraciones de datos.&lt;/li&gt;
&lt;li&gt;Relación con BigData. Procesamiento Distribuido.&lt;/li&gt;
&lt;li&gt;EMR puede usar Glue Catalog.&lt;/li&gt;
&lt;li&gt;Mirar la combinación de cómputo recomendada para brindar alta disponibilidad y cost effective. Instancias Spot y Procesadores Graviton.&lt;/li&gt;
&lt;li&gt;EMR: feature security configuration para setear encriptación tanto en reposo como en tránsito.&lt;/li&gt;
&lt;li&gt;EMR Serverless. Casos de uso. Entender en cual caso conviene utilizar en lugar de EMR Standard.&lt;/li&gt;
&lt;/ol&gt;

&lt;h4&gt;
  
  
  Amazon Athena
&lt;/h4&gt;

&lt;ol&gt;
&lt;li&gt;"Analizar datos con sql" la respuesta es Athena.&lt;/li&gt;
&lt;li&gt;Tablas en Athena que se pueden modificar : Apache Iceberg.&lt;/li&gt;
&lt;li&gt;Athena predicate pushdown*&lt;em&gt;.&lt;/em&gt;*&lt;/li&gt;
&lt;li&gt;Athena Parallel Execution.&lt;/li&gt;
&lt;li&gt;Consultas anidadas en Athena (nested), como hacer performante y fácil. View por cada consulta.&lt;/li&gt;
&lt;li&gt;Athena federated Query.&lt;/li&gt;
&lt;li&gt;Athena ➡ queries lentas, están mal las particiones que estoy tomando para filtrar. Uso Partition Projection en base a los accesos.&lt;/li&gt;
&lt;li&gt;Glue Notebooks y Athena Notebooks: cuando se usa cada uno?&lt;/li&gt;
&lt;li&gt;CTAS (Create Table as Select)&lt;/li&gt;
&lt;li&gt;Athena Federated Query por medio de Lambda.&lt;/li&gt;
&lt;li&gt;Athena Workgroups &lt;/li&gt;
&lt;/ol&gt;

&lt;h4&gt;
  
  
  DMS - STC -CDC
&lt;/h4&gt;

&lt;ol&gt;
&lt;li&gt;Migrar a una base de datos en la nube o desde onprem, la mejor elección es DMS. Si no hay homogeneidad en la base de datos origen con la de destino se debe usar STC (AWS Schema Conversion tool). Para replicar datos evitando downtime en la base de datos se replica con CDC (change data capture). Este último se realiza con los logs full de transacciones activado en la base de datos origen.&lt;/li&gt;
&lt;li&gt;En los casos de uso de migración de bases de datos homogéneas solo se usa DMS + DMS Schema Conversion y cdc (change data capture) para los cambios.&lt;/li&gt;
&lt;li&gt;Cuando tengo dos regiones y se quiere migrar una base de datos en la región A con destino en la región B, DMS debe ubicarse idealmente en la región donde está la base de datos de destino o en una región cercana para minimizar la latencia de escritura.&lt;/li&gt;
&lt;/ol&gt;

&lt;h4&gt;
  
  
  Cloudwatch - CloudTrail
&lt;/h4&gt;

&lt;ol&gt;
&lt;li&gt;Comprender cuándo utilizar CloudWatch, ejemplo ➡ si necesito analizar/buscar con lenguaje sql uso Amazon CloudWatch Logs Insights. Metrics Filters y Subscription Filter.&lt;/li&gt;
&lt;li&gt;Creación de Train en CloudTrail. Mecanismo de envío de datos (a S3) y consultas.&lt;/li&gt;
&lt;li&gt;En CloudTrail puedo direccionar el logueo de la actividad de cuentas y/o servicios a un S3 y analizar los datos mediante Athena.&lt;/li&gt;
&lt;li&gt;CloudTrail caso de uso testigo: a. CloudTrail capta eventos de Redshift, b. por medio de Reglas de EventBridge guarda esos logs en DynamoDB. También EventBridge Pipes puede filtrar contenido de eventos.&lt;/li&gt;
&lt;/ol&gt;

</description>
      <category>aws</category>
      <category>dataengineering</category>
      <category>awscertified</category>
    </item>
    <item>
      <title>Camino a lograr AWS Certified Developer - Associate (DVA-C02)</title>
      <dc:creator>Laura Bolaños</dc:creator>
      <pubDate>Tue, 17 Mar 2026 14:23:20 +0000</pubDate>
      <link>https://dev.to/aws-builders/camino-a-lograr-aws-certified-developer-associate-dva-c02-4o19</link>
      <guid>https://dev.to/aws-builders/camino-a-lograr-aws-certified-developer-associate-dva-c02-4o19</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Estas notas no intentan ser una guía detallada, sino un recorrido por temas importantes y tips que debemos tener en cuenta si nos aventuramos a estudiar esta certificación. También es importante aclarar que se trata de una visión subjetiva acerca de la complejidad del examen, basada en mi experiencia después de haber obtenido 3 certificaciones previas de AWS.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Información general del examen
&lt;/h2&gt;

&lt;p&gt;No me voy a detener en esta descripción porque está claramente escrito en este &lt;a href="https://aws.amazon.com/es/certification/certified-developer-associate/" rel="noopener noreferrer"&gt;enlace que debes leer&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;⭐ &lt;strong&gt;Tip&lt;/strong&gt;: si tu lengua no es ingles nativa, pedir 30 minutos adicionales (Exam acommodations) en la plataforma &lt;em&gt;&lt;a href="https://www.aws.training/certification" rel="noopener noreferrer"&gt;Training And Certificacion&lt;/a&gt;&lt;/em&gt; antes de agendar el examen, sin importar si se rinde en ingles o español.&lt;br&gt;
Esta selección se realiza en la opción de menú marcada y queda seleccionada por default para todas las futuras certificaciones de AWS.&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%2Fpopczz0kjfyxxqieunl0.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%2Fpopczz0kjfyxxqieunl0.png" alt="tc" width="215" height="398"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Complejidad
&lt;/h2&gt;

&lt;p&gt;AWS Developer Associate &amp;lt; AWS Solutions Architect Associate&lt;br&gt;
AWS Developer Associate &amp;gt; AWS Cloud Practtioner&lt;br&gt;
AWS Developer Associate &amp;lt; AWS AI Practitioner&lt;/p&gt;

&lt;h2&gt;
  
  
  Relación con certificaciones anteriores
&lt;/h2&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%2F13uk85wqrzw15ryy8sn3.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%2F13uk85wqrzw15ryy8sn3.png" alt="comparativa certificaciones" width="720" height="330"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Cuál es tu punto de partida?
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Leer la guía de examen para tener una visión general del contenido que debemos abordar de los 4 dominios, cada dominio tiene un % diferente de cobertura en la certificación. No te desanimes si a priori pensas que tu perfil no es el del candidato que se describe en la guía, yo tampoco lo soy 100%, pero con ganas y entusiasmo para aprender → llegarás a la meta!!.&lt;br&gt;
&lt;a href="https://d1.awsstatic.com/es_ES/training-and-certification/docs-dev-associate/AWS-Certified-Developer-Associate_Exam-Guide.pdf" rel="noopener noreferrer"&gt;guía del examen&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Learning plan de preparación de AWS SkillBuilder. No importa si no contas con la suscripción, haz lo que este sin costo. Es una forma de nivelar tus conocimientos.&lt;br&gt;
Lo bueno de la suscripción es que accedes a varios laboratorios útiles pero no es un impedimento. Si haces practicas de laboratorios por cuenta propia necesitarás una inversión mínima en la consola de AWS de 1 a 3 usd.&lt;br&gt;
&lt;a href="https://skillbuilder.aws/learning-plan/ZWHYYQBTUK/exam-prep-plan-aws-certified-developer--associate-dvac02--espaol-latam/UD82VTBREP" rel="noopener noreferrer"&gt;Exam Prep Plan: AWS Certified Developer — Associate&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;⭐ Cuando comiences el punto 2, recomiendo armar planilla de calculo de “brechas de conocimiento” e indicar como vas a cubrir ese gap (con laboratorios, documentación de AWS o practicando preguntas de examen).&lt;/p&gt;

&lt;h2&gt;
  
  
  Claves fundamentales para presentar el examen
&lt;/h2&gt;

&lt;p&gt;En esta sección se listan los conocimientos clave que debemos profundizar para alcanzar la certificación. Como siempre, es fundamental tener una perspectiva de seguridad para los diferentes servicios de AWS: quién puede invocar cada servicio y qué acciones puede realizar una vez invocado → aplicando el Principio del Mínimo Privilegio.&lt;/p&gt;

&lt;p&gt;☁ &lt;strong&gt;Desarrollo con Lambda:&lt;/strong&gt; si crees que por lanzar una lambda via consola o cloudformation ya tenes todo el conocimiento…pues no es así. Hay que profundizar y tener practica de laboratorios pasando por la mayoría de sus features:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Versiones Lambda — Alias Lambda-Integraciones (como se usan?). Pruebas de dev y prod con alias. Alias ponderados (como usar?).&lt;/li&gt;
&lt;li&gt;Tiempo de Espera Lambda.&lt;/li&gt;
&lt;li&gt;Variables de Entorno (se cifran? ).&lt;/li&gt;
&lt;li&gt;Concurrencia Aprovisionada y Concurrencia Reservada. (diferencia y sus casos de uso).&lt;/li&gt;
&lt;li&gt;DLQ (cuando se usa).&lt;/li&gt;
&lt;li&gt;Triggers. Lambda Source Events (EventSourceMaping).&lt;/li&gt;
&lt;li&gt;Logueo en &lt;strong&gt;CloudWatch&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Limites y quotas Lambda&lt;/li&gt;
&lt;li&gt;Lambda layers (para que se usan).&lt;/li&gt;
&lt;li&gt;Lambda VPC (cuando y como se usa).&lt;/li&gt;
&lt;li&gt;Eficiencia Lambda (memoria? codigo?)&lt;/li&gt;
&lt;li&gt;Almacenamiento interno /tmp (limites y en que casos es util).&lt;/li&gt;
&lt;li&gt;Manejo de errores. Retroceso exponencial.&lt;/li&gt;
&lt;li&gt;Payload de entrada y de salida.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;⭐ Tip: para cubrir la mayoría de teoría de lambda con demostraciones, ver &lt;a href="https://youtu.be/JIUdRraTZRw?si=S5X6S8j65sd2rwuc" rel="noopener noreferrer"&gt;video Joan Amengual&lt;/a&gt;.&lt;br&gt;
⭐ No dejes de hacer laboratorios o pequeñas pruebas tomando un lenguaje de programación soportado, en mi caso elegí Python.&lt;/p&gt;

&lt;p&gt;☁ &lt;strong&gt;DynamoDB:&lt;/strong&gt; Conocimiento profundo del servicio.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Clave sencilla (único atributo) y compuesta (2 atributos).&lt;/li&gt;
&lt;li&gt;Importancia de cardinalidad en claves de partición. Índices de ordenación.&lt;/li&gt;
&lt;li&gt;Índices LSI y GSI. Qué índice se puede crear en una tabla ya activa y con datos. Limites de índices.
*Recuperar items y en qué casos de uso se utilizan: GetItem, Scan (no performante), Query y BatchGetItem. Consultas condicionales.&lt;/li&gt;
&lt;li&gt;Lecturas eventualmente consistentes y fuertemente consistentes. Transacciones en DynamoDB. Consumo de RCU y WCU de cada una. Tra&lt;/li&gt;
&lt;li&gt;Conocimiento para calcular RCU-WCU en un caso de uso de lecturas/escrituras por segundo de acuerdo al tipo de requerimiento de consistencia.&lt;/li&gt;
&lt;li&gt;Capacidad aprovisionada o a demanda. En qué casos de uso conviene utilizar cada una.&lt;/li&gt;
&lt;li&gt;TTL. Configuración para eliminación de ítem por medio de atributo marca de tiempo.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;⭐&lt;strong&gt;Tip: Hacer laboratorios de Lambda invocando programáticamente a DynamoDB&lt;/strong&gt;, con diferentes funcionalidades de recupero de ítems utilizando el SDK de AWS.&lt;/p&gt;

&lt;p&gt;☁ &lt;strong&gt;DynamoDB Stream:&lt;/strong&gt; Cómo integramos los avisos de cambios de DynamoDB (insert, modify, delete ) con los diferentes servicios .&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;FilterCriteria. Revisar ejemplos.&lt;/li&gt;
&lt;li&gt;Cómo evito publicar información sensible por medio de StreamViewType (KEYS_ONLY).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;⭐Tip: Recomiendo revisar diferentes casos de uso Lambda, Amazon Kinesis Data Stream, Step Functions.&lt;/p&gt;

&lt;p&gt;☁ &lt;strong&gt;Desarrollo Api Gateway:&lt;/strong&gt; Contar con conocimiento profundo del servicio.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Tipos de APIs. Correspondencia con casos de uso.&lt;/li&gt;
&lt;li&gt;Integración con lambda, alias-versiones.&lt;/li&gt;
&lt;li&gt;Stages. Ambientes dev-prod. Variables de stage.&lt;/li&gt;
&lt;li&gt;Integraciones simuladas. Mocks.&lt;/li&gt;
&lt;li&gt;Validación de headers, request y body. Por ejemplo, podemos validar antes de llamar a un backend Lambda.&lt;/li&gt;
&lt;li&gt;Autenticación y Autorización. Roles de IAM. Api key. Cognito (app web y mobile). Lambda Authotizer.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;⭐ Este servicio es de los mas importantes junto con Lambda. Es necesario hacer diferentes laboratorios por medio de la Consola de AWS y también por SAM (Serverless Application Model).&lt;/p&gt;

&lt;p&gt;☁ Autenticación y Autorización Cognito:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;User Pools e Identity Pools. Comprender el flujo básico de autenticación.&lt;/li&gt;
&lt;li&gt;Casos en que solo con User Pools podemos tener autenticación. Adicionando Identity Pool para implemetar Roles de IAM acceder a servicios aws (credenciales temporales).&lt;/li&gt;
&lt;li&gt;Acceso a usuarios autenticados y no autenticados. Casos de uso y diferencias.&lt;/li&gt;
&lt;li&gt;IAM roles y Trust relationships. Su relación con la configuración en Cognito.&lt;/li&gt;
&lt;li&gt;Grupos de usuarios de Cognito (dentro de User Pools). Asignación de Roles de IAM.&lt;/li&gt;
&lt;li&gt;Federación de identidades (Facebook, google, etc). Identity Provider. Protocolos SAML o OpenID Connect (OIDC).&lt;/li&gt;
&lt;li&gt;Flujos de autenticación personalizados con Lambda (Custom authentication challenge Lambda trigger).
*Amazon Cognito Sync para sincronización de perfiles en todos los dispositos mobile y web.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;⭐ Es importante repasar ejemplos y si es posible hacer pequeños laboratorios de: app web con ALB-Cognito, flujos de autorizaciones personalizadas Lambda, Autenticación Cognito en Apigateway.&lt;br&gt;
⭐Ayuda revisar las diferentes configuraciones en la consola de AWS.&lt;/p&gt;

&lt;p&gt;☁ &lt;strong&gt;ALB-ASG-EC2:&lt;/strong&gt; Conocer los casos de uso típicos de aplicaciones web con esta arquitectura de alta disponibilidad y cómo aplicar seguridad y certificados (ACM).&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Perfiles de instancia de EC2 y asunción de roles. Casos de uso que necesito acceder a una RDS a escribir.&lt;/li&gt;
&lt;li&gt;Cómo aplico Seguridad por VPC, Security groups, ACL.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;☁ &lt;strong&gt;Contenedores ECS, EKS:&lt;/strong&gt; Componentes fundamentales, como aplicar monitoreo y observabilidad en los dos casos para solucionar problemas (Cloudwtach y X-Ray).&lt;/p&gt;

&lt;p&gt;☁ &lt;strong&gt;Cloudfront:&lt;/strong&gt; Además de conocer frente a que servicios puede estar (ALB, S3, lambdaEdge..) centrarse en la seguridad. Ver casos de uso para aplicar seguridad entre el lector-cloudfront y cloudfront-origen.&lt;/p&gt;

&lt;p&gt;☁ &lt;strong&gt;SAM (Serveless Application Model):&lt;/strong&gt; Conocer los comandos básicos de la Cli de SAM. Hacer pequeños laboratorios con Lambda-ApiGateway- DynamoDB (caso de uso CRUD), comandos para testear localmente e implementar.&lt;/p&gt;

&lt;p&gt;☁ &lt;strong&gt;CI/CD:&lt;/strong&gt; Conocer comandos básicos y cómo se integran CodeBuild, CodeDeploy, CodePipeline.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Archivos necesarios en la raiz local de cada proyecto: buildspec.yml y appspec.yml (gestiona los hooks necesarios para la implementación).&lt;/li&gt;
&lt;li&gt;Verificación con Hooks de CodeDeploy: PreTraffic y PostTraffic.&lt;/li&gt;
&lt;li&gt;En cual podemos agregar pruebas automatizadas. En dónde podemos agregar aprobación manual.&lt;/li&gt;
&lt;li&gt;Cómo lo integro con SAM? Para separar ambientes de dev-staging-prod que opciones tengo para guardar esa parametría (configuración local, ParameterStore).&lt;/li&gt;
&lt;li&gt;Importancia de las implementaciones Canary y el desvío de tráfico por porcentaje entre producción actual y la nueva implementación .&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;☁ &lt;strong&gt;EventBridge:&lt;/strong&gt; Revisar casos de uso de Arquitecturas orientadas a eventos donde intervenga este servicio.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://www.linkedin.com/posts/theburningmonk_sns-eventbridge-have-many-overlaps-and-activity-7392206683923664896-jigu?utm_source=share&amp;amp;utm_medium=member_desktop&amp;amp;rcm=ACoAAAG0JN8B2SSu7fYsiTll9cyKiq6IrBpqnWc" rel="noopener noreferrer"&gt;Comprender la diferencia de utilizar Amazon Eventbridge o SNS&lt;/a&gt;. Revisar diferentes casos de uso.&lt;/li&gt;
&lt;li&gt;Capacidad de transformación de el payload para cada destino.&lt;/li&gt;
&lt;li&gt;Filtrado de eventos. Reglas complejas basadas en el payload del evento.&lt;/li&gt;
&lt;li&gt;Casos de uso de avisos relacionados a cumplimiento, seguridad o controles generales. Relación con Security Hub, avisos de Vencimientos de certificados (ACM).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;⭐ Recomiendo hacer laboratorio de un ejemplo similar a: venta/pedidos de producto, donde tengo un bus de eventos y diferentes reglas que ejecutan Lambdas: “registrar pedido”, “preparar pedido” y “entregar pedido”. Cada lambda con un evento posterior avisa para el siguiente paso al bus de eventos.&lt;/p&gt;

&lt;p&gt;☁ &lt;strong&gt;SQS:&lt;/strong&gt; Elemental entender sus casos de uso con Lambda, SNS y EventBridge.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Tipos Standard y FIFO. Performance de cada uno.&lt;/li&gt;
&lt;li&gt;DLQ (dead letter queue).&lt;/li&gt;
&lt;li&gt;Visibilidad de mensajes. Máximos.&lt;/li&gt;
&lt;li&gt;Retardos de entrega de mensajes: Delay. No confundir con visbilidad de mensajes.&lt;/li&gt;
&lt;li&gt;Reintentos de entrega de mensajes. Permanencia de mensajes.&lt;/li&gt;
&lt;li&gt;Borrado automático de mensajes cuando se realiza sondeo o pooling y cuando es necesario eliminar programáticamente.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;☁ &lt;strong&gt;SNS:&lt;/strong&gt; Comprender sus casos de uso con Lambda, SQS y EventBridge.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Filtrado de eventos para diferentes consumidores. Uso de atributos para el filtrado.&lt;/li&gt;
&lt;li&gt;Diferencias con SQS. SNS tiene la capacidad de entregar el mismo mensaje a diferentes consumidores.&lt;/li&gt;
&lt;li&gt;Reintentos de entrega de mensaje. Protocolos y Políticas de entrega.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;☁ &lt;strong&gt;S3:&lt;/strong&gt; Conocimiento general de todos los tipos y el tiempo de recuperación de información.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Casos de uso comunes de carga de objetos y que eventos puede disparar, ya sea en una SQS, SNS o simplemente la ejecución de una Lambda.&lt;/li&gt;
&lt;li&gt;Conocimientos de manejo de políticas de bucket (políticas basadas en recursos) no solo para permitir qué hacer a nivel bucket sino también a nivel objeto.&lt;/li&gt;
&lt;li&gt;Políticas de recursos para forzar conexiones cifradas (https), forzar realizar put ítem donde elemento ya venga encriptado. Cómo hacer para que un usuario determinado solo vea sus objetos en un bucket general.&lt;/li&gt;
&lt;li&gt;URL pre-firmadas. Duración máxima y seteo de expiración time.&lt;/li&gt;
&lt;li&gt;Sitios web estaticos. Como hacer para que sólo se puede invocar desde Cloudfront (OAC-Origin Access Control).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;⭐ Es muy útil la practica de comandos/acciones sobre S3 con AWS CLI.&lt;/p&gt;

&lt;p&gt;☁ &lt;strong&gt;ElasticBeanstalk:&lt;/strong&gt; que tipos de casos de uso puedo desarrollar. Comandos ClI EB. Por qué se Beanstalk (ventajas) ? En qué casos nos ayuda?&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Tipos de deployment, (hacer cuadro comparativo de All at once, Rolling, Immutable, Traffic splitting, Blue/green).&lt;/li&gt;
&lt;li&gt;Componentes centrales Enviroments y Applications-Application versions.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;☁ &lt;strong&gt;StepFunctions:&lt;/strong&gt; Conocer los estados y condiciones.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Cómo hace los reintentos. Revisar ejemplos del tipo sistema de pagos.&lt;/li&gt;
&lt;li&gt;Comprender que no siempre utilizar SF es la solución mas sencilla.&lt;/li&gt;
&lt;li&gt;Relación con &lt;strong&gt;Lambda, SQS y Eventbridge&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;☁ &lt;strong&gt;CDK:&lt;/strong&gt; No confundir con SDK.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Uso de AWS CDK Construct Library y AWS CDK Tookit.&lt;/li&gt;
&lt;li&gt;El modelo de Programación de Constructs. Clase CDK Aspects.&lt;/li&gt;
&lt;li&gt;Aserciones de CDK . Pruebas unitarias.&lt;/li&gt;
&lt;li&gt;Traducción a plantillas Cloudformation.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;☁ &lt;strong&gt;CloudFormation:&lt;/strong&gt; Estructura básica. Parametría. Rollback. Diferencias entre Ref o GetAtt. Pilas anidadas. La importancia de los Outputs. Fn::ImportValue.&lt;/p&gt;

&lt;p&gt;☁ &lt;strong&gt;CloudWatch:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Métricas personalizas. Grupos de logs. Logueo personalizado.&lt;/li&gt;
&lt;li&gt;Query en los logs.&lt;/li&gt;
&lt;li&gt;Uso Formato de Métrica Integrada (EMF, Embedded Metric Format).&lt;/li&gt;
&lt;li&gt;Agente cloudwatch. Su relacion con ECS, EKS y servidores on-prem. Qué recopila.&lt;/li&gt;
&lt;li&gt;Filtros Cloudwatch. Contadores. Avisos. Desde qué momento tiene vigencia.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;☁ &lt;strong&gt;CloudTrail — XRay&lt;/strong&gt; Diferencias conceptuales entre ambos. Particularmente para el caso de AWS Developer tiene mas utilidad X-Ray, entender el por qué.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Consultas en CloudTrail, relación con Amazon Athena.&lt;/li&gt;
&lt;li&gt;Auditoria de KMS en CloudTrail.&lt;/li&gt;
&lt;li&gt;Analisis/Solución cuellos de botella. Latencia.&lt;/li&gt;
&lt;li&gt;Cómo integrar &lt;strong&gt;X-Ray en ECS o EKS&lt;/strong&gt;. Sidecar X-Ray.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;☁ &lt;strong&gt;Seguridad de datos y secretos:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Claves simétricas y asimétricas. Cifrado en transito y reposo.&lt;/li&gt;
&lt;li&gt;Cómo puedo usar &lt;strong&gt;KMS&lt;/strong&gt; (claves administrados, material de clave importados, etc).&lt;/li&gt;
&lt;li&gt;Casos de uso en los que un desarrollador necesita rotar secretos de password de base de datos usando Secret Manager.&lt;/li&gt;
&lt;li&gt;Casos de uso que podemos utilizar &lt;strong&gt;Parameter Store - Secure String. Cifrado en transito y reposo&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;☁ &lt;strong&gt;STS:&lt;/strong&gt; Comprender los mecanismos de obtención de credenciales: AssumeRole, AssumeRoleWebIndentity, AssumeRoleWithSAML, GetFederationToken, GetSessionToken..&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Cómo hacer para probar asumir un rol desde AWS CLI y solucionar un problema.&lt;/li&gt;
&lt;li&gt;STS en &lt;strong&gt;Cognito&lt;/strong&gt;. Relaciones de Confianza.&lt;/li&gt;
&lt;li&gt;Invocaciones AssumeRoleWithWebIdentity por qué no requieren el uso de credenciales de seguridad de AWS.&lt;/li&gt;
&lt;li&gt;Etiquetas de Sesión (Tags).&lt;/li&gt;
&lt;li&gt;Endpoint STS Global y Regional. Su relación con la latencia.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Alguna manera útil de estudiar teoría y buscar apoyo de colegas?
&lt;/h2&gt;

&lt;p&gt;⭐ En casos de uso de servicios que mas dudas tengas, lo recomendable siempre es hacer pequeños laboratorios..seguro ya lo dije pero es muy importante!!&lt;/p&gt;

&lt;p&gt;⭐ Cuidado con las IA y la explicación profunda de los servicios o casos de uso, tienen alucinaciones!&lt;br&gt;
Recomiendo estudiar de las &lt;a href="https://docs.aws.amazon.com/es_es/" rel="noopener noreferrer"&gt;documentación oficial de Aws&lt;/a&gt;. En mi caso usé: Developer Guide y API Reference en pdf/html de los servicios para CHATEAR con ellas por medio de un cuaderno de &lt;a href="https://notebooklm.google.com/notebook/7b4cf4a5-6341-4928-a190-9cb95a32b244?authuser=1" rel="noopener noreferrer"&gt;Google NotebookLM&lt;/a&gt; (te permite agregar hasta 50 fuentes con usuario sin suscripción, adición de notas y +…es espectacular!).&lt;/p&gt;

&lt;p&gt;⭐ Practicar muchas preguntas de examen es lo que te asegura el éxito.&lt;br&gt;
En AWS SkillBuilder hay un &lt;a href="https://skillbuilder.aws/learn/VHBKSAVY53/official-practice-question-set-aws-certified-developer--associate-dvac02--espaol-latam/J88736CU3U" rel="noopener noreferrer"&gt;set gratuito&lt;/a&gt; y uno &lt;a href="https://skillbuilder.aws/learn/W6VKWVHMDN/official-practice-exam-aws-certified-developer--associate-dvac02--espaol-latam/BUY8KKYZEN" rel="noopener noreferrer"&gt;con suscripción&lt;/a&gt;.&lt;br&gt;
&lt;a href="https://www.examtopics.com/exams/amazon/aws-certified-developer-associate-dva-c02/view/" rel="noopener noreferrer"&gt;Exam Topics&lt;/a&gt; (10 gratuitas).&lt;br&gt;
Tutoriales Dojo (&lt;a href="https://portal.tutorialsdojo.com/courses/free-aws-certified-developer-associate-practice-exams-sampler/" rel="noopener noreferrer"&gt;gratuitas&lt;/a&gt;).&lt;br&gt;
Revisar algún set de Practica de Udemy. &lt;a href="https://www.udemy.com/course/dva-c02-2/" rel="noopener noreferrer"&gt;En mi caso utilice set de un instructor muy poco conocido&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;⭐ Todo proceso de certificación conviene transitarlo con apoyo de las comunidades con intereses parecidos a los nuestros. Te invito a unirte:&lt;br&gt;
📚 &lt;a href="https://www.linkedin.com/company/aws-wic-buenos-aires/posts/?feedView=all" rel="noopener noreferrer"&gt;AWS Women In Cloud Buenos Aires&lt;/a&gt; → donde ayudamos a cerrar la brecha de género en aws.&lt;br&gt;
📚 &lt;a href="https://www.linkedin.com/in/maxcloud/" rel="noopener noreferrer"&gt;La comunidad de MaxCloud — El Capitan&lt;/a&gt;&lt;br&gt;
📚 &lt;a href="https://www.linkedin.com/company/aws-women-colombia/posts/?feedView=all" rel="noopener noreferrer"&gt;AWS Women Colombia&lt;/a&gt;&lt;/p&gt;

</description>
      <category>aws</category>
      <category>developercertified</category>
      <category>awscertified</category>
    </item>
  </channel>
</rss>
