<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Luis Eduardo Lunar Guevara</title>
    <description>The latest articles on DEV Community by Luis Eduardo Lunar Guevara (@llunarg).</description>
    <link>https://dev.to/llunarg</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.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1066584%2F649d3e02-08da-47af-bad7-04c2a620bad2.jpeg</url>
      <title>DEV Community: Luis Eduardo Lunar Guevara</title>
      <link>https://dev.to/llunarg</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/llunarg"/>
    <language>en</language>
    <item>
      <title>SCS-Lab2 — Data Protection en S3 con KMS: cifrado, políticas y evidencia por CLI</title>
      <dc:creator>Luis Eduardo Lunar Guevara</dc:creator>
      <pubDate>Tue, 09 Jun 2026 02:56:41 +0000</pubDate>
      <link>https://dev.to/llunarg/scs-lab2-data-protection-en-s3-con-kms-cifrado-politicas-y-evidencia-por-cli-2bch</link>
      <guid>https://dev.to/llunarg/scs-lab2-data-protection-en-s3-con-kms-cifrado-politicas-y-evidencia-por-cli-2bch</guid>
      <description>&lt;p&gt;&lt;strong&gt;Región:&lt;/strong&gt; &lt;code&gt;us-east-1&lt;/code&gt;&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Duración estimada:&lt;/strong&gt; 35–55 minutos&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Costo-riesgo:&lt;/strong&gt; Bajo–Medio&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Certificación:&lt;/strong&gt; AWS Certified Security - Specialty (SCS-C03)&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Dominio:&lt;/strong&gt; Data Protection&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Tarea 5.2:&lt;/strong&gt; &lt;em&gt;Design and implement controls for data at rest&lt;/em&gt;  &lt;/p&gt;
&lt;h2&gt;
  
  
  Caso de uso
&lt;/h2&gt;

&lt;p&gt;Camilo viene de una clase de AWS donde hablaron de &lt;strong&gt;Data Protection&lt;/strong&gt;, pero se quedó con una duda que no se atrevió a preguntar al instructor:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“Ok, cifré… ¿cómo se ve eso en la realidad?”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;En Digital Café Luna ya están guardando facturas y reportes en S3. La Sra. Blanca quiere que nadie lea esos documentos y que Camilo pueda demostrarle, con evidencia, que los archivos están cifrados y bajo control.&lt;/p&gt;
&lt;h2&gt;
  
  
  ¿Qué vamos a construir?
&lt;/h2&gt;

&lt;p&gt;Este laboratorio busca cerrar la brecha entre teoría y operación, vas a crear:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Un &lt;strong&gt;bucket S3&lt;/strong&gt; para documentos de Café Luna.&lt;/li&gt;
&lt;li&gt;Una &lt;strong&gt;KMS key administrada por el cliente&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Cifrado por defecto en S3 usando &lt;strong&gt;SSE-KMS&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Una &lt;strong&gt;bucket policy&lt;/strong&gt; que obligue HTTPS y uploads con la KMS key del lab.&lt;/li&gt;
&lt;li&gt;Evidencia por CLI usando &lt;code&gt;head-object&lt;/code&gt;, &lt;code&gt;ServerSideEncryption&lt;/code&gt; y &lt;code&gt;SSEKMSKeyId&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Cleanup completo.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fe8knxkzrq458gql6eq2q.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%2Fe8knxkzrq458gql6eq2q.png" alt="Diagrama SCS-Lab2 — Data Protection en S3 con KMS" width="800" height="600"&gt;&lt;/a&gt;)&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Figura 1 — La Sra. Blanca quiere proteger facturas y reportes; Camilo configura S3 privado, KMS, políticas del bucket y valida la evidencia por CLI.&lt;/em&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Nota de alcance
&lt;/h2&gt;

&lt;p&gt;Este lab se enfoca en &lt;strong&gt;data at rest&lt;/strong&gt; para objetos en S3 usando &lt;strong&gt;SSE-KMS&lt;/strong&gt;. No vamos a cubrir IAM Rol, Secrets Manager, rotación de llaves ni acceso entre aplicaciones, eso lo dejamos para próximos labs.&lt;/p&gt;
&lt;h2&gt;
  
  
  Convención de nombres
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Recurso&lt;/th&gt;
&lt;th&gt;Nombre&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;KMS Key Alias&lt;/td&gt;
&lt;td&gt;&lt;code&gt;alias/scs-lab2-data-key&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;S3 Bucket&lt;/td&gt;
&lt;td&gt;&lt;code&gt;scs-lab2-data-&amp;lt;tu-sufijo&amp;gt;&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Prefix data&lt;/td&gt;
&lt;td&gt;&lt;code&gt;data/&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Prefix evidencia&lt;/td&gt;
&lt;td&gt;&lt;code&gt;evidence/&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Bucket policy file&lt;/td&gt;
&lt;td&gt;&lt;code&gt;scs-lab2-bucket-guardrails.json&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;blockquote&gt;
&lt;p&gt;Nota práctica: el nombre del bucket debe ser único globalmente. Sugerencia puedes usar 4 números aleatorios como sufijo.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;
  
  
  Requisitos previos
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Cuenta AWS con permisos para crear recursos en S3 y KMS.&lt;/li&gt;
&lt;li&gt;Región &lt;code&gt;us-east-1&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;AWS CLI configurado. Valida con &lt;code&gt;aws sts get-caller-identity&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Recomendado: usar &lt;strong&gt;CloudShell&lt;/strong&gt; para evitar problemas locales.&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;Ojo: KMS puede generar costos por key y por requests. En este lab lo mantenemos pequeño y cerramos con cleanup para evitar sustos.&lt;/p&gt;
&lt;/blockquote&gt;


&lt;h2&gt;
  
  
  Paso 1 — Preparar variables y crear la KMS key
&lt;/h2&gt;

&lt;p&gt;Este lab lo haremos por CLI, es viable, limpio y nos ayuda a ganar habilidad en el CLI.&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;REGION&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"us-east-1"&lt;/span&gt;
&lt;span class="nv"&gt;LAB_ID&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"scs-lab2"&lt;/span&gt;
&lt;span class="nv"&gt;ACCOUNT_ID&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;aws sts get-caller-identity &lt;span class="nt"&gt;--query&lt;/span&gt; Account &lt;span class="nt"&gt;--output&lt;/span&gt; text&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;

&lt;span class="nv"&gt;KMS_ALIAS&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"alias/&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;LAB_ID&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;-data-key"&lt;/span&gt;
&lt;span class="nv"&gt;KMS_DESC&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"SCS Lab2 - Data Protection baseline with S3 and KMS"&lt;/span&gt;

&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"REGION=&lt;/span&gt;&lt;span class="nv"&gt;$REGION&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"ACCOUNT_ID=&lt;/span&gt;&lt;span class="nv"&gt;$ACCOUNT_ID&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"KMS_ALIAS=&lt;/span&gt;&lt;span class="nv"&gt;$KMS_ALIAS&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Crear la KMS key:&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;KMS_KEY_ID&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;aws kms create-key &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--region&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$REGION&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--description&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$KMS_DESC&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--key-usage&lt;/span&gt; ENCRYPT_DECRYPT &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--origin&lt;/span&gt; AWS_KMS &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--tags&lt;/span&gt; &lt;span class="nv"&gt;TagKey&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;Name,TagValue&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;LAB_ID&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;-data-key"&lt;/span&gt; &lt;span class="nv"&gt;TagKey&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;Lab,TagValue&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$LAB_ID&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--query&lt;/span&gt; &lt;span class="s1"&gt;'KeyMetadata.KeyId'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--output&lt;/span&gt; text&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;

&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"KMS_KEY_ID=&lt;/span&gt;&lt;span class="nv"&gt;$KMS_KEY_ID&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Crear el alias:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;aws kms create-alias &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--region&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$REGION&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--alias-name&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$KMS_ALIAS&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--target-key-id&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$KMS_KEY_ID&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Obtener el ARN de la key:&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;KMS_KEY_ARN&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;aws kms describe-key &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--region&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$REGION&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--key-id&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$KMS_KEY_ID&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--query&lt;/span&gt; &lt;span class="s1"&gt;'KeyMetadata.Arn'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--output&lt;/span&gt; text&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;

&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"KMS_KEY_ARN=&lt;/span&gt;&lt;span class="nv"&gt;$KMS_KEY_ARN&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Validar:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;aws kms describe-key &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--region&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$REGION&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--key-id&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$KMS_KEY_ID&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--query&lt;/span&gt; &lt;span class="s1"&gt;'KeyMetadata.{KeyId:KeyId,Arn:Arn,State:KeyState,Manager:KeyManager}'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--output&lt;/span&gt; table

aws kms list-aliases &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--region&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$REGION&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--query&lt;/span&gt; &lt;span class="s2"&gt;"Aliases[?AliasName=='&lt;/span&gt;&lt;span class="nv"&gt;$KMS_ALIAS&lt;/span&gt;&lt;span class="s2"&gt;'].{AliasName:AliasName,TargetKeyId:TargetKeyId}"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--output&lt;/span&gt; table
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Checkpoint
&lt;/h3&gt;

&lt;p&gt;Valida que:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;La key aparece en estado &lt;code&gt;Enabled&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;El alias &lt;code&gt;alias/scs-lab2-data-key&lt;/code&gt; apunta a tu &lt;code&gt;KMS_KEY_ID&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;La key quedó taggeada con &lt;code&gt;Lab=scs-lab2&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fq7lsxv5fqe8oqk3szwci.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%2Fq7lsxv5fqe8oqk3szwci.png" alt="Evidencia" width="798" height="145"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkoiebfq6tlywpe5jksp1.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%2Fkoiebfq6tlywpe5jksp1.png" alt="Evidencia" width="799" height="147"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvvenleh9nsfbpw9q3w3h.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%2Fvvenleh9nsfbpw9q3w3h.png" alt="Evidencia" width="800" height="107"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fheycgif3vvwx0pi2dm4k.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%2Fheycgif3vvwx0pi2dm4k.png" alt="Evidencia" width="800" height="247"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Paso 2 — Crear el bucket S3 y habilitar cifrado por defecto
&lt;/h2&gt;

&lt;p&gt;Ahora crearemos un bucket privado y dejaremos cifrado por defecto con la KMS key del lab.&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;SUFFIX&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;printf&lt;/span&gt; &lt;span class="s2"&gt;"%04d"&lt;/span&gt; &lt;span class="k"&gt;$((&lt;/span&gt;RANDOM%10000&lt;span class="k"&gt;))&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;span class="nv"&gt;BUCKET&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;LAB_ID&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;-data-camilo-&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;SUFFIX&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;

&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"BUCKET=&lt;/span&gt;&lt;span class="nv"&gt;$BUCKET&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Crear bucket:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;aws s3api create-bucket &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--region&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$REGION&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--bucket&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$BUCKET&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Bloquear acceso público:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;aws s3api put-public-access-block &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--region&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$REGION&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--bucket&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$BUCKET&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--public-access-block-configuration&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nv"&gt;BlockPublicAcls&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;true&lt;/span&gt;,IgnorePublicAcls&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;true&lt;/span&gt;,BlockPublicPolicy&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;true&lt;/span&gt;,RestrictPublicBuckets&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;true&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Agregar tags:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;aws s3api put-bucket-tagging &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--region&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$REGION&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--bucket&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$BUCKET&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--tagging&lt;/span&gt; &lt;span class="s2"&gt;"TagSet=[{Key=Name,Value=&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;LAB_ID&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;-data-bucket},{Key=Lab,Value=&lt;/span&gt;&lt;span class="nv"&gt;$LAB_ID&lt;/span&gt;&lt;span class="s2"&gt;}]"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Configurar cifrado por defecto con SSE-KMS:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;aws s3api put-bucket-encryption &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--region&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$REGION&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--bucket&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$BUCKET&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--server-side-encryption-configuration&lt;/span&gt; &lt;span class="s2"&gt;"{
    &lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;Rules&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;: [
      {
        &lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;ApplyServerSideEncryptionByDefault&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;: {
          &lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;SSEAlgorithm&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;: &lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;aws:kms&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;,
          &lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;KMSMasterKeyID&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;: &lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="nv"&gt;$KMS_KEY_ARN&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;
        },
        &lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;BucketKeyEnabled&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;: true
      }
    ]
  }"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Validar:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;aws s3api head-bucket &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--region&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$REGION&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--bucket&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$BUCKET&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;

aws s3api get-public-access-block &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--region&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$REGION&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--bucket&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$BUCKET&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;

aws s3api get-bucket-encryption &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--region&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$REGION&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--bucket&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$BUCKET&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Checkpoint
&lt;/h3&gt;

&lt;p&gt;Valida que:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;El bucket existe.&lt;/li&gt;
&lt;li&gt;Public Access Block está activo.&lt;/li&gt;
&lt;li&gt;Default encryption está en &lt;code&gt;aws:kms&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;La KMS key corresponde a la key del lab.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fp2q0ikl2o5sv90sarcsg.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%2Fp2q0ikl2o5sv90sarcsg.png" alt="Evidencia" width="798" height="104"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftr5iul583qz6qbfc6n6p.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%2Ftr5iul583qz6qbfc6n6p.png" alt="Evidencia" width="799" height="126"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsm318096eogz492p7y40.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%2Fsm318096eogz492p7y40.png" alt="Evidencia" width="800" height="138"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&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%2Fu4s2g8y5hmnx3lan4hh1.png" alt="Evidencia" width="800" height="332"&gt;
&lt;/h2&gt;

&lt;h2&gt;
  
  
  Paso 3 — Subir un objeto cifrado con KMS y validarlo
&lt;/h2&gt;

&lt;p&gt;Ahora vamos a subir una factura de prueba y comprobar con CLI cómo quedó guardada.&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;echo&lt;/span&gt; &lt;span class="s2"&gt;"Factura demo - &lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;date&lt;/span&gt; &lt;span class="nt"&gt;-u&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; factura-demo.txt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Subir el objeto usando SSE-KMS con la key del lab:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;aws s3 &lt;span class="nb"&gt;cp &lt;/span&gt;factura-demo.txt &lt;span class="s2"&gt;"s3://&lt;/span&gt;&lt;span class="nv"&gt;$BUCKET&lt;/span&gt;&lt;span class="s2"&gt;/data/factura-demo.txt"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--region&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$REGION&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--sse&lt;/span&gt; aws:kms &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--sse-kms-key-id&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$KMS_KEY_ARN&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Validar el objeto:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;aws s3api head-object &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--region&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$REGION&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--bucket&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$BUCKET&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--key&lt;/span&gt; &lt;span class="s2"&gt;"data/factura-demo.txt"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--query&lt;/span&gt; &lt;span class="s2"&gt;"{SSE:ServerSideEncryption,KMSKey:SSEKMSKeyId}"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--output&lt;/span&gt; table
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Comparar alias contra la key real:&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;KEY_ID_FROM_ALIAS&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;aws kms list-aliases &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--region&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$REGION&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--query&lt;/span&gt; &lt;span class="s2"&gt;"Aliases[?AliasName=='&lt;/span&gt;&lt;span class="nv"&gt;$KMS_ALIAS&lt;/span&gt;&lt;span class="s2"&gt;'].TargetKeyId"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--output&lt;/span&gt; text&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;

&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Alias apunta a KeyId: &lt;/span&gt;&lt;span class="nv"&gt;$KEY_ID_FROM_ALIAS&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Key creada en el lab: &lt;/span&gt;&lt;span class="nv"&gt;$KMS_KEY_ID&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Checkpoint
&lt;/h3&gt;

&lt;p&gt;Valida que:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;head-object&lt;/code&gt; muestra &lt;code&gt;SSE = aws:kms&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;SSEKMSKeyId&lt;/code&gt; apunta a la KMS key del lab.&lt;/li&gt;
&lt;li&gt;El alias apunta al mismo &lt;code&gt;KMS_KEY_ID&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fi5mn5cyjbd0uvgtzodat.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%2Fi5mn5cyjbd0uvgtzodat.png" alt="Evidencia" width="799" height="297"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Paso 4 — Aplicar guardrails: HTTPS y KMS key correcta
&lt;/h2&gt;

&lt;p&gt;Ya tenemos cifrado por defecto, pero ahora vamos a poner guardrails para reducir errores humanos:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;bloquear tráfico sin HTTPS;&lt;/li&gt;
&lt;li&gt;bloquear uploads sin SSE-KMS explícito;&lt;/li&gt;
&lt;li&gt;bloquear uploads con una KMS key diferente a la del lab.&lt;/li&gt;
&lt;/ol&gt;

&lt;blockquote&gt;
&lt;p&gt;Ojo: este guardrail exige intención explícita en el upload. Aunque el bucket tenga default encryption, vamos a pedir que se envíe los headers de SSE-KMS y la key correcta.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Crear la bucket policy:&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;cat&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; scs-lab2-bucket-guardrails.json &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class="no"&gt;EOF&lt;/span&gt;&lt;span class="sh"&gt;
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "DenyInsecureTransport",
      "Effect": "Deny",
      "Principal": "*",
      "Action": "s3:*",
      "Resource": [
        "arn:aws:s3:::&lt;/span&gt;&lt;span class="nv"&gt;$BUCKET&lt;/span&gt;&lt;span class="sh"&gt;",
        "arn:aws:s3:::&lt;/span&gt;&lt;span class="nv"&gt;$BUCKET&lt;/span&gt;&lt;span class="sh"&gt;/*"
      ],
      "Condition": {
        "Bool": {
          "aws:SecureTransport": "false"
        }
      }
    },
    {
      "Sid": "DenyPutWithoutKMSEncryption",
      "Effect": "Deny",
      "Principal": "*",
      "Action": "s3:PutObject",
      "Resource": "arn:aws:s3:::&lt;/span&gt;&lt;span class="nv"&gt;$BUCKET&lt;/span&gt;&lt;span class="sh"&gt;/*",
      "Condition": {
        "StringNotEquals": {
          "s3:x-amz-server-side-encryption": "aws:kms"
        }
      }
    },
    {
      "Sid": "DenyPutWithWrongKMSKey",
      "Effect": "Deny",
      "Principal": "*",
      "Action": "s3:PutObject",
      "Resource": "arn:aws:s3:::&lt;/span&gt;&lt;span class="nv"&gt;$BUCKET&lt;/span&gt;&lt;span class="sh"&gt;/*",
      "Condition": {
        "StringNotEquals": {
          "s3:x-amz-server-side-encryption-aws-kms-key-id": "&lt;/span&gt;&lt;span class="nv"&gt;$KMS_KEY_ARN&lt;/span&gt;&lt;span class="sh"&gt;"
        }
      }
    }
  ]
}
&lt;/span&gt;&lt;span class="no"&gt;EOF
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Aplicar la policy:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;aws s3api put-bucket-policy &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--region&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$REGION&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--bucket&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$BUCKET&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--policy&lt;/span&gt; file://scs-lab2-bucket-guardrails.json
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Checkpoint
&lt;/h3&gt;

&lt;p&gt;Valida que &lt;code&gt;get-bucket-policy&lt;/code&gt; devuelve la policy sin error.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;aws s3api get-bucket-policy &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--region&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$REGION&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--bucket&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$BUCKET&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--query&lt;/span&gt; Policy &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--output&lt;/span&gt; text
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&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%2Fymmgidivnhj1sux2dx5h.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%2Fymmgidivnhj1sux2dx5h.png" alt="Evidencia" width="800" height="201"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Paso 5 — Probar el guardrail
&lt;/h2&gt;

&lt;p&gt;Aquí hacemos la prueba màs importante, demostrar que el bucket bloquea uploads inseguros y acepta uploads con &lt;code&gt;aws:kms&lt;/code&gt; y la key correcta.&lt;/p&gt;

&lt;h3&gt;
  
  
  Intento incorrecto: debe fallar
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"prueba sin SSE-KMS - &lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;date&lt;/span&gt; &lt;span class="nt"&gt;-u&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; sin-kms.txt

aws s3 &lt;span class="nb"&gt;cp &lt;/span&gt;sin-kms.txt &lt;span class="s2"&gt;"s3://&lt;/span&gt;&lt;span class="nv"&gt;$BUCKET&lt;/span&gt;&lt;span class="s2"&gt;/data/sin-kms.txt"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--region&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$REGION&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;La salida esperada es un error &lt;code&gt;AccessDenied&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Intento correcto: debe funcionar
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;aws s3 &lt;span class="nb"&gt;cp &lt;/span&gt;sin-kms.txt &lt;span class="s2"&gt;"s3://&lt;/span&gt;&lt;span class="nv"&gt;$BUCKET&lt;/span&gt;&lt;span class="s2"&gt;/data/con-kms.txt"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--region&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$REGION&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--sse&lt;/span&gt; aws:kms &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--sse-kms-key-id&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$KMS_KEY_ARN&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Evidencia final
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;aws s3api head-object &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--region&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$REGION&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--bucket&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$BUCKET&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--key&lt;/span&gt; &lt;span class="s2"&gt;"data/con-kms.txt"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--query&lt;/span&gt; &lt;span class="s2"&gt;"{SSE:ServerSideEncryption,KMSKey:SSEKMSKeyId}"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--output&lt;/span&gt; table
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Checkpoint
&lt;/h3&gt;

&lt;p&gt;Valida que:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;El upload sin SSE-KMS falla.&lt;/li&gt;
&lt;li&gt;El upload con &lt;code&gt;--sse aws:kms&lt;/code&gt; funciona.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;head-object&lt;/code&gt; muestra &lt;code&gt;SSE = aws:kms&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;SSEKMSKeyId&lt;/code&gt; apunta a la key del lab.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F707yaprtf3dcsog3qu6o.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%2F707yaprtf3dcsog3qu6o.png" alt="Evidencia" width="799" height="156"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fx1nuvnuf8vcvwnr0t00p.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%2Fx1nuvnuf8vcvwnr0t00p.png" alt="Evidencia" width="799" height="181"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&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%2F0zaitboy1yu7vpykrws0.png" alt="Evidencia" width="798" height="195"&gt;
&lt;/h2&gt;

&lt;h2&gt;
  
  
  Clean up completo
&lt;/h2&gt;

&lt;p&gt;Este lab deja S3 y KMS configurados. Para no dejar costos ni recursos colgados, eliminamos en este orden:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;objetos;&lt;/li&gt;
&lt;li&gt;bucket policy;&lt;/li&gt;
&lt;li&gt;bucket;&lt;/li&gt;
&lt;li&gt;alias;&lt;/li&gt;
&lt;li&gt;KMS key con borrado programado.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Vaciar bucket:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;aws s3 &lt;span class="nb"&gt;rm&lt;/span&gt; &lt;span class="s2"&gt;"s3://&lt;/span&gt;&lt;span class="nv"&gt;$BUCKET&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--region&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$REGION&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--recursive&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Quitar bucket policy:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;aws s3api delete-bucket-policy &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--region&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$REGION&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--bucket&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$BUCKET&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Borrar bucket:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;aws s3api delete-bucket &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--region&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$REGION&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--bucket&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$BUCKET&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Borrar alias:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;aws kms delete-alias &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--region&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$REGION&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--alias-name&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$KMS_ALIAS&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Programar borrado de la KMS key:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;aws kms schedule-key-deletion &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--region&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$REGION&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--key-id&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$KMS_KEY_ID&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--pending-window-in-days&lt;/span&gt; 7
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Validar cleanup:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;aws s3api head-bucket &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--region&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$REGION&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--bucket&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$BUCKET&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; 2&amp;gt;&amp;amp;1 | &lt;span class="nb"&gt;tail&lt;/span&gt; &lt;span class="nt"&gt;-n&lt;/span&gt; 2
&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;aws kms list-aliases &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--region&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$REGION&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--query&lt;/span&gt; &lt;span class="s2"&gt;"Aliases[?AliasName=='&lt;/span&gt;&lt;span class="nv"&gt;$KMS_ALIAS&lt;/span&gt;&lt;span class="s2"&gt;']"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--output&lt;/span&gt; table
&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;aws kms describe-key &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--region&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$REGION&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--key-id&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$KMS_KEY_ID&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--query&lt;/span&gt; &lt;span class="s2"&gt;"KeyMetadata.KeyState"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--output&lt;/span&gt; text
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Ojo: &lt;code&gt;404 Not Found&lt;/code&gt; en el bucket es esperado si ya fue eliminado. En KMS, la key debe quedar en &lt;code&gt;PendingDeletion&lt;/code&gt;.&lt;/p&gt;
&lt;/blockquote&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%2F15vrmzkvyqodsz0c5oui.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%2F15vrmzkvyqodsz0c5oui.png" alt="Evidencia" width="798" height="183"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Troubleshooting
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;AccessDenied al subir a S3:&lt;/strong&gt; revisa si falta &lt;code&gt;--sse aws:kms&lt;/code&gt; o si estás usando una KMS key distinta a la del lab.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;KMS alias no existe:&lt;/strong&gt; valida con &lt;code&gt;aws kms list-aliases&lt;/code&gt; y confirma &lt;code&gt;alias/scs-lab2-data-key&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;head-object&lt;/code&gt; no muestra &lt;code&gt;aws:kms&lt;/code&gt;:&lt;/strong&gt; el objeto pudo subirse sin SSE-KMS. Vuelve a subirlo forzando &lt;code&gt;--sse aws:kms&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;No puedes borrar el bucket:&lt;/strong&gt; elimina primero objetos, luego bucket policy y vuelve a intentar.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;No puedes borrar la key de inmediato:&lt;/strong&gt; KMS requiere borrado programado, mínimo 7 días.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Well-Architected lens: ¿Qué aplicamos aquí?
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Security:&lt;/strong&gt; cifrado en reposo con SSE-KMS y guardrails explícitos para reducir errores humanos.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Operational Excellence:&lt;/strong&gt; evidencia por CLI para auditar sin depender de “fe en la consola”.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cost Optimization:&lt;/strong&gt; lab corto y cleanup completo para controlar S3 y KMS.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Reliability:&lt;/strong&gt; guardrails ayudan a evitar que datos entren mal configurados.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Resultado esperado
&lt;/h2&gt;

&lt;p&gt;Al finalizar este laboratorio, Camilo puede demostrar con evidencia:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;que un objeto en S3 quedó cifrado con &lt;code&gt;aws:kms&lt;/code&gt;;&lt;/li&gt;
&lt;li&gt;qué KMS key lo cifró usando &lt;code&gt;SSEKMSKeyId&lt;/code&gt;;&lt;/li&gt;
&lt;li&gt;que el bucket bloquea prácticas inseguras, como uploads sin SSE-KMS o con una key distinta.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;La idea no era solo “activar cifrado”, sino entender cómo se ve, cómo se valida y cómo se controla.&lt;/p&gt;




&lt;h2&gt;
  
  
  Referencias oficiales
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://docs.aws.amazon.com/AmazonS3/latest/userguide/serv-side-encryption.html" rel="noopener noreferrer"&gt;Protecting data using server-side encryption&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.aws.amazon.com/AmazonS3/latest/userguide/UsingKMSEncryption.html" rel="noopener noreferrer"&gt;Using server-side encryption with AWS KMS keys&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.aws.amazon.com/kms/latest/developerguide/keys.html" rel="noopener noreferrer"&gt;AWS KMS keys&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.aws.amazon.com/kms/latest/developerguide/kms-alias.html" rel="noopener noreferrer"&gt;Using aliases in AWS KMS&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.aws.amazon.com/AmazonS3/latest/userguide/example-bucket-policies.html" rel="noopener noreferrer"&gt;Bucket policy examples&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.aws.amazon.com/AmazonS3/latest/userguide/amazon-s3-policy-keys.html" rel="noopener noreferrer"&gt;Amazon S3 policy keys&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  ¿Qué viene en el próximo lab?
&lt;/h2&gt;

&lt;p&gt;Camilo ya vio cómo funciona KMS, cómo se cifra un objeto, cómo se valida por CLI y cómo se aplican guardrails (básicos) en S3.&lt;/p&gt;

&lt;p&gt;En el próximo lab subimos el nivel: trabajaremos con &lt;strong&gt;IAM Roles y políticas de acceso&lt;/strong&gt; para que solo los componentes correctos puedan leer o escribir datos.&lt;/p&gt;

&lt;p&gt;Nada de credenciales sueltas por ahí.&lt;/p&gt;

&lt;p&gt;Nos vemos en el próximo laboratorio de &lt;strong&gt;Digital Café Luna&lt;/strong&gt;.&lt;/p&gt;




</description>
      <category>aws</category>
      <category>cloudskills</category>
      <category>tutorial</category>
      <category>kms</category>
    </item>
    <item>
      <title>SAA-Lab1 — Scaling en AWS (baseline): ALB + Auto Scaling + CloudFront</title>
      <dc:creator>Luis Eduardo Lunar Guevara</dc:creator>
      <pubDate>Mon, 01 Jun 2026 23:00:00 +0000</pubDate>
      <link>https://dev.to/llunarg/saa-lab1-scaling-en-aws-baseline-alb-auto-scaling-cloudfront-3pc3</link>
      <guid>https://dev.to/llunarg/saa-lab1-scaling-en-aws-baseline-alb-auto-scaling-cloudfront-3pc3</guid>
      <description>&lt;p&gt;&lt;strong&gt;Región:&lt;/strong&gt; &lt;code&gt;us-east-1&lt;/code&gt;&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Duración estimada:&lt;/strong&gt; 35–55 minutos&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Costo-riesgo:&lt;/strong&gt; Medio&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Certificación:&lt;/strong&gt; AWS Certified Solutions Architect - Associate (SAA-C03)&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Dominio:&lt;/strong&gt; Design Secure Architectures&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Tarea 1.2:&lt;/strong&gt; &lt;em&gt;Design secure workloads and applications&lt;/em&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Caso de uso
&lt;/h2&gt;

&lt;p&gt;La plataforma de Digital Café Luna venía bastante estable… hasta que se les ocurrió hacer un evento especial de fin de semana. El tráfico sube, la aplicación empieza a sentirse lenta y Camilo se da cuenta que una sola instancia no es suficiente.&lt;/p&gt;

&lt;p&gt;La Sra. Blanca no entiende de escalamiento vertical y horizontal, ella solo quiere algo:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“Que el sistema no se caiga justo cuando más estamos vendiendo.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Este laboratorio es el salto de un servidor único a un baseline más realista: &lt;strong&gt;Application Load Balancer&lt;/strong&gt;, &lt;strong&gt;Auto Scaling Group&lt;/strong&gt; y &lt;strong&gt;CloudFront&lt;/strong&gt; trabajando juntos para absorber variaciones de tráfico.&lt;/p&gt;

&lt;p&gt;No vamos a montar una arquitectura perfecta y mucho menos lista para producción.&lt;/p&gt;
&lt;h2&gt;
  
  
  ¿Qué vamos a construir?
&lt;/h2&gt;

&lt;p&gt;En este laboratorio vas a crear:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Un &lt;strong&gt;Application Load Balancer&lt;/strong&gt; como punto de entrada.&lt;/li&gt;
&lt;li&gt;Un &lt;strong&gt;Target Group&lt;/strong&gt; para enrutar tráfico hacia instancias EC2.&lt;/li&gt;
&lt;li&gt;Un &lt;strong&gt;Launch Template&lt;/strong&gt; con una app básica en NGINX.&lt;/li&gt;
&lt;li&gt;Un &lt;strong&gt;Auto Scaling Group&lt;/strong&gt; con capacidad mínima distribuida en dos subnets.&lt;/li&gt;
&lt;li&gt;Una &lt;strong&gt;distribución de CloudFront&lt;/strong&gt; apuntando al ALB.&lt;/li&gt;
&lt;li&gt;Validaciones del flujo &lt;code&gt;Usuario → CloudFront → ALB → EC2&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Cleanup completo.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgjz8sqtn6ybmcmomeg6o.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%2Fgjz8sqtn6ybmcmomeg6o.png" alt="Diagrama SAA-Lab1 — ALB + Auto Scaling + CloudFront" width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Figura 1 — CloudFront recibe la solicitud, la envía al ALB y el ALB distribuye tráfico hacia instancias EC2 administradas por Auto Scaling.&lt;/em&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Nota de alcance
&lt;/h2&gt;

&lt;p&gt;Usaremos la &lt;strong&gt;default VPC&lt;/strong&gt; para hacer las cosas mas simple y enfocarnos en el objetivo principal.&lt;/p&gt;

&lt;p&gt;En labs posteriores podemos madurar esto con &lt;strong&gt;SSM Session Manager&lt;/strong&gt;, HTTPS end-to-end, WAF y controles más finos. Por ahora queremos entender el flujo base y verlo funcionando.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Ojo: en este baseline el ALB seguirá siendo público. CloudFront estará delante, pero no vamos a restringir todavía el ALB para aceptar tráfico únicamente desde CloudFront.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;
  
  
  Convención de nombres
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Recurso&lt;/th&gt;
&lt;th&gt;Nombre&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;ALB&lt;/td&gt;
&lt;td&gt;&lt;code&gt;saa-lab1-alb&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Target Group&lt;/td&gt;
&lt;td&gt;&lt;code&gt;saa-lab1-tg&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Launch Template&lt;/td&gt;
&lt;td&gt;&lt;code&gt;saa-lab1-lt&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Auto Scaling Group&lt;/td&gt;
&lt;td&gt;&lt;code&gt;saa-lab1-asg&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Security Group ALB&lt;/td&gt;
&lt;td&gt;&lt;code&gt;saa-lab1-alb-sg&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Security Group App/EC2&lt;/td&gt;
&lt;td&gt;&lt;code&gt;saa-lab1-app-sg&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;CloudFront Distribution&lt;/td&gt;
&lt;td&gt;&lt;code&gt;saa-lab1-cf&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Tag estándar&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;Name=&amp;lt;recurso&amp;gt;&lt;/code&gt; y &lt;code&gt;Lab=saa-lab1&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;
&lt;h2&gt;
  
  
  Requisitos previos
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Región &lt;code&gt;us-east-1&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Permisos para EC2, Load Balancing, Auto Scaling y CloudFront.&lt;/li&gt;
&lt;li&gt;Default VPC disponible.&lt;/li&gt;
&lt;li&gt;Acceso a AWS Console y CloudShell o AWS CLI local.&lt;/li&gt;
&lt;/ul&gt;


&lt;h2&gt;
  
  
  Paso 1 — Identificar VPC y subnets
&lt;/h2&gt;

&lt;p&gt;Necesitamos una VPC y al menos dos subnets en AZ distintas.&lt;/p&gt;

&lt;p&gt;En AWS Console:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Ve a &lt;strong&gt;VPC → Your VPCs&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Verifica que estás en &lt;code&gt;us-east-1&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Usa la &lt;strong&gt;Default VPC&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Ve a &lt;strong&gt;VPC → Subnets&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Identifica dos subnets en AZ distintas, por ejemplo &lt;code&gt;us-east-1a&lt;/code&gt; y &lt;code&gt;us-east-1b&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  Checkpoint
&lt;/h3&gt;

&lt;p&gt;Valida que:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Tienes una VPC en &lt;code&gt;us-east-1&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Identificaste dos subnets en AZ distintas.&lt;/li&gt;
&lt;/ul&gt;


&lt;h2&gt;
  
  
  Paso 2 — Crear Security Groups
&lt;/h2&gt;

&lt;p&gt;Crearemos dos Security Groups: uno para el ALB y otro para las instancias de aplicación.&lt;/p&gt;
&lt;h3&gt;
  
  
  Desde la consola
&lt;/h3&gt;
&lt;h4&gt;
  
  
  Security Group del ALB
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Name:&lt;/strong&gt; &lt;code&gt;saa-lab1-alb-sg&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Inbound:&lt;/strong&gt; HTTP &lt;code&gt;80&lt;/code&gt; desde &lt;code&gt;0.0.0.0/0&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Outbound:&lt;/strong&gt; default&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Tags:&lt;/strong&gt; &lt;code&gt;Name=saa-lab1-alb-sg&lt;/code&gt;, &lt;code&gt;Lab=saa-lab1&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;
  
  
  Security Group App/EC2
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Name:&lt;/strong&gt; &lt;code&gt;saa-lab1-app-sg&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Inbound:&lt;/strong&gt; HTTP &lt;code&gt;80&lt;/code&gt; desde el Security Group del ALB&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Outbound:&lt;/strong&gt; default&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Tags:&lt;/strong&gt; &lt;code&gt;Name=saa-lab1-app-sg&lt;/code&gt;, &lt;code&gt;Lab=saa-lab1&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;Mosca con esto: las instancias no deben recibir HTTP directo desde Internet, el tráfico debe entrar por el ALB.&lt;/p&gt;
&lt;/blockquote&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%2Fcx4bine882t3iv08t586.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%2Fcx4bine882t3iv08t586.png" alt="Security Group del ALB" width="800" height="247"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Figura 2 — Security Group del ALB.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8t9moew4tsbrc5fs9npo.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%2F8t9moew4tsbrc5fs9npo.png" alt="Security Group App/EC2" width="800" height="253"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Figura 3 — Security Group App/EC2.&lt;/em&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Checkpoint
&lt;/h3&gt;

&lt;p&gt;Valida que:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;El ALB SG permite HTTP desde Internet.&lt;/li&gt;
&lt;li&gt;El App SG permite HTTP solo desde el SG del ALB.&lt;/li&gt;
&lt;/ul&gt;


&lt;h2&gt;
  
  
  Paso 3 — Crear Target Group, Launch Template y Auto Scaling Group
&lt;/h2&gt;

&lt;p&gt;El ALB enruta tráfico hacia un &lt;strong&gt;Target Group&lt;/strong&gt;. El &lt;strong&gt;Auto Scaling Group&lt;/strong&gt; registra ahí sus instancias.&lt;/p&gt;
&lt;h3&gt;
  
  
  Crear Target Group
&lt;/h3&gt;

&lt;p&gt;En AWS Console:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Ve a &lt;strong&gt;EC2 → Target Groups → Create target group&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Target type:&lt;/strong&gt; &lt;code&gt;Instances&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Name:&lt;/strong&gt; &lt;code&gt;saa-lab1-tg&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Protocol/Port:&lt;/strong&gt; &lt;code&gt;HTTP : 80&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;VPC:&lt;/strong&gt; default VPC&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Health check path:&lt;/strong&gt; &lt;code&gt;/&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Tags: &lt;code&gt;Name=saa-lab1-tg&lt;/code&gt;, &lt;code&gt;Lab=saa-lab1&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7d0lx0x4r3ieq49mjo7i.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%2F7d0lx0x4r3ieq49mjo7i.png" alt="Target Groups" width="799" height="391"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Figura 4 — Target Groups.&lt;/em&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Crear Launch Template
&lt;/h3&gt;

&lt;p&gt;En &lt;strong&gt;EC2 → Launch Templates → Create launch template&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Name:&lt;/strong&gt; &lt;code&gt;saa-lab1-lt&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;AMI:&lt;/strong&gt; Amazon Linux 2023&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Instance type:&lt;/strong&gt; &lt;code&gt;t3.nano&lt;/code&gt; o &lt;code&gt;t3.micro&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Key pair:&lt;/strong&gt; None&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Subnet:&lt;/strong&gt; Don’t include&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Security group:&lt;/strong&gt; &lt;code&gt;saa-lab1-app-sg&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Auto-assign public IP:&lt;/strong&gt; Enable&lt;/li&gt;
&lt;li&gt;Tags: &lt;code&gt;Name=saa-lab1-lt&lt;/code&gt;, &lt;code&gt;Lab=saa-lab1&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;User data:&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;#!/bin/bash&lt;/span&gt;
&lt;span class="nb"&gt;set&lt;/span&gt; &lt;span class="nt"&gt;-euo&lt;/span&gt; pipefail
dnf &lt;span class="nt"&gt;-y&lt;/span&gt; update
dnf &lt;span class="nt"&gt;-y&lt;/span&gt; &lt;span class="nb"&gt;install &lt;/span&gt;nginx

&lt;span class="nb"&gt;cat&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; /usr/share/nginx/html/index.html &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;HTML&lt;/span&gt;&lt;span class="sh"&gt;
&amp;lt;!doctype html&amp;gt;
&amp;lt;html&amp;gt;
&amp;lt;head&amp;gt;&amp;lt;meta charset="utf-8"&amp;gt;&amp;lt;title&amp;gt;Digital Cafe Luna&amp;lt;/title&amp;gt;&amp;lt;/head&amp;gt;
&amp;lt;body&amp;gt;
&amp;lt;h2&amp;gt;Digital Cafe Luna - OK&amp;lt;/h2&amp;gt;
&amp;lt;p&amp;gt;Host: &lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;hostname&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="sh"&gt;&amp;lt;/p&amp;gt;
&amp;lt;p&amp;gt;Time: &lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;date&lt;/span&gt; &lt;span class="nt"&gt;-u&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="sh"&gt;&amp;lt;/p&amp;gt;
&amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/span&gt;&lt;span class="no"&gt;HTML

&lt;/span&gt;systemctl &lt;span class="nb"&gt;enable&lt;/span&gt; &lt;span class="nt"&gt;--now&lt;/span&gt; nginx
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&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%2F7smgsjh2e1syx1q7ve42.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%2F7smgsjh2e1syx1q7ve42.png" alt="Launch Templates" width="800" height="398"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Figura 5 — Launch Templates.&lt;/em&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Crear Auto Scaling Group
&lt;/h3&gt;

&lt;p&gt;En &lt;strong&gt;EC2 → Auto Scaling groups → Create&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Name:&lt;/strong&gt; &lt;code&gt;saa-lab1-asg&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Launch template:&lt;/strong&gt; &lt;code&gt;saa-lab1-lt&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;VPC:&lt;/strong&gt; default VPC&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Subnets:&lt;/strong&gt; dos subnets en AZ distintas&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Attach to load balancer:&lt;/strong&gt; Existing target group → &lt;code&gt;saa-lab1-tg&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Health checks:&lt;/strong&gt; ELB&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Grace period:&lt;/strong&gt; 60–120s&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Desired:&lt;/strong&gt; 2&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Min:&lt;/strong&gt; 2&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Max:&lt;/strong&gt; 4&lt;/li&gt;
&lt;li&gt;Tags: &lt;code&gt;Name=saa-lab1-asg&lt;/code&gt;, &lt;code&gt;Lab=saa-lab1&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Focfo7b95tbuuub8vx5xt.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%2Focfo7b95tbuuub8vx5xt.png" alt="Auto Scaling groups" width="800" height="349"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Figura 6 — Auto Scaling groups.&lt;/em&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Checkpoint
&lt;/h3&gt;

&lt;p&gt;Valida que:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;El ASG tiene dos instancias.&lt;/li&gt;
&lt;li&gt;El Target Group muestra targets healthy.&lt;/li&gt;
&lt;li&gt;Las instancias solo reciben HTTP desde el ALB SG.&lt;/li&gt;
&lt;/ul&gt;


&lt;h2&gt;
  
  
  Paso 4 — Crear el Application Load Balancer
&lt;/h2&gt;

&lt;p&gt;Ahora crearemos el ALB, que será el origin de CloudFront y distribuirá tráfico al Target Group.&lt;/p&gt;

&lt;p&gt;En AWS Console:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Ve a &lt;strong&gt;EC2 → Load Balancers → Create load balancer&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Selecciona &lt;strong&gt;Application Load Balancer&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Name:&lt;/strong&gt; &lt;code&gt;saa-lab1-alb&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Scheme:&lt;/strong&gt; Internet-facing&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;IP address type:&lt;/strong&gt; IPv4&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;VPC:&lt;/strong&gt; default VPC&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Mappings:&lt;/strong&gt; dos subnets en AZ distintas&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Security Group:&lt;/strong&gt; &lt;code&gt;saa-lab1-alb-sg&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Listener:&lt;/strong&gt; HTTP &lt;code&gt;80&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Default action:&lt;/strong&gt; Forward to &lt;code&gt;saa-lab1-tg&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxvxb9tedb042wiu80cog.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%2Fxvxb9tedb042wiu80cog.png" alt="Load Balancers" width="799" height="366"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Figura 7 — Load Balancers.&lt;/em&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Checkpoint
&lt;/h3&gt;

&lt;p&gt;Valida que:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;El ALB está &lt;code&gt;Active&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;El listener HTTP &lt;code&gt;80&lt;/code&gt; envía tráfico a &lt;code&gt;saa-lab1-tg&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;El DNS del ALB muestra &lt;code&gt;Digital Cafe Luna - OK&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;


&lt;h2&gt;
  
  
  Paso 5 — Crear CloudFront delante del ALB
&lt;/h2&gt;

&lt;p&gt;Vamos a poner &lt;strong&gt;CloudFront&lt;/strong&gt; delante del ALB para mostrar cómo una distribución global puede servir como entrada de la aplicación.&lt;/p&gt;

&lt;p&gt;En este lab la carga no justifica CloudFront por sí sola, el objetivo de configurarlo es meramente didáctico.&lt;/p&gt;
&lt;h3&gt;
  
  
  Desde la consola
&lt;/h3&gt;

&lt;p&gt;Ve a &lt;strong&gt;CloudFront → Distributions → Create distribution&lt;/strong&gt;.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Plan:&lt;/strong&gt; &lt;code&gt;Pay as you go&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Distribution name:&lt;/strong&gt; &lt;code&gt;saa-lab1-cf&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Description:&lt;/strong&gt; &lt;code&gt;Digital Cafe Luna - scaling baseline&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Distribution type:&lt;/strong&gt; &lt;code&gt;Single website or app&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Domain:&lt;/strong&gt; vacío, usaremos &lt;code&gt;xxxxx.cloudfront.net&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Origin type:&lt;/strong&gt; Elastic Load Balancer&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Origin:&lt;/strong&gt; DNS del ALB&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Origin protocol policy:&lt;/strong&gt; HTTP only&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;HTTP port:&lt;/strong&gt; 80&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cache settings:&lt;/strong&gt; recommended/default&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Security protections:&lt;/strong&gt; deja lo incluido&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Rate limiting:&lt;/strong&gt; apagado para este lab&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;Ojo: &lt;code&gt;Pay as you go&lt;/code&gt; no significa “gratis”. CloudFront puede generar costos por requests, transferencia y uso. Haz el cleanup y no pasa nada.&lt;/p&gt;

&lt;p&gt;Ojo: &lt;code&gt;HTTP only&lt;/code&gt; funciona porque el ALB escucha por HTTP. En producción, la mejora natural sería HTTPS end-to-end.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;
  
  
  Checkpoint
&lt;/h3&gt;

&lt;p&gt;Valida que:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;La distribución pasa de &lt;code&gt;Deploying&lt;/code&gt; a &lt;code&gt;Enabled&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Tienes un dominio tipo &lt;code&gt;xxxxx.cloudfront.net&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Al abrir &lt;code&gt;https://xxxxx.cloudfront.net&lt;/code&gt;, ves &lt;code&gt;Digital Cafe Luna - OK&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;


&lt;h2&gt;
  
  
  Paso 6 — Validación final
&lt;/h2&gt;

&lt;p&gt;Confirma el flujo completo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Usuario → CloudFront → ALB → Target Group → EC2 en Auto Scaling Group
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Desde tu terminal:&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;CF_DOMAIN&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"xxxxx.cloudfront.net"&lt;/span&gt;

curl &lt;span class="nt"&gt;-I&lt;/span&gt; &lt;span class="s2"&gt;"https://&lt;/span&gt;&lt;span class="nv"&gt;$CF_DOMAIN&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
curl &lt;span class="s2"&gt;"https://&lt;/span&gt;&lt;span class="nv"&gt;$CF_DOMAIN&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Checkpoint
&lt;/h3&gt;

&lt;p&gt;Valida que:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;CloudFront responde.&lt;/li&gt;
&lt;li&gt;El ALB sigue activo.&lt;/li&gt;
&lt;li&gt;El Target Group tiene targets healthy.&lt;/li&gt;
&lt;li&gt;La página muestra &lt;code&gt;Digital Cafe Luna - OK&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Clean up completo — SAA-Lab1
&lt;/h2&gt;

&lt;p&gt;Elimina los recursos en este orden:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;CloudFront&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Disable distribución &lt;code&gt;saa-lab1-cf&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Espera que despliegue el cambio&lt;/li&gt;
&lt;li&gt;Delete distribution&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Auto Scaling&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;ASG &lt;code&gt;saa-lab1-asg&lt;/code&gt;: Desired/Min = 0&lt;/li&gt;
&lt;li&gt;Delete ASG&lt;/li&gt;
&lt;li&gt;Delete Launch Template &lt;code&gt;saa-lab1-lt&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Load Balancing&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Delete ALB &lt;code&gt;saa-lab1-alb&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Delete Target Group &lt;code&gt;saa-lab1-tg&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Security Groups&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Delete &lt;code&gt;saa-lab1-app-sg&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Delete &lt;code&gt;saa-lab1-alb-sg&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;blockquote&gt;
&lt;p&gt;Si un Security Group aparece “in use”, espera 2–3 minutos. Puede quedar una ENI pendiente.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Troubleshooting rápido
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;CloudFront da 504 pero el ALB responde:&lt;/strong&gt; revisa el origin protocol. Si el ALB es HTTP, el origin debe usar HTTP.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Targets unhealthy:&lt;/strong&gt; revisa user data, NGINX y que el App SG permita HTTP 80 desde el ALB SG.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;CloudFront queda Deploying:&lt;/strong&gt; paciencia. Puede tardar varios minutos.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;SG in use al borrar:&lt;/strong&gt; espera 2–3 minutos y reintenta.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Well-Architected lens: ¿Qué aplicamos aquí?
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Reliability:&lt;/strong&gt; ALB + health checks + ASG para tolerar fallos y sostener capacidad.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Performance Efficiency:&lt;/strong&gt; CloudFront ayuda a reducir latencia y carga directa al origin.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Operational Excellence:&lt;/strong&gt; naming, tags y checkpoints hacen el lab repetible.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cost Optimization:&lt;/strong&gt; arquitectura mínima y cleanup completo.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Security:&lt;/strong&gt; las instancias no reciben tráfico directo desde Internet.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Resultado esperado
&lt;/h2&gt;

&lt;p&gt;Al final del lab, Camilo cuenta con un baseline real de escalamiento para Digital Café Luna: un endpoint global con &lt;strong&gt;CloudFront&lt;/strong&gt;, un origin estable con &lt;strong&gt;ALB&lt;/strong&gt; y capacidad elástica con &lt;strong&gt;Auto Scaling Group&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  Referencias oficiales
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://docs.aws.amazon.com/elasticloadbalancing/latest/application/introduction.html" rel="noopener noreferrer"&gt;Application Load Balancers&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.aws.amazon.com/autoscaling/ec2/userguide/auto-scaling-groups.html" rel="noopener noreferrer"&gt;Auto Scaling Groups&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-launch-templates.html" rel="noopener noreferrer"&gt;Launch Templates&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/distribution-working-with.html" rel="noopener noreferrer"&gt;CloudFront distributions&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/restrict-access-to-load-balancer.html" rel="noopener noreferrer"&gt;Use an Application Load Balancer as a CloudFront origin&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  ¿Qué viene en el próximo lab?
&lt;/h2&gt;

&lt;p&gt;Camilo escuchó en su última clase el concepto de &lt;strong&gt;Data Protection&lt;/strong&gt; y se quedó con esa sensación típica:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“La teoría está buena, pero quiero verlo funcionando.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;En el próximo laboratorio vamos a aterrizarlo en Digital Café Luna con un caso simple: proteger facturas y reportes en &lt;strong&gt;Amazon S3&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Vamos a crear un bucket privado, habilitar &lt;strong&gt;SSE-KMS&lt;/strong&gt;, usar una &lt;strong&gt;KMS key administrada por el cliente&lt;/strong&gt; y aplicar políticas que obliguen el uso de HTTPS.&lt;/p&gt;

&lt;p&gt;También validaremos la evidencia por CLI, para que Camilo entienda mejor cómo se ve el manejo de KMS en la práctica, cuándo un objeto queda cifrado con &lt;code&gt;aws:kms&lt;/code&gt;, qué key lo protegió y cómo comprobarlo sin quedarnos solo con lo que dice la consola.&lt;/p&gt;

&lt;p&gt;Nos vemos en el próximo laboratorio de &lt;strong&gt;Digital Café Luna&lt;/strong&gt;.&lt;/p&gt;




</description>
      <category>aws</category>
      <category>cloudskills</category>
      <category>tutorial</category>
      <category>cloudfront</category>
    </item>
    <item>
      <title>SCS-Lab1 — CloudTrail: Trail + S3 + KMS + Log Validation</title>
      <dc:creator>Luis Eduardo Lunar Guevara</dc:creator>
      <pubDate>Mon, 25 May 2026 23:00:00 +0000</pubDate>
      <link>https://dev.to/llunarg/scs-lab1-cloudtrail-trail-s3-kms-log-validation-2fj2</link>
      <guid>https://dev.to/llunarg/scs-lab1-cloudtrail-trail-s3-kms-log-validation-2fj2</guid>
      <description>&lt;p&gt;&lt;strong&gt;Región:&lt;/strong&gt; &lt;code&gt;us-east-1&lt;/code&gt;&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Duración estimada:&lt;/strong&gt; 35–55 minutos&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Costo-riesgo:&lt;/strong&gt; Medio&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Certificación:&lt;/strong&gt; AWS Certified Security - Specialty (SCS-C03)&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Dominio:&lt;/strong&gt; Detection&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Tarea 1.2:&lt;/strong&gt; &lt;em&gt;Design and implement logging solutions&lt;/em&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Caso de uso
&lt;/h2&gt;

&lt;p&gt;Digital Cafe Luna ya superó sus primeros tropiezos operativos. La aplicación que apoya facturación e inventario funciona mejor, el negocio va creciendo y ahora más personas interactúan en la plataforma. Robert, compañero de estudio de Camilo, también está colaborando con algunos ajustes técnicos.&lt;/p&gt;

&lt;p&gt;Un día, la Sra. Blanca nota un comportamiento extraño en el aplicativo y hace la pregunta incómoda:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“¿Quién cambió qué y cuándo?”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Camilo duda. No sabe si el cambio lo hizo él, Robert o algún proceso de la cuenta. Ahí entiende algo clave: no basta con tener recursos funcionando, se necesita trazabilidad para investigar cambios, responder con evidencia y proteger los registros que cuentan la historia de lo ocurrido.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Sin auditoría, investigar se vuelve opinión.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;En este laboratorio vamos a construir un baseline de auditoría en una sola cuenta AWS usando &lt;strong&gt;AWS CloudTrail&lt;/strong&gt;, &lt;strong&gt;Amazon S3&lt;/strong&gt;, &lt;strong&gt;AWS KMS&lt;/strong&gt; y &lt;strong&gt;log file validation&lt;/strong&gt;. No es una estrategia multi-account todavía; es la base para registrar actividad, almacenar logs, cifrarlos y validar su integridad.&lt;/p&gt;
&lt;h2&gt;
  
  
  ¿Qué vamos a construir?
&lt;/h2&gt;

&lt;p&gt;En este laboratorio vas a crear:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Un &lt;strong&gt;CloudTrail Trail multi-region&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Un &lt;strong&gt;bucket S3 dedicado&lt;/strong&gt; para logs.&lt;/li&gt;
&lt;li&gt;Bloqueo de acceso público y versioning en S3.&lt;/li&gt;
&lt;li&gt;Una &lt;strong&gt;KMS key administrada por el cliente&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Una &lt;strong&gt;key policy&lt;/strong&gt; para permitir uso desde CloudTrail.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Log file validation&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Una prueba controlada para buscar evidencia en CloudTrail.&lt;/li&gt;
&lt;li&gt;Cleanup completo.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fii7tio9w2cpihzef5z03.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%2Fii7tio9w2cpihzef5z03.png" alt="Diagrama SCS-Lab1 — CloudTrail: Trail + S3 + KMS + Log Validation" width="800" height="600"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Figura 1 — CloudTrail registra actividad, entrega logs en S3, los protege con KMS y habilita validación de integridad.&lt;/em&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Nota de alcance
&lt;/h2&gt;

&lt;p&gt;Este laboratorio se ejecuta en &lt;strong&gt;una sola cuenta AWS&lt;/strong&gt;. Más adelante puede evolucionar hacia un &lt;strong&gt;Organization Trail&lt;/strong&gt;, pero aquí nos enfocamos en el fundamento: crear el trail, enviar logs a S3, cifrarlos y validar integridad.&lt;/p&gt;
&lt;h2&gt;
  
  
  Convención de nombres
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Recurso&lt;/th&gt;
&lt;th&gt;Nombre&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;CloudTrail Trail&lt;/td&gt;
&lt;td&gt;&lt;code&gt;scs-lab1-trail&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;S3 Bucket&lt;/td&gt;
&lt;td&gt;&lt;code&gt;scs-lab1-cloudtrail-logs-&amp;lt;tu-alias&amp;gt;-&amp;lt;4digitos&amp;gt;&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;KMS Key Alias&lt;/td&gt;
&lt;td&gt;&lt;code&gt;alias/scs-lab1-cloudtrail&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;S3 Prefix&lt;/td&gt;
&lt;td&gt;&lt;code&gt;cloudtrail/&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;blockquote&gt;
&lt;p&gt;Nota práctica: el bucket de S3 debe tener un nombre único globalmente, por eso usamos &lt;code&gt;&amp;lt;tu-alias&amp;gt;-&amp;lt;4digitos&amp;gt;&lt;/code&gt;.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;
  
  
  Requisitos previos
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Cuenta AWS con permisos para CloudTrail, S3 y KMS.&lt;/li&gt;
&lt;li&gt;Región &lt;code&gt;us-east-1&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Acceso a AWS Console y CloudShell o AWS CLI local.&lt;/li&gt;
&lt;li&gt;Un sufijo único para el bucket. Ejemplo: &lt;code&gt;camilo-4721&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Entender que este lab es &lt;strong&gt;single account&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;Ojo: este laboratorio toca KMS. Si tu cuenta tiene políticas restrictivas, lo más común es fallar por permisos en la key policy.&lt;/p&gt;
&lt;/blockquote&gt;


&lt;h2&gt;
  
  
  Paso 1 — Crear el bucket S3 para los logs
&lt;/h2&gt;

&lt;p&gt;CloudTrail necesita un destino para entregar logs. Usaremos un bucket dedicado, con acceso público bloqueado y versioning habilitado.&lt;/p&gt;
&lt;h3&gt;
  
  
  Crear el bucket desde la consola
&lt;/h3&gt;

&lt;p&gt;En AWS Console:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Ve a &lt;strong&gt;S3 → Buckets&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Selecciona &lt;strong&gt;Create bucket&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Usa el nombre &lt;code&gt;scs-lab1-cloudtrail-logs-&amp;lt;tu-alias&amp;gt;-&amp;lt;4digitos&amp;gt;&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Región: &lt;code&gt;us-east-1&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Deja &lt;strong&gt;Block Public Access&lt;/strong&gt; habilitado.&lt;/li&gt;
&lt;li&gt;En &lt;strong&gt;Bucket Versioning&lt;/strong&gt;, selecciona &lt;strong&gt;Enable&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Crea el bucket.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  CLI opcional
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;REGION&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"us-east-1"&lt;/span&gt;
&lt;span class="nv"&gt;LAB_ID&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"scs-lab1"&lt;/span&gt;
&lt;span class="nv"&gt;ALIAS&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"camilo"&lt;/span&gt;
&lt;span class="nv"&gt;SUFFIX&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"4721"&lt;/span&gt;

&lt;span class="nv"&gt;BUCKET&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;LAB_ID&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;-cloudtrail-logs-&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;ALIAS&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;-&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;SUFFIX&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;

aws s3api create-bucket &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--region&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$REGION&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--bucket&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$BUCKET&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;

aws s3api put-public-access-block &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--region&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$REGION&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--bucket&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$BUCKET&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--public-access-block-configuration&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nv"&gt;BlockPublicAcls&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;true&lt;/span&gt;,IgnorePublicAcls&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;true&lt;/span&gt;,BlockPublicPolicy&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;true&lt;/span&gt;,RestrictPublicBuckets&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;true

&lt;/span&gt;aws s3api put-bucket-versioning &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--region&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$REGION&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--bucket&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$BUCKET&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--versioning-configuration&lt;/span&gt; &lt;span class="nv"&gt;Status&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;Enabled

aws s3api put-bucket-tagging &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--region&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$REGION&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--bucket&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$BUCKET&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--tagging&lt;/span&gt; &lt;span class="s2"&gt;"TagSet=[{Key=Name,Value=&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;LAB_ID&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;-cloudtrail-logs},{Key=Lab,Value=&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;LAB_ID&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;}]"&lt;/span&gt;

aws s3api get-bucket-versioning &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--region&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$REGION&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--bucket&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$BUCKET&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;

aws s3api get-public-access-block &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--region&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$REGION&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--bucket&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$BUCKET&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h3&gt;
  
  
  Checkpoint
&lt;/h3&gt;

&lt;p&gt;Valida que:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;El bucket existe en &lt;code&gt;us-east-1&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Block Public Access&lt;/strong&gt; está activo.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Bucket Versioning&lt;/strong&gt; está en &lt;code&gt;Enabled&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;El bucket tiene el tag &lt;code&gt;Lab=scs-lab1&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;


&lt;h2&gt;
  
  
  Paso 2 — Crear la KMS key
&lt;/h2&gt;

&lt;p&gt;Ahora crearemos una &lt;strong&gt;KMS key administrada por el cliente&lt;/strong&gt; para cifrar los logs de CloudTrail con &lt;strong&gt;SSE-KMS&lt;/strong&gt;.&lt;/p&gt;
&lt;h3&gt;
  
  
  Crear la KMS key desde la consola
&lt;/h3&gt;

&lt;p&gt;En AWS Console:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Ve a &lt;strong&gt;KMS → Customer managed keys&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Selecciona &lt;strong&gt;Create key&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Tipo: &lt;code&gt;Symmetric&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Uso: &lt;code&gt;Encrypt and decrypt&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Alias: &lt;code&gt;alias/scs-lab1-cloudtrail&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;En &lt;strong&gt;Key administrators&lt;/strong&gt;, selecciona tu usuario o rol administrador.&lt;/li&gt;
&lt;li&gt;En &lt;strong&gt;Key users&lt;/strong&gt;, agrega también tu usuario o rol administrador.&lt;/li&gt;
&lt;li&gt;Crea la key.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  Agregar permiso para CloudTrail
&lt;/h3&gt;

&lt;p&gt;En la key:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Entra a &lt;strong&gt;Key policy&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Selecciona &lt;strong&gt;Edit&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Agrega este statement &lt;strong&gt;sin eliminar los permisos administrativos existentes&lt;/strong&gt;.
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"Sid"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"AllowCloudTrailToUseTheKey"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"Effect"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Allow"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"Principal"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"Service"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"cloudtrail.amazonaws.com"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"Action"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="s2"&gt;"kms:GenerateDataKey*"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="s2"&gt;"kms:Encrypt"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="s2"&gt;"kms:Decrypt"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="s2"&gt;"kms:DescribeKey"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"Resource"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"*"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;blockquote&gt;
&lt;p&gt;Ojo: el principal debe ser &lt;code&gt;cloudtrail.amazonaws.com&lt;/code&gt; como &lt;strong&gt;Service principal&lt;/strong&gt;.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;
  
  
  CLI opcional para validar
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;REGION&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"us-east-1"&lt;/span&gt;

aws kms describe-key &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--region&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$REGION&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--key-id&lt;/span&gt; &lt;span class="s2"&gt;"alias/scs-lab1-cloudtrail"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--query&lt;/span&gt; &lt;span class="s2"&gt;"{KeyId:KeyMetadata.KeyId,Arn:KeyMetadata.Arn,State:KeyMetadata.KeyState,Usage:KeyMetadata.KeyUsage}"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--output&lt;/span&gt; table

aws kms list-aliases &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--region&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$REGION&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--query&lt;/span&gt; &lt;span class="s2"&gt;"Aliases[?AliasName=='alias/scs-lab1-cloudtrail'].[AliasName,TargetKeyId]"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--output&lt;/span&gt; table
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h3&gt;
  
  
  Checkpoint
&lt;/h3&gt;

&lt;p&gt;Valida que:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;La key está en estado &lt;code&gt;Enabled&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;El alias existe.&lt;/li&gt;
&lt;li&gt;Tu usuario o rol conserva permisos.&lt;/li&gt;
&lt;li&gt;La key policy permite uso desde CloudTrail.&lt;/li&gt;
&lt;/ul&gt;


&lt;h2&gt;
  
  
  Paso 3 — Crear el CloudTrail Trail multi-region
&lt;/h2&gt;

&lt;p&gt;Ahora vamos a crear el trail para registrar actividad de la cuenta y conservar evidencia en S3.&lt;/p&gt;
&lt;h3&gt;
  
  
  Crear el trail desde la consola
&lt;/h3&gt;

&lt;p&gt;En AWS Console:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Ve a &lt;strong&gt;CloudTrail → Trails&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Selecciona &lt;strong&gt;Create trail&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Nombre: &lt;code&gt;scs-lab1-trail&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;En &lt;strong&gt;Storage location&lt;/strong&gt;, selecciona &lt;strong&gt;Use existing S3 bucket&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Elige el bucket del lab.&lt;/li&gt;
&lt;li&gt;Si usas prefijo, coloca &lt;code&gt;cloudtrail&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Habilita &lt;strong&gt;Log file SSE-KMS encryption&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Selecciona &lt;code&gt;alias/scs-lab1-cloudtrail&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Habilita &lt;strong&gt;Log file validation&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Asegúrate de que sea &lt;strong&gt;multi-region&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;En eventos:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Management events:&lt;/strong&gt; habilitado.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Read:&lt;/strong&gt; habilitado.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Write:&lt;/strong&gt; habilitado.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Data events:&lt;/strong&gt; deshabilitado.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Insights events:&lt;/strong&gt; deshabilitado.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Network activity events:&lt;/strong&gt; deshabilitado.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  CLI opcional para validar
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;REGION&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"us-east-1"&lt;/span&gt;

aws cloudtrail describe-trails &lt;span class="nt"&gt;--region&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$REGION&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--query&lt;/span&gt; &lt;span class="s2"&gt;"trailList[?Name=='scs-lab1-trail'].[Name,S3BucketName,IsMultiRegionTrail,KmsKeyId,LogFileValidationEnabled]"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--output&lt;/span&gt; table

aws cloudtrail get-trail-status &lt;span class="nt"&gt;--region&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$REGION&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--name&lt;/span&gt; &lt;span class="s2"&gt;"scs-lab1-trail"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--query&lt;/span&gt; &lt;span class="s2"&gt;"{IsLogging:IsLogging,LatestDeliveryTime:LatestDeliveryTime,LatestDigestDeliveryTime:LatestDigestDeliveryTime,LatestDeliveryError:LatestDeliveryError}"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--output&lt;/span&gt; table
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h3&gt;
  
  
  Checkpoint
&lt;/h3&gt;

&lt;p&gt;Valida que:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;IsMultiRegionTrail&lt;/code&gt; aparece como &lt;code&gt;true&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;LogFileValidationEnabled&lt;/code&gt; aparece como &lt;code&gt;true&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;IsLogging&lt;/code&gt; aparece como &lt;code&gt;true&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;LatestDeliveryError&lt;/code&gt; está vacío o sin errores relevantes.&lt;/li&gt;
&lt;/ul&gt;


&lt;h2&gt;
  
  
  Paso 4 — Generar un evento y confirmar entrega
&lt;/h2&gt;

&lt;p&gt;Crear CloudTrail no basta. Hay que validar que registra eventos y entrega logs en S3.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Acción en AWS → CloudTrail → S3 bucket → Evidencia disponible
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Generar un evento desde la consola
&lt;/h3&gt;

&lt;p&gt;Puedes crear una access key temporal solo como evento de prueba:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Ve a &lt;strong&gt;IAM → Users&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Selecciona tu usuario.&lt;/li&gt;
&lt;li&gt;Entra a &lt;strong&gt;Security credentials&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;En &lt;strong&gt;Access keys&lt;/strong&gt;, selecciona &lt;strong&gt;Create access key&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Crea la key solo para generar el evento.&lt;/li&gt;
&lt;li&gt;No la uses para nada productivo.&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;Ojo: elimina esta access key en el cleanup.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;También puedes usar un cambio menor, como agregar un tag no crítico.&lt;/p&gt;

&lt;h3&gt;
  
  
  Validar entrega por CLI
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;REGION&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"us-east-1"&lt;/span&gt;

aws cloudtrail get-trail-status &lt;span class="nt"&gt;--region&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$REGION&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--name&lt;/span&gt; &lt;span class="s2"&gt;"scs-lab1-trail"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--query&lt;/span&gt; &lt;span class="s2"&gt;"{IsLogging:IsLogging,LatestDeliveryTime:LatestDeliveryTime,LatestDeliveryError:LatestDeliveryError}"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--output&lt;/span&gt; table
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ajusta &lt;code&gt;BUCKET&lt;/code&gt; con tu bucket real:&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;REGION&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"us-east-1"&lt;/span&gt;
&lt;span class="nv"&gt;BUCKET&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"scs-lab1-cloudtrail-logs-camilo-4721"&lt;/span&gt;
&lt;span class="nv"&gt;ACCOUNT_ID&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;aws sts get-caller-identity &lt;span class="nt"&gt;--query&lt;/span&gt; Account &lt;span class="nt"&gt;--output&lt;/span&gt; text&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;

aws s3 &lt;span class="nb"&gt;ls&lt;/span&gt; &lt;span class="s2"&gt;"s3://&lt;/span&gt;&lt;span class="nv"&gt;$BUCKET&lt;/span&gt;&lt;span class="s2"&gt;/cloudtrail/AWSLogs/&lt;/span&gt;&lt;span class="nv"&gt;$ACCOUNT_ID&lt;/span&gt;&lt;span class="s2"&gt;/"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--recursive&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--human-readable&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--summarize&lt;/span&gt; | &lt;span class="nb"&gt;tail&lt;/span&gt; &lt;span class="nt"&gt;-n&lt;/span&gt; 20
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Si no usaste prefijo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;aws s3 &lt;span class="nb"&gt;ls&lt;/span&gt; &lt;span class="s2"&gt;"s3://&lt;/span&gt;&lt;span class="nv"&gt;$BUCKET&lt;/span&gt;&lt;span class="s2"&gt;/AWSLogs/&lt;/span&gt;&lt;span class="nv"&gt;$ACCOUNT_ID&lt;/span&gt;&lt;span class="s2"&gt;/"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--recursive&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--human-readable&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--summarize&lt;/span&gt; | &lt;span class="nb"&gt;tail&lt;/span&gt; &lt;span class="nt"&gt;-n&lt;/span&gt; 20
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Paso 5 — Verificar cifrado y log file validation
&lt;/h2&gt;

&lt;p&gt;Ahora validamos que los logs estén cifrados con &lt;strong&gt;SSE-KMS&lt;/strong&gt; y que CloudTrail genere archivos digest para integridad.&lt;/p&gt;

&lt;h3&gt;
  
  
  Validar desde la consola
&lt;/h3&gt;

&lt;p&gt;En AWS Console:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Ve a &lt;strong&gt;CloudTrail → Trails&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Abre &lt;code&gt;scs-lab1-trail&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Valida:

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Log file SSE-KMS encryption:&lt;/strong&gt; Enabled.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;AWS KMS key:&lt;/strong&gt; &lt;code&gt;alias/scs-lab1-cloudtrail&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Log file validation:&lt;/strong&gt; Enabled.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;h3&gt;
  
  
  Confirmar por CLI
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;REGION&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"us-east-1"&lt;/span&gt;

aws cloudtrail describe-trails &lt;span class="nt"&gt;--region&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$REGION&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--query&lt;/span&gt; &lt;span class="s2"&gt;"trailList[?Name=='scs-lab1-trail'].[Name,IsMultiRegionTrail,LogFileValidationEnabled,KmsKeyId,S3BucketName,S3KeyPrefix]"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--output&lt;/span&gt; table
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Verifica objetos digest:&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;BUCKET&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"scs-lab1-cloudtrail-logs-camilo-4721"&lt;/span&gt;
&lt;span class="nv"&gt;ACCOUNT_ID&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;aws sts get-caller-identity &lt;span class="nt"&gt;--query&lt;/span&gt; Account &lt;span class="nt"&gt;--output&lt;/span&gt; text&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;

aws s3 &lt;span class="nb"&gt;ls&lt;/span&gt; &lt;span class="s2"&gt;"s3://&lt;/span&gt;&lt;span class="nv"&gt;$BUCKET&lt;/span&gt;&lt;span class="s2"&gt;/cloudtrail/AWSLogs/&lt;/span&gt;&lt;span class="nv"&gt;$ACCOUNT_ID&lt;/span&gt;&lt;span class="s2"&gt;/CloudTrail-Digest/"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--recursive&lt;/span&gt; | &lt;span class="nb"&gt;tail&lt;/span&gt; &lt;span class="nt"&gt;-n&lt;/span&gt; 10
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Verifica cifrado en un objeto real:&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;BUCKET&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"scs-lab1-cloudtrail-logs-camilo-4721"&lt;/span&gt;
&lt;span class="nv"&gt;ACCOUNT_ID&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;aws sts get-caller-identity &lt;span class="nt"&gt;--query&lt;/span&gt; Account &lt;span class="nt"&gt;--output&lt;/span&gt; text&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;

&lt;span class="nv"&gt;OBJ_KEY&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;aws s3api list-objects-v2 &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--bucket&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$BUCKET&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--prefix&lt;/span&gt; &lt;span class="s2"&gt;"cloudtrail/AWSLogs/&lt;/span&gt;&lt;span class="nv"&gt;$ACCOUNT_ID&lt;/span&gt;&lt;span class="s2"&gt;/CloudTrail/"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--query&lt;/span&gt; &lt;span class="s2"&gt;"reverse(sort_by(Contents,&amp;amp;LastModified))[0].Key"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--output&lt;/span&gt; text&lt;span class="si"&gt;)&lt;/span&gt;

&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$OBJ_KEY&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;

aws s3api head-object &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--bucket&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$BUCKET&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--key&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$OBJ_KEY&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--query&lt;/span&gt; &lt;span class="s2"&gt;"{SSE:ServerSideEncryption,KMSKey:SSEKMSKeyId}"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--output&lt;/span&gt; table
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Salida esperada:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SSE     aws:kms
KMSKey  arn:aws:kms:...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Paso 6 — Buscar el cambio en CloudTrail
&lt;/h2&gt;

&lt;p&gt;Ahora usamos CloudTrail para responder con evidencia:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“¿Quién cambió qué y cuándo?”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Buscar desde la consola
&lt;/h3&gt;

&lt;p&gt;En AWS Console:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Ve a &lt;strong&gt;CloudTrail → Event history&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;En &lt;strong&gt;Lookup attributes&lt;/strong&gt;, filtra según la acción.&lt;/li&gt;
&lt;li&gt;Si creaste una access key, busca:

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Event name:&lt;/strong&gt; &lt;code&gt;CreateAccessKey&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Event name:&lt;/strong&gt; &lt;code&gt;DeleteAccessKey&lt;/code&gt;, si ya la eliminaste.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;Abre el evento y revisa:

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Event name&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Event time&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;User name / ARN&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Source IP address&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;AWS Region&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;User agent&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;h3&gt;
  
  
  Buscar por CLI
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;REGION&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"us-east-1"&lt;/span&gt;

&lt;span class="nv"&gt;START_TIME&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;date&lt;/span&gt; &lt;span class="nt"&gt;-u&lt;/span&gt; &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'60 minutes ago'&lt;/span&gt; +&lt;span class="s2"&gt;"%Y-%m-%dT%H:%M:%SZ"&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;

aws cloudtrail lookup-events &lt;span class="nt"&gt;--region&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$REGION&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--start-time&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$START_TIME&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--max-results&lt;/span&gt; 10 &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--query&lt;/span&gt; &lt;span class="s2"&gt;"Events[].{Time:EventTime,Name:EventName,User:Username,EventId:EventId}"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--output&lt;/span&gt; table
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Por evento específico:&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;REGION&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"us-east-1"&lt;/span&gt;

aws cloudtrail lookup-events &lt;span class="nt"&gt;--region&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$REGION&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--lookup-attributes&lt;/span&gt; &lt;span class="nv"&gt;AttributeKey&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;EventName,AttributeValue&lt;span class="o"&gt;=&lt;/span&gt;CreateAccessKey &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--max-results&lt;/span&gt; 5 &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--query&lt;/span&gt; &lt;span class="s2"&gt;"Events[].{Time:EventTime,Name:EventName,User:Username,EventId:EventId}"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--output&lt;/span&gt; table
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Detalle del evento:&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;REGION&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"us-east-1"&lt;/span&gt;

aws cloudtrail lookup-events &lt;span class="nt"&gt;--region&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$REGION&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--lookup-attributes&lt;/span&gt; &lt;span class="nv"&gt;AttributeKey&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;EventName,AttributeValue&lt;span class="o"&gt;=&lt;/span&gt;CreateAccessKey &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--max-results&lt;/span&gt; 1 &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--query&lt;/span&gt; &lt;span class="s2"&gt;"Events[0].CloudTrailEvent"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--output&lt;/span&gt; text
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Ojo: si estás en Mac y &lt;code&gt;date -d&lt;/code&gt; no funciona, ejecuta esa parte desde CloudShell o ajusta el cálculo de tiempo.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Clean up completo — SCS-Lab1
&lt;/h2&gt;

&lt;p&gt;Elimina los recursos para evitar costos y mantener la cuenta limpia.&lt;/p&gt;

&lt;h3&gt;
  
  
  Recursos a eliminar
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;CloudTrail Trail:&lt;/strong&gt; &lt;code&gt;scs-lab1-trail&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;S3 Bucket:&lt;/strong&gt; &lt;code&gt;scs-lab1-cloudtrail-logs-&amp;lt;tu-alias&amp;gt;-&amp;lt;4digitos&amp;gt;&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;KMS Key:&lt;/strong&gt; &lt;code&gt;alias/scs-lab1-cloudtrail&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Access key temporal:&lt;/strong&gt; si la creaste&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Orden recomendado
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Elimina la &lt;strong&gt;access key temporal&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Elimina el &lt;strong&gt;CloudTrail Trail&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Vacía y elimina el &lt;strong&gt;S3 Bucket&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Agenda la eliminación de la &lt;strong&gt;KMS Key&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Desde la consola
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;En &lt;strong&gt;CloudTrail → Trails&lt;/strong&gt;, elimina &lt;code&gt;scs-lab1-trail&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;En &lt;strong&gt;S3 → Buckets&lt;/strong&gt;, vacía y elimina el bucket del lab.&lt;/li&gt;
&lt;li&gt;En &lt;strong&gt;KMS → Customer managed keys&lt;/strong&gt;, selecciona la key y usa &lt;strong&gt;Schedule key deletion&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;Ojo: si versioning está habilitado, revisa versiones y delete markers antes de eliminar el bucket.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  CLI opcional para validar cleanup
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;REGION&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"us-east-1"&lt;/span&gt;

aws cloudtrail describe-trails &lt;span class="nt"&gt;--region&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$REGION&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--query&lt;/span&gt; &lt;span class="s2"&gt;"trailList[?Name=='scs-lab1-trail'].[Name]"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--output&lt;/span&gt; table
&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="nv"&gt;BUCKET&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"scs-lab1-cloudtrail-logs-camilo-4721"&lt;/span&gt;

&lt;span class="k"&gt;if &lt;/span&gt;aws s3api head-bucket &lt;span class="nt"&gt;--bucket&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$BUCKET&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; 2&amp;gt;/dev/null&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
  &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Bucket aún existe: &lt;/span&gt;&lt;span class="nv"&gt;$BUCKET&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;span class="k"&gt;else
  &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Bucket eliminado o no accesible: &lt;/span&gt;&lt;span class="nv"&gt;$BUCKET&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;span class="k"&gt;fi&lt;/span&gt;
&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="nv"&gt;REGION&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"us-east-1"&lt;/span&gt;

aws kms describe-key &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--region&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$REGION&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--key-id&lt;/span&gt; &lt;span class="s2"&gt;"alias/scs-lab1-cloudtrail"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--query&lt;/span&gt; &lt;span class="s2"&gt;"{KeyId:KeyMetadata.KeyId,State:KeyMetadata.KeyState,DeletionDate:KeyMetadata.DeletionDate}"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--output&lt;/span&gt; table
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Troubleshooting rápido
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;CloudTrail no entrega logs en S3:&lt;/strong&gt; revisa &lt;code&gt;LatestDeliveryError&lt;/code&gt;, bucket policy, prefijo y KMS.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;KMS policy falla:&lt;/strong&gt; valida &lt;code&gt;Principal.Service = cloudtrail.amazonaws.com&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;No aparecen objetos digest:&lt;/strong&gt; espera unos minutos y confirma que ya llegan logs normales.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;OBJ_KEY&lt;/code&gt; sale como &lt;code&gt;None&lt;/code&gt;:&lt;/strong&gt; revisa si usaste prefijo &lt;code&gt;cloudtrail&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;El bucket no se deja borrar:&lt;/strong&gt; elimina contenido, versiones y delete markers.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;No puedes agendar eliminación de la KMS key:&lt;/strong&gt; valida que sigues siendo administrador de la key.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Well-Architected lens: ¿Qué aplicamos aquí?
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Security:&lt;/strong&gt; pasamos de sospechas a evidencia verificable.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Operational Excellence:&lt;/strong&gt; dejamos un flujo repetible de investigación.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Reliability:&lt;/strong&gt; reducimos cambios silenciosos sin trazabilidad.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cost Optimization:&lt;/strong&gt; mantenemos el lab autocontenido y con cleanup completo.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Performance Efficiency:&lt;/strong&gt; evitamos data events e Insights para no recolectar señales innecesarias.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Resultado esperado
&lt;/h2&gt;

&lt;p&gt;Al finalizar deberías poder crear un baseline de auditoría en una cuenta AWS: trail multi-region, logs en S3, cifrado con KMS, validación de integridad, búsqueda de eventos y cleanup completo.&lt;/p&gt;

&lt;p&gt;La idea no era solo “prender CloudTrail”, sino dejar evidencia auditable, protegida y verificable.&lt;/p&gt;

&lt;p&gt;Al final, Camilo puede responder con más claridad:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“¿Quién cambió qué y cuándo?”&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Referencias oficiales
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudtrail-user-guide.html" rel="noopener noreferrer"&gt;AWS CloudTrail — User Guide&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudtrail-create-and-update-a-trail.html" rel="noopener noreferrer"&gt;Create a trail — AWS CloudTrail&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.aws.amazon.com/awscloudtrail/latest/userguide/encrypting-cloudtrail-log-files-with-aws-kms.html" rel="noopener noreferrer"&gt;Encrypting CloudTrail log files with AWS KMS&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudtrail-log-file-validation-intro.html" rel="noopener noreferrer"&gt;CloudTrail log file integrity validation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.aws.amazon.com/awscloudtrail/latest/userguide/create-s3-bucket-policy-for-cloudtrail.html" rel="noopener noreferrer"&gt;Amazon S3 bucket policy for CloudTrail&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  ¿Qué viene en el próximo lab?
&lt;/h2&gt;

&lt;p&gt;Digital Cafe Luna ya tiene una base de auditoría en una sola cuenta. El siguiente paso es prepararse para un reto real: &lt;strong&gt;escalar&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;SAA-Lab1 — Scaling en AWS (baseline): ALB + Auto Scaling + CloudFront&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Montaremos un baseline de escalamiento con balanceo, escalado automático y caché en el borde, usando el dominio por defecto de CloudFront.&lt;/p&gt;

&lt;p&gt;Nos vemos en el próximo laboratorio de &lt;strong&gt;Digital Cafe Luna&lt;/strong&gt;.&lt;/p&gt;




</description>
      <category>aws</category>
      <category>cloudskills</category>
      <category>tutorial</category>
      <category>cloudtrail</category>
    </item>
    <item>
      <title>SOA-Lab1 — Observabilidad mínima: CloudWatch Logs + Alarmas + SNS</title>
      <dc:creator>Luis Eduardo Lunar Guevara</dc:creator>
      <pubDate>Mon, 18 May 2026 23:00:00 +0000</pubDate>
      <link>https://dev.to/llunarg/soa-lab1-observabilidad-minima-cloudwatch-logs-alarmas-sns-2l81</link>
      <guid>https://dev.to/llunarg/soa-lab1-observabilidad-minima-cloudwatch-logs-alarmas-sns-2l81</guid>
      <description>&lt;p&gt;&lt;strong&gt;Región:&lt;/strong&gt; &lt;code&gt;us-east-1&lt;/code&gt;&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Duración estimada:&lt;/strong&gt; 35–55 minutos&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Costo-riesgo:&lt;/strong&gt; Bajo&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Certificación:&lt;/strong&gt; AWS Certified CloudOps Engineer - Associate (SOA-C03)&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Dominio:&lt;/strong&gt; Monitoring, Logging and Remediation&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Tarea 1.1:&lt;/strong&gt; &lt;em&gt;Implement metrics, alarms, and filters by using AWS monitoring and logging services&lt;/em&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Caso de uso
&lt;/h2&gt;

&lt;p&gt;Digital Cafe Luna inicia sus actividades: un café pequeño, un sueño familiar y una oportunidad para salir adelante. Camilo, hijo de la Sra. Blanca, estudia tecnología y desde el primer día insistió en montar una pequeña aplicación en AWS para apoyar la facturación y llevar un control básico del inventario. Un lunes por la mañana, la Sra. Blanca nota retrasos en la caja, algunos errores en el sistema y suelta esa frase que cualquier equipo técnico ha escuchado alguna vez:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“El sistema está lento, ¿qué pasa?.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Camilo revisa la instancia, pero no tiene suficiente visibilidad para entender. No sabe si fue la CPU, logs, errores de arranque, una carga puntual o simplemente una percepción del usuario.&lt;/p&gt;

&lt;p&gt;La clave es simple: sin observabilidad, diagnosticar se vuelve adivinar.&lt;/p&gt;

&lt;p&gt;En este laboratorio vamos a construir un baseline mínimo de observabilidad en AWS: logs centralizados, una alarma de CPU y una notificación por email. ¡No es una plataforma completa de monitoreo por Dios!, pero si un primer paso para operar con datos y no con suposiciones.&lt;/p&gt;
&lt;h2&gt;
  
  
  ¿Qué vamos a construir?
&lt;/h2&gt;

&lt;p&gt;En este laboratorio vas a crear:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Un &lt;strong&gt;SNS Topic&lt;/strong&gt; con suscripción por email para recibir alertas.&lt;/li&gt;
&lt;li&gt;Un &lt;strong&gt;CloudWatch Log Group&lt;/strong&gt; con retención corta para centralizar logs.&lt;/li&gt;
&lt;li&gt;Una &lt;strong&gt;instancia EC2 Amazon Linux&lt;/strong&gt; accesible por SSH.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;CloudWatch Agent&lt;/strong&gt; en la instancia para enviar logs y métricas básicas.&lt;/li&gt;
&lt;li&gt;Una &lt;strong&gt;alarma de CPU en CloudWatch&lt;/strong&gt; que notifica al SNS Topic.&lt;/li&gt;
&lt;li&gt;Una prueba controlada de carga para validar que la alarma realmente dispara.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fev7razt59m7bx5az5tqe.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%2Fev7razt59m7bx5az5tqe.png" alt="Diagrama SOA-Lab1 — Observabilidad mínima con CloudWatch Logs, Alarmas y SNS" width="800" height="600"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Figura 1 — Flujo mínimo de observabilidad para Digital Cafe Luna: EC2 envía logs y métricas a CloudWatch, la alarma dispara SNS y Camilo recibe la notificación por email.&lt;/em&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Convención de nombres
&lt;/h2&gt;

&lt;p&gt;Usaremos el prefijo &lt;code&gt;soa-lab1&lt;/code&gt; para que puedas buscar, filtrar y eliminar recursos sin perder tiempo.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Recurso&lt;/th&gt;
&lt;th&gt;Nombre&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;EC2 Instance&lt;/td&gt;
&lt;td&gt;&lt;code&gt;soa-lab1-app&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Security Group&lt;/td&gt;
&lt;td&gt;&lt;code&gt;soa-lab1-app-sg&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Key Pair&lt;/td&gt;
&lt;td&gt;&lt;code&gt;kp-soa-lab1&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;CloudWatch Log Group&lt;/td&gt;
&lt;td&gt;&lt;code&gt;/soa/lab1/system&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;SNS Topic&lt;/td&gt;
&lt;td&gt;&lt;code&gt;soa-lab1-alerts-v2&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;CloudWatch Alarm&lt;/td&gt;
&lt;td&gt;&lt;code&gt;ALARM-soa-lab1-high-cpu&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;IAM Role&lt;/td&gt;
&lt;td&gt;&lt;code&gt;soa-lab1-ec2-cw-role&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;blockquote&gt;
&lt;p&gt;Nota práctica: usar nombres consistentes no es un detalle menor. En labs ayuda al cleanup, en ambientes reales ayuda a operar, auditar y reducir confusión.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;
  
  
  Requisitos previos
&lt;/h2&gt;

&lt;p&gt;Antes de comenzar, asegúrate de tener:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Una cuenta AWS con permisos suficientes para crear recursos del laboratorio.&lt;/li&gt;
&lt;li&gt;Región de trabajo: &lt;code&gt;us-east-1&lt;/code&gt; (N. Virginia).&lt;/li&gt;
&lt;li&gt;Un correo activo para confirmar la suscripción de Amazon SNS.&lt;/li&gt;
&lt;li&gt;Cliente SSH disponible: Terminal en Mac/Linux, PuTTY o similar en Windows.&lt;/li&gt;
&lt;li&gt;Acceso a una VPC default en la región.&lt;/li&gt;
&lt;li&gt;Tu IP pública disponible para permitir SSH solo desde tu origen.&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;Ojo: para este laboratorio no abras SSH a &lt;code&gt;0.0.0.0/0&lt;/code&gt;. Vamos a permitir el puerto 22 únicamente desde tu IP pública en formato &lt;code&gt;/32&lt;/code&gt;.&lt;/p&gt;
&lt;/blockquote&gt;


&lt;h2&gt;
  
  
  Paso 1 — Preparar acceso por SSH
&lt;/h2&gt;

&lt;p&gt;Antes de crear la instancia, vamos a dejar listo el acceso. La regla es simple: necesitamos poder entrar por SSH, pero sin abrir la instancia al mundo.&lt;/p&gt;

&lt;p&gt;En este lab vamos a permitir SSH solo desde tu IP pública. Nada de &lt;code&gt;0.0.0.0/0&lt;/code&gt;.&lt;/p&gt;
&lt;h3&gt;
  
  
  1.1 Crear el Key Pair
&lt;/h3&gt;

&lt;p&gt;En AWS Console:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Ve a &lt;strong&gt;EC2 → Key Pairs&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Selecciona &lt;strong&gt;Create key pair&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;En &lt;strong&gt;Name&lt;/strong&gt;, usa &lt;code&gt;kp-soa-lab1&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;En el tipo de llave:

&lt;ul&gt;
&lt;li&gt;Si usas Mac/Linux, selecciona &lt;code&gt;.pem&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Si usas Windows con PuTTY, selecciona &lt;code&gt;.ppk&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Crea el key pair y guarda el archivo en un lugar seguro.&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;Ojo: AWS solo te permite descargar la llave privada una vez. Si la pierdes, tendrás que crear otro key pair o usar otro método de acceso (mas adelante te enseñaré qué hacer cuando pierdes tu Key pair).&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;
  
  
  1.2 Crear el Security Group
&lt;/h3&gt;

&lt;p&gt;Ahora crea el Security Group que permitirá SSH solo desde tu IP.&lt;/p&gt;

&lt;p&gt;En AWS Console:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Ve a &lt;strong&gt;EC2 → Security Groups&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Selecciona &lt;strong&gt;Create security group&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;En &lt;strong&gt;Name&lt;/strong&gt;, usa &lt;code&gt;soa-lab1-app-sg&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;En &lt;strong&gt;Description&lt;/strong&gt;, usa &lt;code&gt;SOA Lab1 SSH restricted&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;En &lt;strong&gt;VPC&lt;/strong&gt;, selecciona la default VPC.&lt;/li&gt;
&lt;li&gt;En &lt;strong&gt;Inbound rules&lt;/strong&gt;, agrega &lt;code&gt;SSH&lt;/code&gt;, puerto &lt;code&gt;22&lt;/code&gt;, source &lt;code&gt;My IP&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;En &lt;strong&gt;Outbound rules&lt;/strong&gt;, deja la regla por defecto &lt;code&gt;All traffic&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Crea el Security Group.&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;En este lab dejamos salida abierta para que la instancia pueda instalar paquetes y comunicarse con servicios de AWS. Lo importante aquí es cuidar el tráfico de entrada.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;
  
  
  CLI opcional
&lt;/h3&gt;

&lt;p&gt;Si prefieres hacerlo por CLI, puedes usar este bloque desde tu terminal.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Ojo: &lt;code&gt;MYIP&lt;/code&gt; debe obtenerse desde tu máquina local, no desde CloudShell. Si lo ejecutas desde CloudShell, estarías permitiendo la IP pública de CloudShell, no la tuya.&lt;br&gt;
&lt;/p&gt;


&lt;/blockquote&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# 0) Variables&lt;/span&gt;
&lt;span class="nv"&gt;REGION&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"us-east-1"&lt;/span&gt;
&lt;span class="nv"&gt;MYIP&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;curl &lt;span class="nt"&gt;-s&lt;/span&gt; https://checkip.amazonaws.com&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;/32"&lt;/span&gt;

&lt;span class="c"&gt;# 1) Obtener la default VPC&lt;/span&gt;
&lt;span class="nv"&gt;VPC_ID&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;aws ec2 describe-vpcs &lt;span class="nt"&gt;--region&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$REGION&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--filters&lt;/span&gt; &lt;span class="nv"&gt;Name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;isDefault,Values&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;true&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--query&lt;/span&gt; &lt;span class="s1"&gt;'Vpcs[0].VpcId'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--output&lt;/span&gt; text&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;

&lt;span class="c"&gt;# 2) Crear Security Group&lt;/span&gt;
&lt;span class="nv"&gt;SG_ID&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;aws ec2 create-security-group &lt;span class="nt"&gt;--region&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$REGION&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--group-name&lt;/span&gt; &lt;span class="s2"&gt;"soa-lab1-app-sg"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--description&lt;/span&gt; &lt;span class="s2"&gt;"SOA Lab1 SSH restricted"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--vpc-id&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$VPC_ID&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--query&lt;/span&gt; &lt;span class="s1"&gt;'GroupId'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--output&lt;/span&gt; text&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;

&lt;span class="c"&gt;# 3) Autorizar SSH solo desde tu IP pública&lt;/span&gt;
aws ec2 authorize-security-group-ingress &lt;span class="nt"&gt;--region&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$REGION&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--group-id&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$SG_ID&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--ip-permissions&lt;/span&gt; &lt;span class="s2"&gt;"IpProtocol=tcp,FromPort=22,ToPort=22,IpRanges=[{CidrIp=&lt;/span&gt;&lt;span class="nv"&gt;$MYIP&lt;/span&gt;&lt;span class="s2"&gt;,Description='SSH solo mi IP'}]"&lt;/span&gt;

&lt;span class="c"&gt;# 4) Agregar tags&lt;/span&gt;
aws ec2 create-tags &lt;span class="nt"&gt;--region&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$REGION&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--resources&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$SG_ID&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--tags&lt;/span&gt; &lt;span class="nv"&gt;Key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;Name,Value&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"soa-lab1-app-sg"&lt;/span&gt; &lt;span class="nv"&gt;Key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;Lab,Value&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"soa-lab1"&lt;/span&gt;

&lt;span class="c"&gt;# 5) Verificar reglas&lt;/span&gt;
aws ec2 describe-security-groups &lt;span class="nt"&gt;--region&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$REGION&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--group-ids&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$SG_ID&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--query&lt;/span&gt; &lt;span class="s2"&gt;"SecurityGroups[0].IpPermissions"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--output&lt;/span&gt; table
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Checkpoint
&lt;/h3&gt;

&lt;p&gt;Antes de seguir, valida:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Existe el key pair &lt;code&gt;kp-soa-lab1&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Existe el Security Group &lt;code&gt;soa-lab1-app-sg&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;La regla inbound permite SSH &lt;code&gt;22&lt;/code&gt; solo desde tu IP pública &lt;code&gt;/32&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;No existe una regla SSH abierta a &lt;code&gt;0.0.0.0/0&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Paso 2 — Lanzar la instancia EC2
&lt;/h2&gt;

&lt;p&gt;Ahora vamos a crear la instancia que usaremos como servidor base de Digital Cafe Luna. No estamos buscando una arquitectura compleja todavía; solo necesitamos una EC2 pequeña, identificable por tags y accesible por SSH para instalar el CloudWatch Agent.&lt;/p&gt;

&lt;h3&gt;
  
  
  Crear la instancia desde la consola
&lt;/h3&gt;

&lt;p&gt;En AWS Console:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Ve a &lt;strong&gt;EC2 → Instances → Launch instance&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;En &lt;strong&gt;Name&lt;/strong&gt;, usa &lt;code&gt;soa-lab1-app&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;En &lt;strong&gt;Application and OS Images&lt;/strong&gt;, selecciona &lt;code&gt;Amazon Linux 2023&lt;/code&gt;. También puedes usar Amazon Linux 2 si es lo que tienes disponible.&lt;/li&gt;
&lt;li&gt;En &lt;strong&gt;Instance type&lt;/strong&gt;, selecciona &lt;code&gt;t3.nano&lt;/code&gt;. Si tu cuenta no permite &lt;code&gt;t3.nano&lt;/code&gt;, usa &lt;code&gt;t3.micro&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;En &lt;strong&gt;Key pair&lt;/strong&gt;, selecciona &lt;code&gt;kp-soa-lab1&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;En &lt;strong&gt;Network settings&lt;/strong&gt;, selecciona &lt;strong&gt;Edit&lt;/strong&gt; y configura:

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;VPC:&lt;/strong&gt; default VPC.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Subnet:&lt;/strong&gt; No preference.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Auto-assign public IP:&lt;/strong&gt; Enabled.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Firewall:&lt;/strong&gt; Select existing security group.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Security group:&lt;/strong&gt; &lt;code&gt;soa-lab1-app-sg&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;En &lt;strong&gt;Tags&lt;/strong&gt;, agrega &lt;code&gt;Lab=soa-lab1&lt;/code&gt;.&lt;/li&gt;

&lt;li&gt;Lanza la instancia y espera hasta que esté en estado &lt;code&gt;Running&lt;/code&gt; y con &lt;code&gt;2/2 checks passed&lt;/code&gt;.&lt;/li&gt;

&lt;/ul&gt;

&lt;h3&gt;
  
  
  CLI opcional para validar
&lt;/h3&gt;

&lt;p&gt;Cuando la instancia esté corriendo, puedes validar con:&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;REGION&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"us-east-1"&lt;/span&gt;

aws ec2 describe-instances &lt;span class="nt"&gt;--region&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$REGION&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--filters&lt;/span&gt; &lt;span class="s2"&gt;"Name=tag:Name,Values=soa-lab1-app"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
            &lt;span class="s2"&gt;"Name=instance-state-name,Values=running"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--query&lt;/span&gt; &lt;span class="s2"&gt;"Reservations[0].Instances[0].{InstanceId:InstanceId,PublicIp:PublicIpAddress,State:State.Name,Tags:Tags}"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--output&lt;/span&gt; table
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Checkpoint
&lt;/h3&gt;

&lt;p&gt;Antes de seguir, confirma:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;La instancia &lt;code&gt;soa-lab1-app&lt;/code&gt; está en estado &lt;code&gt;Running&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Tiene &lt;code&gt;Public IPv4 address&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Tiene el Security Group &lt;code&gt;soa-lab1-app-sg&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Tiene los tags &lt;code&gt;Name=soa-lab1-app&lt;/code&gt; y &lt;code&gt;Lab=soa-lab1&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Paso 3 — Conectarte por SSH y validar la instancia
&lt;/h2&gt;

&lt;p&gt;Antes de instalar agentes o configurar logs, vamos a validar lo básico: que puedes entrar a la instancia. Si SSH falla aquí, mejor corregirlo ahora y no después.&lt;/p&gt;

&lt;h3&gt;
  
  
  Obtener la IP pública
&lt;/h3&gt;

&lt;p&gt;En AWS Console:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Ve a &lt;strong&gt;EC2 → Instances&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Selecciona la instancia &lt;code&gt;soa-lab1-app&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Copia el valor de &lt;strong&gt;Public IPv4 address&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;También puedes obtenerla por CLI:&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;REGION&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"us-east-1"&lt;/span&gt;

aws ec2 describe-instances &lt;span class="nt"&gt;--region&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$REGION&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--filters&lt;/span&gt; &lt;span class="s2"&gt;"Name=tag:Name,Values=soa-lab1-app"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
            &lt;span class="s2"&gt;"Name=instance-state-name,Values=running"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--query&lt;/span&gt; &lt;span class="s2"&gt;"Reservations[0].Instances[0].PublicIpAddress"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--output&lt;/span&gt; text
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;En los siguientes comandos usaré el placeholder &lt;code&gt;&amp;lt;PUBLIC_IP&amp;gt;&lt;/code&gt;. Reemplázalo por la IP real de tu instancia.&lt;/p&gt;

&lt;h3&gt;
  
  
  Conectarte por SSH
&lt;/h3&gt;

&lt;p&gt;Si estás en Mac/Linux, probablemente el archivo quedó en &lt;code&gt;~/Downloads/kp-soa-lab1.pem&lt;/code&gt;. Ajusta la ruta si lo guardaste en otra carpeta.&lt;/p&gt;

&lt;p&gt;Primero asegura los permisos de la llave:&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;chmod &lt;/span&gt;400 ~/Downloads/kp-soa-lab1.pem
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Luego entra a la instancia:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ssh &lt;span class="nt"&gt;-i&lt;/span&gt; ~/Downloads/kp-soa-lab1.pem ec2-user@&amp;lt;PUBLIC_IP&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ejemplo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ssh &lt;span class="nt"&gt;-i&lt;/span&gt; ~/Downloads/kp-soa-lab1.pem ec2-user@3.123.45.67
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Cuando pregunte si confías en el host, responde &lt;code&gt;yes&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Validaciones rápidas dentro de la instancia
&lt;/h3&gt;

&lt;p&gt;Una vez dentro, ejecuta:&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;uname&lt;/span&gt; &lt;span class="nt"&gt;-a&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Y valida salida a Internet:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-s&lt;/span&gt; https://checkip.amazonaws.com
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Checkpoint
&lt;/h3&gt;

&lt;p&gt;Antes de seguir, confirma:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Pudiste conectarte por SSH.&lt;/li&gt;
&lt;li&gt;Ves el prompt de &lt;code&gt;ec2-user&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;uname -a&lt;/code&gt; responde correctamente.&lt;/li&gt;
&lt;li&gt;La instancia tiene salida a Internet.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Paso 4 — Preparar CloudWatch Logs
&lt;/h2&gt;

&lt;p&gt;Antes de instalar el agente en la instancia, vamos a crear el Log Group donde llegarán los logs. La idea es dejar el destino listo y configurar una retención corta desde el inicio.&lt;/p&gt;

&lt;h3&gt;
  
  
  Crear el Log Group desde la consola
&lt;/h3&gt;

&lt;p&gt;En AWS Console:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Ve a &lt;strong&gt;CloudWatch&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;En el menú izquierdo, entra a &lt;strong&gt;Logs → Log groups&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Selecciona &lt;strong&gt;Create log group&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;En &lt;strong&gt;Name&lt;/strong&gt;, usa &lt;code&gt;/soa/lab1/system&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Crea el Log Group.&lt;/li&gt;
&lt;li&gt;Entra al Log Group recién creado.&lt;/li&gt;
&lt;li&gt;Busca &lt;strong&gt;Retention setting&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Selecciona &lt;strong&gt;Edit&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Cambia la retención a &lt;code&gt;3 days&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Guarda el cambio.&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;Ojo: si dejas la retención en “Never expire”, los logs no se eliminan automáticamente. Para un laboratorio pequeño puede parecer poco relevante, pero es una mala costumbre operativa.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  CLI opcional
&lt;/h3&gt;

&lt;p&gt;Si prefieres hacerlo por CLI:&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;REGION&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"us-east-1"&lt;/span&gt;

aws logs create-log-group &lt;span class="nt"&gt;--region&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$REGION&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--log-group-name&lt;/span&gt; &lt;span class="s2"&gt;"/soa/lab1/system"&lt;/span&gt; 2&amp;gt;/dev/null &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nb"&gt;true

&lt;/span&gt;aws logs put-retention-policy &lt;span class="nt"&gt;--region&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$REGION&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--log-group-name&lt;/span&gt; &lt;span class="s2"&gt;"/soa/lab1/system"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--retention-in-days&lt;/span&gt; 3
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Checkpoint
&lt;/h3&gt;

&lt;p&gt;Antes de seguir, valida:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Existe el Log Group &lt;code&gt;/soa/lab1/system&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;La retención está configurada en &lt;code&gt;3 days&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Paso 5 — Instalar y configurar CloudWatch Agent
&lt;/h2&gt;

&lt;p&gt;Ahora vamos a instalar y configurar &lt;strong&gt;CloudWatch Agent&lt;/strong&gt; en la instancia EC2. Este agente enviará logs y métricas básicas hacia CloudWatch. Sin este paso, tendríamos una instancia corriendo, pero con poca visibilidad operativa.&lt;/p&gt;

&lt;p&gt;No estamos montando una solución completa de observabilidad. Solo queremos una base mínima y funcional: logs centralizados y algunas métricas adicionales desde la instancia.&lt;/p&gt;

&lt;h3&gt;
  
  
  5.1 Crear el IAM Role para la instancia
&lt;/h3&gt;

&lt;p&gt;Primero necesitamos que la EC2 tenga permisos para publicar logs y métricas en CloudWatch.&lt;/p&gt;

&lt;p&gt;En AWS Console:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Ve a &lt;strong&gt;IAM → Roles&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Selecciona &lt;strong&gt;Create role&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;En &lt;strong&gt;Trusted entity type&lt;/strong&gt;, selecciona &lt;code&gt;AWS service&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;En &lt;strong&gt;Use case&lt;/strong&gt;, selecciona &lt;code&gt;EC2&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;En permisos, agrega la política administrada &lt;code&gt;CloudWatchAgentServerPolicy&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Asigna este nombre al role: &lt;code&gt;soa-lab1-ec2-cw-role&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Crea el role.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Ahora asócialo a la instancia:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Ve a &lt;strong&gt;EC2 → Instances&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Selecciona &lt;code&gt;soa-lab1-app&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Ve a &lt;strong&gt;Actions → Security → Modify IAM role&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Selecciona &lt;code&gt;soa-lab1-ec2-cw-role&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Guarda el cambio.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;En los detalles de la instancia, confirma que el campo &lt;strong&gt;IAM role&lt;/strong&gt; muestre &lt;code&gt;soa-lab1-ec2-cw-role&lt;/code&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Ojo: si la instancia no tiene este role, el agente puede instalarse y arrancar, pero no podrá publicar correctamente en CloudWatch.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  5.2 Instalar CloudWatch Agent en la EC2
&lt;/h3&gt;

&lt;p&gt;Conéctate por SSH a la instancia &lt;code&gt;soa-lab1-app&lt;/code&gt; y ejecuta:&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;sudo &lt;/span&gt;yum &lt;span class="nt"&gt;-y&lt;/span&gt; &lt;span class="nb"&gt;install &lt;/span&gt;amazon-cloudwatch-agent &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nb"&gt;sudo &lt;/span&gt;dnf &lt;span class="nt"&gt;-y&lt;/span&gt; &lt;span class="nb"&gt;install &lt;/span&gt;amazon-cloudwatch-agent
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Nota: usamos &lt;code&gt;yum&lt;/code&gt; o &lt;code&gt;dnf&lt;/code&gt; para cubrir Amazon Linux 2 y Amazon Linux 2023. Si uno no aplica, el otro debería funcionar.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  5.3 Crear la configuración del agente
&lt;/h3&gt;

&lt;p&gt;Ahora crea el archivo de configuración del agente. Este archivo le indica al agente qué logs enviar y qué métricas adicionales recolectar.&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;sudo tee&lt;/span&gt; /opt/aws/amazon-cloudwatch-agent/etc/amazon-cloudwatch-agent.json &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; /dev/null &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="no"&gt;EOF&lt;/span&gt;&lt;span class="sh"&gt;'
{
  "logs": {
    "logs_collected": {
      "files": {
        "collect_list": [
          {
            "file_path": "/var/log/cloud-init.log",
            "log_group_name": "/soa/lab1/system",
            "log_stream_name": "{instance_id}/cloud-init"
          }
        ]
      }
    }
  },
  "metrics": {
    "metrics_collected": {
      "mem": {
        "measurement": [
          "mem_used_percent"
        ]
      },
      "disk": {
        "measurement": [
          "disk_used_percent"
        ],
        "resources": [
          "*"
        ]
      }
    }
  }
}
&lt;/span&gt;&lt;span class="no"&gt;EOF
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;¿Qué estamos haciendo aquí?&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Enviamos &lt;code&gt;/var/log/cloud-init.log&lt;/code&gt; hacia CloudWatch Logs.&lt;/li&gt;
&lt;li&gt;Usamos el Log Group &lt;code&gt;/soa/lab1/system&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Creamos un Log Stream por instancia usando &lt;code&gt;{instance_id}/cloud-init&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Recolectamos métricas básicas de memoria y disco.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  5.4 Arrancar el agente
&lt;/h3&gt;

&lt;p&gt;Ejecuta:&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;sudo&lt;/span&gt; /opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent-ctl &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-a&lt;/span&gt; fetch-config &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-m&lt;/span&gt; ec2 &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-c&lt;/span&gt; file:/opt/aws/amazon-cloudwatch-agent/etc/amazon-cloudwatch-agent.json &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-s&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Este comando carga la configuración local, indica que el agente corre en modo EC2 y arranca el servicio después de aplicar el archivo.&lt;/p&gt;

&lt;h3&gt;
  
  
  5.5 Verificar el estado del agente
&lt;/h3&gt;

&lt;p&gt;Ejecuta:&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;sudo&lt;/span&gt; /opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent-ctl &lt;span class="nt"&gt;-a&lt;/span&gt; status
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;La salida debe mostrar algo parecido a &lt;code&gt;"status": "running"&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Checkpoint
&lt;/h3&gt;

&lt;p&gt;Antes de seguir, valida:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;El IAM Role &lt;code&gt;soa-lab1-ec2-cw-role&lt;/code&gt; está asociado a la instancia.&lt;/li&gt;
&lt;li&gt;El agente está instalado.&lt;/li&gt;
&lt;li&gt;El comando de estado muestra &lt;code&gt;running&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;En &lt;strong&gt;CloudWatch → Logs → Log groups → /soa/lab1/system&lt;/strong&gt; aparece un Log Stream parecido a &lt;code&gt;i-xxxxxxxxxxxxxxxxx/cloud-init&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;Puede tardar unos minutos en aparecer. Si no aparece de inmediato, espera un poco y refresca la consola.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Paso 6 — Consultar logs con CloudWatch Logs Insights
&lt;/h2&gt;

&lt;p&gt;Ya estamos enviando logs desde la instancia hacia CloudWatch. Ahora vamos a consultarlos sin entrar por SSH al servidor.&lt;/p&gt;

&lt;p&gt;Esta es una de las primeras ganancias reales de centralizar logs: puedes investigar desde CloudWatch, filtrar eventos y revisar actividad reciente sin depender de entrar manualmente a la EC2.&lt;/p&gt;

&lt;h3&gt;
  
  
  Ejecutar una consulta desde la consola
&lt;/h3&gt;

&lt;p&gt;En AWS Console:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Ve a &lt;strong&gt;CloudWatch&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;En el menú izquierdo, entra a &lt;strong&gt;Logs → Logs Insights&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Selecciona el Log Group &lt;code&gt;/soa/lab1/system&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;En el editor de query, pega esta consulta:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="n"&gt;fields&lt;/span&gt; &lt;span class="o"&gt;@&lt;/span&gt;&lt;span class="nb"&gt;timestamp&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;@&lt;/span&gt;&lt;span class="n"&gt;message&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;sort&lt;/span&gt; &lt;span class="o"&gt;@&lt;/span&gt;&lt;span class="nb"&gt;timestamp&lt;/span&gt; &lt;span class="k"&gt;desc&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="k"&gt;limit&lt;/span&gt; &lt;span class="mi"&gt;20&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Selecciona un rango de tiempo reciente, por ejemplo &lt;code&gt;Last 15 minutes&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Ejecuta la consulta.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Deberías ver eventos recientes del archivo &lt;code&gt;/var/log/cloud-init.log&lt;/code&gt;, con su timestamp y mensaje correspondiente.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;EC2 → CloudWatch Agent → CloudWatch Logs → Logs Insights
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  CLI opcional
&lt;/h3&gt;

&lt;p&gt;También puedes iniciar una consulta desde CloudShell o desde tu terminal con AWS CLI configurado:&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;REGION&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"us-east-1"&lt;/span&gt;

&lt;span class="nv"&gt;QUERY_ID&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;aws logs start-query &lt;span class="nt"&gt;--region&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$REGION&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--log-group-name&lt;/span&gt; &lt;span class="s2"&gt;"/soa/lab1/system"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--start-time&lt;/span&gt; &lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;date&lt;/span&gt; &lt;span class="nt"&gt;-u&lt;/span&gt; &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'15 minutes ago'&lt;/span&gt; +%s&lt;span class="si"&gt;)&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--end-time&lt;/span&gt; &lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;date&lt;/span&gt; &lt;span class="nt"&gt;-u&lt;/span&gt; +%s&lt;span class="si"&gt;)&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--query-string&lt;/span&gt; &lt;span class="s2"&gt;"fields @timestamp, @message | sort @timestamp desc | limit 20"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--query&lt;/span&gt; &lt;span class="s1"&gt;'queryId'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--output&lt;/span&gt; text&lt;span class="si"&gt;)&lt;/span&gt;

&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$QUERY_ID&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Luego consulta el resultado:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;aws logs get-query-results &lt;span class="nt"&gt;--region&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$REGION&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--query-id&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$QUERY_ID&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Ojo: si estás en Mac y el comando &lt;code&gt;date -d&lt;/code&gt; no funciona, ejecuta esta parte desde CloudShell o ajusta el cálculo de tiempo según tu sistema operativo.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Checkpoint
&lt;/h3&gt;

&lt;p&gt;Antes de seguir, valida:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;La consulta devuelve eventos.&lt;/li&gt;
&lt;li&gt;Puedes ver timestamps recientes.&lt;/li&gt;
&lt;li&gt;El Log Group usado es &lt;code&gt;/soa/lab1/system&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Paso 7 — Crear SNS Topic y suscripción por email
&lt;/h2&gt;

&lt;p&gt;Ahora necesitamos un canal de notificación. Cuando la alarma de CloudWatch cambie a estado &lt;code&gt;ALARM&lt;/code&gt;, queremos que alguien se entere. Para este primer lab usaremos algo simple y efectivo: &lt;strong&gt;Amazon SNS + email&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;No estamos automatizando remediación todavía. Aquí solo queremos cerrar el flujo mínimo de alerta.&lt;/p&gt;

&lt;h3&gt;
  
  
  Crear el SNS Topic desde la consola
&lt;/h3&gt;

&lt;p&gt;En AWS Console:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Ve a &lt;strong&gt;Amazon SNS&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;En el menú izquierdo, entra a &lt;strong&gt;Topics&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Selecciona &lt;strong&gt;Create topic&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;En &lt;strong&gt;Type&lt;/strong&gt;, selecciona &lt;code&gt;Standard&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;En &lt;strong&gt;Name&lt;/strong&gt;, usa &lt;code&gt;soa-lab1-alerts-v2&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Crea el topic.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Crear la suscripción por email
&lt;/h3&gt;

&lt;p&gt;Ahora entra al topic &lt;code&gt;soa-lab1-alerts-v2&lt;/code&gt; y crea una suscripción:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Selecciona &lt;strong&gt;Create subscription&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;En &lt;strong&gt;Protocol&lt;/strong&gt;, elige &lt;code&gt;Email&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;En &lt;strong&gt;Endpoint&lt;/strong&gt;, escribe tu correo. Ejemplo: &lt;code&gt;tu-correo@dominio.com&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Selecciona &lt;strong&gt;Create subscription&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Abre tu correo y confirma la suscripción desde el mensaje de SNS.&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;Ojo: si no confirmas la suscripción, SNS no podrá enviarte notificaciones. La suscripción quedará en estado &lt;code&gt;Pending confirmation&lt;/code&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  CLI opcional
&lt;/h3&gt;

&lt;p&gt;Si prefieres hacerlo por CLI:&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;REGION&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"us-east-1"&lt;/span&gt;
&lt;span class="nv"&gt;EMAIL&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"tu-correo@dominio.com"&lt;/span&gt;

&lt;span class="nv"&gt;TOPIC_ARN&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;aws sns create-topic &lt;span class="nt"&gt;--region&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$REGION&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--name&lt;/span&gt; &lt;span class="s2"&gt;"soa-lab1-alerts-v2"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--query&lt;/span&gt; &lt;span class="s1"&gt;'TopicArn'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--output&lt;/span&gt; text&lt;span class="si"&gt;)&lt;/span&gt;

&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$TOPIC_ARN&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;

aws sns subscribe &lt;span class="nt"&gt;--region&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$REGION&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--topic-arn&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$TOPIC_ARN&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--protocol&lt;/span&gt; email &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--notification-endpoint&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$EMAIL&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Después de ejecutar esto, revisa tu correo y confirma la suscripción.&lt;/p&gt;

&lt;h3&gt;
  
  
  Checkpoint
&lt;/h3&gt;

&lt;p&gt;Antes de seguir, valida:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Existe el SNS Topic &lt;code&gt;soa-lab1-alerts-v2&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;La suscripción aparece como &lt;code&gt;Confirmed&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;No debe quedar en &lt;code&gt;Pending confirmation&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Paso 8 — Crear la alarma de CPU y notificar a SNS
&lt;/h2&gt;

&lt;p&gt;Ya tenemos logs centralizados y un canal de notificación. Ahora vamos a crear una alarma sencilla de CPU.&lt;/p&gt;

&lt;p&gt;La idea es conectar una señal técnica con una acción operativa:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;CPU alta → CloudWatch Alarm → SNS → email
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Esto ya le da a Camilo una primera capacidad proactiva: no esperar a que la Sra. Blanca diga “el sistema está lento”, sino recibir una alerta cuando una métrica supere un umbral definido.&lt;/p&gt;

&lt;h3&gt;
  
  
  Crear la alarma desde la consola
&lt;/h3&gt;

&lt;p&gt;En AWS Console:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Ve a &lt;strong&gt;CloudWatch → Alarms&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Selecciona &lt;strong&gt;Create alarm&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;En &lt;strong&gt;Specify metric and conditions&lt;/strong&gt;, selecciona &lt;strong&gt;Select metric&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Busca o navega por &lt;strong&gt;EC2 → Per-Instance Metrics&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Selecciona la métrica &lt;code&gt;CPUUtilization&lt;/code&gt; correspondiente a la instancia &lt;code&gt;soa-lab1-app&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Selecciona &lt;strong&gt;Select metric&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Configura la condición así:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Threshold type:&lt;/strong&gt; Static.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Whenever CPUUtilization is:&lt;/strong&gt; Greater/Equal.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Threshold value:&lt;/strong&gt; &lt;code&gt;70&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Period:&lt;/strong&gt; &lt;code&gt;5 minutes&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Evaluation periods:&lt;/strong&gt; &lt;code&gt;1&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Datapoints to alarm:&lt;/strong&gt; &lt;code&gt;1 out of 1&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;Nota: para un laboratorio, este umbral nos sirve para validar el flujo. En producción, el umbral debe definirse según comportamiento real de la aplicación, baseline histórico y tolerancia del negocio.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;En &lt;strong&gt;Configure actions&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;En &lt;strong&gt;Alarm state trigger&lt;/strong&gt;, selecciona &lt;code&gt;In alarm&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;En notificación, elige &lt;strong&gt;Select an existing SNS topic&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Selecciona el topic &lt;code&gt;soa-lab1-alerts-v2&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Continúa con &lt;strong&gt;Next&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;En &lt;strong&gt;Add name and description&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Alarm name:&lt;/strong&gt; &lt;code&gt;ALARM-soa-lab1-high-cpu&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Description opcional:&lt;/strong&gt; &lt;code&gt;CPU &amp;gt;= 70% durante 5 minutos. Notifica a soa-lab1-alerts-v2.&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Luego revisa el resumen y selecciona &lt;strong&gt;Create alarm&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  CLI opcional para validar
&lt;/h3&gt;

&lt;p&gt;Puedes revisar que la alarma exista y que tenga acciones habilitadas:&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;REGION&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"us-east-1"&lt;/span&gt;

aws cloudwatch describe-alarms &lt;span class="nt"&gt;--region&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$REGION&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--alarm-names&lt;/span&gt; &lt;span class="s2"&gt;"ALARM-soa-lab1-high-cpu"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--query&lt;/span&gt; &lt;span class="s2"&gt;"MetricAlarms[0].{AlarmName:AlarmName,StateValue:StateValue,MetricName:MetricName,Namespace:Namespace,Threshold:Threshold,Period:Period,EvaluationPeriods:EvaluationPeriods,ActionsEnabled:ActionsEnabled,AlarmActions:AlarmActions}"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--output&lt;/span&gt; table
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Checkpoint
&lt;/h3&gt;

&lt;p&gt;Antes de seguir, valida:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;La alarma &lt;code&gt;ALARM-soa-lab1-high-cpu&lt;/code&gt; aparece en &lt;strong&gt;CloudWatch → Alarms&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;La métrica asociada es &lt;code&gt;CPUUtilization&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;El threshold está en &lt;code&gt;&amp;gt;= 70&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Actions enabled&lt;/strong&gt; está en &lt;code&gt;Yes&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;En &lt;strong&gt;Alarm actions&lt;/strong&gt; aparece el SNS Topic &lt;code&gt;soa-lab1-alerts-v2&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Paso 9 — Probar la alarma y confirmar el email
&lt;/h2&gt;

&lt;p&gt;Crear una alarma no es suficiente. En operación, lo importante es validar que el flujo completo funciona.&lt;/p&gt;

&lt;p&gt;Aquí vamos a probar el camino completo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;CPU alta → CloudWatch Alarm → SNS Topic → Email
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;La idea es generar una carga controlada en la instancia para que la alarma cambie a estado &lt;code&gt;ALARM&lt;/code&gt; y recibas la notificación por correo.&lt;/p&gt;

&lt;h3&gt;
  
  
  9.1 Conectarte por SSH
&lt;/h3&gt;

&lt;p&gt;Conéctate nuevamente a la instancia &lt;code&gt;soa-lab1-app&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;ssh &lt;span class="nt"&gt;-i&lt;/span&gt; ~/Downloads/kp-soa-lab1.pem ec2-user@&amp;lt;PUBLIC_IP&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Reemplaza &lt;code&gt;&amp;lt;PUBLIC_IP&amp;gt;&lt;/code&gt; por la IP pública real de tu instancia.&lt;/p&gt;

&lt;h3&gt;
  
  
  9.2 Instalar &lt;code&gt;stress&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;Dentro de la EC2, instala la herramienta &lt;code&gt;stress&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;&lt;span class="nb"&gt;sudo &lt;/span&gt;yum &lt;span class="nt"&gt;-y&lt;/span&gt; &lt;span class="nb"&gt;install &lt;/span&gt;stress &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nb"&gt;sudo &lt;/span&gt;dnf &lt;span class="nt"&gt;-y&lt;/span&gt; &lt;span class="nb"&gt;install &lt;/span&gt;stress
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  9.3 Generar carga de CPU
&lt;/h3&gt;

&lt;p&gt;Ejecuta una carga controlada por unos minutos:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;stress &lt;span class="nt"&gt;--cpu&lt;/span&gt; 4 &lt;span class="nt"&gt;--timeout&lt;/span&gt; 600
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Este comando genera carga de CPU durante 600 segundos, es decir, 10 minutos.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Ojo: la alarma está configurada con un periodo de 5 minutos. No esperes que cambie de estado al segundo. Dale unos minutos para que CloudWatch recolecte los datos y evalúe la condición.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  9.4 Validar la alarma en CloudWatch
&lt;/h3&gt;

&lt;p&gt;En AWS Console:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Ve a &lt;strong&gt;CloudWatch → Alarms&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Abre la alarma &lt;code&gt;ALARM-soa-lab1-high-cpu&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Revisa el estado.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Dependiendo del momento en que revises, podrías ver una transición parecida a esta:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;INSUFFICIENT_DATA → OK → ALARM
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;No siempre ocurre exactamente en ese orden, pero lo importante es que la alarma llegue a estado &lt;code&gt;ALARM&lt;/code&gt; al menos una vez.&lt;/p&gt;

&lt;h3&gt;
  
  
  9.5 Confirmar el correo de SNS
&lt;/h3&gt;

&lt;p&gt;Revisa el correo que usaste en la suscripción de SNS. Deberías recibir una notificación con un asunto parecido a:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ALARM: "ALARM-soa-lab1-high-cpu"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Cuando termine la prueba de carga, la CPU debería bajar y la alarma volverá a &lt;code&gt;OK&lt;/code&gt;. Esto puede tardar algunos minutos.&lt;/p&gt;

&lt;h3&gt;
  
  
  Checkpoint
&lt;/h3&gt;

&lt;p&gt;Antes de cerrar el lab, valida:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;La alarma &lt;code&gt;ALARM-soa-lab1-high-cpu&lt;/code&gt; llegó a estado &lt;code&gt;ALARM&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Recibiste el correo de SNS.&lt;/li&gt;
&lt;li&gt;Al terminar la carga, la alarma volvió a estado &lt;code&gt;OK&lt;/code&gt; o empezó a normalizarse.&lt;/li&gt;
&lt;li&gt;El flujo completo quedó probado: métrica, alarma, notificación.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Clean up completo — SOA-Lab1
&lt;/h2&gt;

&lt;p&gt;Ahora vamos a eliminar los recursos creados en el laboratorio. Esto evita costos innecesarios y mantiene tu cuenta limpia para futuros labs.&lt;/p&gt;

&lt;p&gt;Trabajaremos en la región &lt;code&gt;us-east-1&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Recursos a eliminar
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;CloudWatch Alarm:&lt;/strong&gt; &lt;code&gt;ALARM-soa-lab1-high-cpu&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;SNS Topic:&lt;/strong&gt; &lt;code&gt;soa-lab1-alerts-v2&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;CloudWatch Log Group:&lt;/strong&gt; &lt;code&gt;/soa/lab1/system&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;EC2 Instance:&lt;/strong&gt; &lt;code&gt;soa-lab1-app&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Security Group:&lt;/strong&gt; &lt;code&gt;soa-lab1-app-sg&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Key Pair:&lt;/strong&gt; &lt;code&gt;kp-soa-lab1&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;IAM Role:&lt;/strong&gt; &lt;code&gt;soa-lab1-ec2-cw-role&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Orden recomendado
&lt;/h3&gt;

&lt;p&gt;Elimina los recursos en este orden para evitar bloqueos o dependencias:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;CloudWatch Alarm:&lt;/strong&gt; elimínala primero para que deje de evaluar y notificar.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;SNS Topic:&lt;/strong&gt; borra el topic &lt;code&gt;soa-lab1-alerts-v2&lt;/code&gt;. Al eliminarlo, también se eliminan sus suscripciones asociadas.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;CloudWatch Log Group:&lt;/strong&gt; elimina &lt;code&gt;/soa/lab1/system&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;EC2 Instance:&lt;/strong&gt; termina la instancia &lt;code&gt;soa-lab1-app&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Security Group:&lt;/strong&gt; elimina &lt;code&gt;soa-lab1-app-sg&lt;/code&gt; solo cuando la instancia ya esté terminada.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Key Pair:&lt;/strong&gt; elimina &lt;code&gt;kp-soa-lab1&lt;/code&gt; desde &lt;strong&gt;EC2 → Key Pairs&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;IAM Role:&lt;/strong&gt; elimina &lt;code&gt;soa-lab1-ec2-cw-role&lt;/code&gt;. Si AWS no te deja borrarlo de inmediato, revisa si aún tiene políticas asociadas o si la instancia todavía aparece vinculada.&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;Ojo: el Security Group puede quedar bloqueado mientras la instancia siga existiendo. Si no te deja borrarlo, espera a que la instancia quede completamente terminada y vuelve a intentar.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Validación final
&lt;/h3&gt;

&lt;p&gt;Al terminar, confirma que:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;No existe la alarma &lt;code&gt;ALARM-soa-lab1-high-cpu&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;No existe el SNS Topic &lt;code&gt;soa-lab1-alerts-v2&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;No existe el Log Group &lt;code&gt;/soa/lab1/system&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;La instancia &lt;code&gt;soa-lab1-app&lt;/code&gt; está terminada.&lt;/li&gt;
&lt;li&gt;No existe el Security Group &lt;code&gt;soa-lab1-app-sg&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;No existe el Key Pair &lt;code&gt;kp-soa-lab1&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;No existe el IAM Role &lt;code&gt;soa-lab1-ec2-cw-role&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Troubleshooting rápido
&lt;/h2&gt;

&lt;p&gt;Si algo no funciona, revisa estos puntos:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;No llega el email de SNS:&lt;/strong&gt; revisa si la suscripción quedó en &lt;code&gt;Pending confirmation&lt;/code&gt;. Debes abrir el correo de SNS y confirmar la suscripción.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;No aparecen logs en CloudWatch:&lt;/strong&gt; confirma que el CloudWatch Agent esté en estado &lt;code&gt;running&lt;/code&gt; y que la instancia tenga asociado el role &lt;code&gt;soa-lab1-ec2-cw-role&lt;/code&gt; con la política &lt;code&gt;CloudWatchAgentServerPolicy&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;SSH no conecta:&lt;/strong&gt; verifica que el Security Group permita SSH &lt;code&gt;22&lt;/code&gt; desde tu IP pública real en formato &lt;code&gt;/32&lt;/code&gt;. Ojo: la IP de CloudShell no necesariamente es tu IP local.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;La alarma no dispara:&lt;/strong&gt; recuerda que la alarma usa un periodo de 5 minutos. Si tarda, mantén la carga unos minutos más, usa &lt;code&gt;stress --cpu 4 --timeout 600&lt;/code&gt; o baja temporalmente el umbral para validar el flujo.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Well-Architected lens: ¿Qué aplicamos aquí?
&lt;/h2&gt;

&lt;p&gt;Este laboratorio es pequeño, pero ya toca varios principios importantes del &lt;strong&gt;AWS Well-Architected Framework&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Operational Excellence:&lt;/strong&gt; centralizamos logs y usamos Logs Insights para investigar sin depender de entrar manualmente a la instancia.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Reliability:&lt;/strong&gt; una alarma básica permite detectar una condición anómala antes de que el problema dependa solo del reporte de un usuario.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Security:&lt;/strong&gt; restringimos SSH a tu IP pública &lt;code&gt;/32&lt;/code&gt; y evitamos exponer el puerto 22 a &lt;code&gt;0.0.0.0/0&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cost Optimization:&lt;/strong&gt; configuramos retención corta de logs y hacemos cleanup completo al final.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Performance Efficiency:&lt;/strong&gt; usamos una instancia pequeña y suficiente para el objetivo del lab, sin sobredimensionar recursos.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Resultado esperado
&lt;/h2&gt;

&lt;p&gt;Al finalizar este laboratorio deberías tener claro cómo construir una observabilidad mínima para una instancia EC2:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Crear un Log Group en CloudWatch Logs.&lt;/li&gt;
&lt;li&gt;Instalar y configurar CloudWatch Agent.&lt;/li&gt;
&lt;li&gt;Consultar logs con Logs Insights.&lt;/li&gt;
&lt;li&gt;Crear un SNS Topic con suscripción por email.&lt;/li&gt;
&lt;li&gt;Crear una alarma de CPU.&lt;/li&gt;
&lt;li&gt;Probar el flujo real de alerta.&lt;/li&gt;
&lt;li&gt;Limpiar todos los recursos del laboratorio.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;La idea no era montar una plataforma completa de monitoreo, sino construir una primera base operativa: ver señales, consultar evidencia y recibir una alerta cuando algo se sale del comportamiento esperado.&lt;/p&gt;




&lt;h2&gt;
  
  
  Referencias oficiales
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/WhatIsCloudWatchLogs.html" rel="noopener noreferrer"&gt;Amazon CloudWatch Logs — Conceptos y Log Groups&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/AnalyzingLogData.html" rel="noopener noreferrer"&gt;CloudWatch Logs Insights — Consultas y uso&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/AlarmThatSendsEmail.html" rel="noopener noreferrer"&gt;CloudWatch Alarms — Crear alarmas y acciones&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.aws.amazon.com/sns/latest/dg/sns-create-topic.html" rel="noopener noreferrer"&gt;Amazon SNS — Topics y suscripciones&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/Install-CloudWatch-Agent.html" rel="noopener noreferrer"&gt;CloudWatch Agent — Instalación y configuración en EC2&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  ¿Qué viene en el próximo lab?
&lt;/h2&gt;

&lt;p&gt;En este laboratorio dejamos una capacidad mínima de observabilidad: logs centralizados, una alarma y una notificación funcionando.&lt;/p&gt;

&lt;p&gt;Pero observar una carga es solo una parte de operar bien. También necesitamos saber &lt;strong&gt;quién hizo qué, cuándo lo hizo y desde dónde&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;En el próximo laboratorio vamos a entrar en un tema clave de seguridad y auditoría:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;SCS-Lab1 — CloudTrail: Trail + S3 + KMS + Log Validation&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;La idea será construir un baseline de auditoría en una cuenta AWS: crear un trail, enviar eventos a S3, protegerlos con KMS y habilitar validación de integridad de logs.&lt;/p&gt;

&lt;p&gt;En otras palabras: pasar de “tengo señales operativas” a “tengo evidencia auditable y protegida”.&lt;/p&gt;

&lt;p&gt;Nos vemos en el próximo laboratorio de &lt;strong&gt;Digital Cafe Luna&lt;/strong&gt;.&lt;/p&gt;




</description>
      <category>aws</category>
      <category>cloudskills</category>
      <category>tutorial</category>
      <category>cloudwatch</category>
    </item>
    <item>
      <title>Certificarse en AWS no debería quedarse solo en responder preguntas: nace Digital Cafe Luna</title>
      <dc:creator>Luis Eduardo Lunar Guevara</dc:creator>
      <pubDate>Mon, 11 May 2026 23:00:00 +0000</pubDate>
      <link>https://dev.to/llunarg/certificarse-en-aws-no-deberia-quedarse-solo-en-responder-preguntas-nace-digital-cafe-luna-4pfo</link>
      <guid>https://dev.to/llunarg/certificarse-en-aws-no-deberia-quedarse-solo-en-responder-preguntas-nace-digital-cafe-luna-4pfo</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Nelson:&lt;/strong&gt; Alejandra, últimamente he estado pensando en algo que veo mucho en el mundo corporativo.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Alejandra:&lt;/strong&gt; ¿Qué cosa?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Nelson:&lt;/strong&gt; Que muchas veces las certificaciones terminan convertidas en una hoja de cálculo: personas certificadas, badges, métricas, cumplimiento… y sí, todo eso tiene valor. Pero me pregunto algo: ¿eso realmente garantiza que una persona pueda operar bien dentro del alcance de esa certificación?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Alejandra:&lt;/strong&gt; O sea, ¿alguien puede aprobar el examen, pero no necesariamente saber llevar eso a la práctica?.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Nelson:&lt;/strong&gt; Exactamente y es muy común. Puedes saber qué servicio usar para monitorear, alertar o remediar. Pero la pregunta real es otra: ¿lo sabes hacer?, ¿lo has hecho?, ¿lo puedes validar?, ¿entiendes qué riesgo estás reduciendo?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Esa conversación resume bastante bien la inquietud que me llevó a crear esta serie.&lt;/p&gt;

&lt;p&gt;No estoy en contra de las certificaciones; al contrario, creo que certificarse ayuda a ordenar conocimiento, entender un alcance técnico y validar una base formal frente a un proveedor como AWS. El problema aparece cuando el proceso se queda solo en memorizar preguntas, ver videos, repetir respuestas y buscar pasar el examen.&lt;/p&gt;

&lt;p&gt;Porque memorizar no es lo mismo que desarrollar capacidad operativa.&lt;/p&gt;

&lt;p&gt;Y en cloud, como sucede con muchas otras tecnologías, tarde o temprano hay que operar. Hay que entrar a la consola, usar CLI cuando haga falta, configurar, validar, equivocarse, corregir, revisar logs, entender permisos, controlar costos, limpiar recursos y tomar decisiones con criterio.&lt;/p&gt;

&lt;p&gt;El mercado no necesita únicamente personas certificadas, opino que el mejor escenario es otro: personas con capacidad operativa real que además, estén certificadas, ¡no lo contrario!.&lt;/p&gt;

&lt;h2&gt;
  
  
  La brecha
&lt;/h2&gt;

&lt;p&gt;Hay muchos cursos buenos, bancos de preguntas, bootcamps y documentación. Todo eso suma. Pero veo un espacio que todavía puede trabajarse mejor, especialmente en español: &lt;strong&gt;laboratorios ejecutables que conecten directamente las guías oficiales de examen de AWS con habilidades prácticas.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;No hablo de laboratorios sueltos ni de ejercicios genéricos. La idea es partir de los objetivos de las guías oficiales, entender el dominio, revisar la tarea que se espera dominar y llevar eso a una práctica concreta en AWS.&lt;/p&gt;

&lt;p&gt;En otras palabras:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Guía oficial / blueprint → caso práctico → laboratorio ejecutable → checkpoints → cleanup → mirada Well-Architected&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Porque nuevamente una cosa es leer que CloudWatch permite monitorear recursos y crear alarmas; otra cosa es configurar logs, crear métricas, definir una alarma, conectarla con SNS, probar si dispara, validar el flujo y limpiar todo al final para no dejar costos innecesarios.&lt;/p&gt;

&lt;p&gt;Responder bien una pregunta no es lo mismo que ejecutar bien una práctica.&lt;/p&gt;

&lt;h2&gt;
  
  
  Qué significa aprender AWS
&lt;/h2&gt;

&lt;p&gt;Para mí, aprender AWS no es solo saber que un servicio existe y que hace, es desarrollar criterio para entender cuándo usarlo, cuándo no, qué problema resuelve, qué costo introduce, qué riesgo reduce y cómo se comporta dentro de una arquitectura real.&lt;/p&gt;

&lt;p&gt;En cloud casi siempre hay más de una forma de resolver un problema, pero no todas las respuestas tienen la misma calidad arquitectónica. Una opción puede funcionar, pero ser costosa. Otra puede ser segura, pero compleja de operar. Otra puede resolver el problema hoy, pero dejar una deuda enorme para el equipo que tenga que mantenerla mañana.&lt;/p&gt;

&lt;p&gt;Por eso quiero que cada laboratorio tenga una conexión clara con el &lt;strong&gt;AWS Well-Architected Framework&lt;/strong&gt;. No como decoración al final del post, sino como una forma de cerrar la práctica con criterio: operación, seguridad, confiabilidad, eficiencia, costos y sostenibilidad.&lt;/p&gt;

&lt;p&gt;Porque que algo funcione no significa necesariamente que esté bien diseñado.&lt;/p&gt;

&lt;h2&gt;
  
  
  Por qué Digital Cafe Luna
&lt;/h2&gt;

&lt;p&gt;Para darle continuidad a la serie voy a usar una empresa ficticia llamada &lt;strong&gt;Digital Cafe Luna&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Es un digital coffee shop: un espacio donde personas del mundo tech, profesionales remotos, freelancers... pueden trabajar, reunirse, tomar café y compartir comunidad.&lt;/p&gt;

&lt;p&gt;Digital Cafe Luna empieza como una tienda física pequeña, un negocio local que poco a poco va creciendo. Primero necesita operar mejor su infraestructura básica; luego empieza a vender online, aparecen nuevas sedes, más usuarios, más datos, más riesgos, más costos y más necesidad de automatización.&lt;/p&gt;

&lt;p&gt;Ahí es donde AWS entra en la historia. No porque sí, sino porque el crecimiento del negocio empieza a exigir capacidades reales: observabilidad, seguridad, disponibilidad, control de costos, gobierno, automatización y operación cloud.&lt;/p&gt;

&lt;h2&gt;
  
  
  A quién va dirigida esta serie
&lt;/h2&gt;

&lt;p&gt;Esta serie es para personas que están preparando certificaciones AWS, pero no quieren quedarse solo con teoría. También es para Cloud Engineers junior, intermedios o semi-senior que ya conocen servicios, pero quieren fortalecer ejecución.&lt;/p&gt;

&lt;p&gt;También pienso en líderes técnicos, managers, directores de arquitectura, soluciones, operaciones o delivery que necesitan entender mejor lo que viven sus equipos. Porque colegas &lt;em&gt;no basta con mirar la operación desde el escritorio;&lt;/em&gt; hay que entender qué decisiones se toman, qué restricciones existen, qué riesgos aparecen y qué implica realmente operar una plataforma.&lt;/p&gt;

&lt;p&gt;Y, por supuesto, también pienso en personas que vienen de otros mundos profesionales y quieren entrar a cloud de forma práctica. En mis clases he visto contadores, médicos, personas de operaciones, empleados de restaurantes, negocios y muchas otras áreas.&lt;/p&gt;

&lt;p&gt;A ellos también les puede servir una serie así.&lt;/p&gt;

&lt;h2&gt;
  
  
  El método
&lt;/h2&gt;

&lt;p&gt;Cada laboratorio seguirá una estructura simple:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Guía oficial / blueprint:&lt;/strong&gt; partimos de un objetivo real del examen.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Caso práctico:&lt;/strong&gt; lo llevamos a un escenario de Digital Cafe Luna.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Lab ejecutable:&lt;/strong&gt; configuramos servicios reales en AWS.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Checkpoints:&lt;/strong&gt; validamos que cada parte funcione.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;CleanUp completo:&lt;/strong&gt; eliminamos recursos para evitar costos innecesarios.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Well-Architected lens:&lt;/strong&gt; cerramos conectando la práctica con buenas decisiones de arquitectura.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;La intención no es solo crear recursos. La intención es entender el caso, ejecutar, validar, equivocarse cuando toque, corregir y aprender.&lt;/p&gt;

&lt;h2&gt;
  
  
  Cadencia de publicación
&lt;/h2&gt;

&lt;p&gt;Mi intención es publicar un laboratorio cada semana, siempre priorizando la calidad, la ejecución real y la validación.&lt;/p&gt;

&lt;p&gt;El detalle completo estará en Dev.to, porque ahí puedo desarrollar el caso, explicar los pasos, incluir validaciones, comandos, cleanup y cierre técnico. LinkedIn será el punto de entrada: el espacio para abrir la conversación, compartir el gancho y conectar con quienes quieran ejecutar el laboratorio completo.&lt;/p&gt;

&lt;h2&gt;
  
  
  Qué viene primero
&lt;/h2&gt;

&lt;p&gt;El primer laboratorio será:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;SOA-Lab1 — Observabilidad mínima: CloudWatch Logs + Alarmas + SNS&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Un punto sencillo para empezar, pero muy importante: si no puedes observar una carga, tampoco puedes operarla bien, mucho menos garantizar su disponibilidad.&lt;/p&gt;

&lt;h2&gt;
  
  
  Para cerrar
&lt;/h2&gt;

&lt;p&gt;Esta serie no nace desde el ego de “miren lo que sé”. Nace desde una idea mucho más práctica: compartir mientras aprendo, ordenar conocimiento mientras lo explico y madurar capacidades mientras diseño laboratorios que otras personas también puedan ejecutar.&lt;/p&gt;

&lt;p&gt;Mi invitación es simple:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Planifica tu tiempo.&lt;/li&gt;
&lt;li&gt;Toma el control de tu aprendizaje.&lt;/li&gt;
&lt;li&gt;Ejecuta los laboratorios.&lt;/li&gt;
&lt;li&gt;Rompe cosas en ambientes controlados.&lt;/li&gt;
&lt;li&gt;Valida, corrige, limpia y repite.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Ahí es donde la teoría empieza a convertirse en habilidad.&lt;/p&gt;

&lt;p&gt;Nos vemos en el primer laboratorio de Digital Cafe Luna.&lt;/p&gt;

</description>
      <category>aws</category>
      <category>cloudskills</category>
      <category>devops</category>
      <category>career</category>
    </item>
    <item>
      <title>Trabajo remoto y cultura tóxica: lo que nadie dice</title>
      <dc:creator>Luis Eduardo Lunar Guevara</dc:creator>
      <pubDate>Thu, 07 Aug 2025 01:00:00 +0000</pubDate>
      <link>https://dev.to/llunarg/trabajo-remoto-y-cultura-toxica-lo-que-nadie-dice-31kj</link>
      <guid>https://dev.to/llunarg/trabajo-remoto-y-cultura-toxica-lo-que-nadie-dice-31kj</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%2Fyk81nt28ibtfamvjmwkg.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%2Fyk81nt28ibtfamvjmwkg.png" alt="Agotamiento, contradicciones culturales, desconexión humana y una crítica profunda a lo que se ha normalizado" width="800" height="800"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  ¿Productividad o autoexplotación digital?
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Antes, ibas al trabajo. Ahora, el trabajo entra al baño contigo.
&lt;/h4&gt;

&lt;p&gt;Literal.&lt;/p&gt;

&lt;p&gt;Antes había oficinas, reuniones presenciales, pausas para almorzar (o no), pero sabías que &lt;em&gt;estabas en una reunión, en un lugar de trabajo&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Hoy, con el trabajo remoto, hemos normalizado lo insostenible:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Reuniones desde el inodoro &lt;em&gt;(lavatory)&lt;/em&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Almuerzos frente a tres pantallas.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Tres videollamadas al mismo tiempo… y al final, no estás realmente en ninguna.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Responder un Slack mientras estás en una llamada por Teams y compartes pantalla en Zoom.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;No es una exageración. Es la vida diaria de miles.&lt;/p&gt;

&lt;h2&gt;
  
  
  Cultura de LinkedIn vs. realidad interna.
&lt;/h2&gt;

&lt;p&gt;Y lo peor no es eso.&lt;/p&gt;

&lt;p&gt;Lo peor es que muchas de las organizaciones que promueven esta dinámica son las que se llenan la boca con términos como &lt;em&gt;“automatización”, “agilidad”, “eficiencia operacional” y “upskilling”&lt;/em&gt;.&lt;br&gt;
Venden transformación digital, pero no transforman su propia cultura.&lt;/p&gt;

&lt;p&gt;Mientras tanto, sus propios equipos no tienen tiempo para aprender, ni para comer, ni para vivir. Y no hablemos de innovar.&lt;/p&gt;

&lt;h2&gt;
  
  
  Estar siempre conectados no es estar comprometidos.
&lt;/h2&gt;

&lt;p&gt;¿En qué momento se culturizó lo anormal?&lt;/p&gt;

&lt;p&gt;Hoy muchas organizaciones que miden el compromiso por conexión, no por impacto.&lt;br&gt;
Celebran “estar siempre disponibles”, cuando eso es sinónimo de estar siempre agotados.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Vale la pena insistir en esto&lt;/strong&gt;: el problema no es el trabajo remoto. El problema es cómo se ha malinterpretado.&lt;/p&gt;

&lt;p&gt;Porque la eficiencia mal gestionada se convierte en desgaste. Y ese desgaste termina afectando lo que más debería importar: &lt;strong&gt;el servicio, la calidad y la experiencia del cliente&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Lo que compran los clientes… no siempre es valor.
&lt;/h2&gt;

&lt;p&gt;En este escenario, algunos clientes muchas veces no compran servicios.&lt;br&gt;
Compran seguridad financiera: una gran marca que les da tranquilidad, aunque detrás haya desorden, rotación, burnout y servicios mediocres.&lt;/p&gt;

&lt;p&gt;Mientras tanto, empresas más pequeñas, más organizadas, con talento de verdad, metodologías claras, mejores precios, prestan mejores servicios… Pero no tienen el músculo financiero para entrar a competir.&lt;/p&gt;

&lt;h2&gt;
  
  
  Talento promedio no escala. Talento quemado, tampoco.
&lt;/h2&gt;

&lt;p&gt;¿Y quién paga el precio?&lt;/p&gt;

&lt;p&gt;El colaborador.&lt;br&gt;
Que trabaja por inercia.&lt;br&gt;
Que se sostiene solo por el salario y la responsabilidad familiar.&lt;br&gt;
Que va perdiendo salud, motivación… y a veces hasta sentido.&lt;/p&gt;

&lt;p&gt;¿Y qué pasa con los equipos?&lt;/p&gt;

&lt;p&gt;El techo de muchos prestadores de servicios proviene de tener una operación imposible de escalar.&lt;br&gt;
Porque si el día a día está desordenado, saturado, caótico… No hay espacio para construir talento de verdad.&lt;/p&gt;

&lt;p&gt;Y al escalar, no se puede permitir talento promedio.&lt;br&gt;
Se necesita gente que piense, que resuelva problemas reales, con experiencia relevante y &lt;em&gt;energía disponible&lt;/em&gt;.&lt;br&gt;
No basta una lista de certificados si detrás no hay tiempo, guía ni contexto para que ese conocimiento se transforme en valor real.&lt;/p&gt;

&lt;p&gt;Y cuando logran hacerlo (con esfuerzo, con entrega) muchas veces terminan yéndose.&lt;br&gt;
Porque sin una cultura que acompañe el desarrollo operativo, el talento no florece… se fuga.&lt;/p&gt;

&lt;p&gt;A veces me pregunto:&lt;br&gt;
&lt;strong&gt;¿Qué pasaría si en los procesos licitatorios o RFP también se solicitará el porcentaje de rotación del personal?&lt;/strong&gt;&lt;br&gt;
¿O es que eso no es una variable crítica para sostener operaciones tecnológicas de alto impacto?&lt;/p&gt;

&lt;h2&gt;
  
  
  ¿Y si lo hiciéramos diferente?.
&lt;/h2&gt;

&lt;p&gt;No se trata solo de tiempo.&lt;br&gt;
Se trata de foco, salud y claridad.&lt;/p&gt;

&lt;p&gt;Y de imaginar:&lt;br&gt;
¿Qué pasaría si todo eso que le ofrecemos a nuestros clientes… &lt;strong&gt;lo aplicáramos primero en nuestros equipos?&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Si usáramos el agilismo no solo como discurso comercial, sino como modelo operativo real.&lt;/li&gt;
&lt;li&gt;Si automatizáramos el caos interno antes de vender eficiencia externa.&lt;/li&gt;
&lt;li&gt;Si el aprendizaje fuese parte del flujo de trabajo, no un lujo fuera de horario.&lt;/li&gt;
&lt;li&gt;Si la cultura no se resumiera en frases de PowerPoint, sino en prácticas vividas.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;¿Qué pasaría si de verdad invirtiéramos en capacidades internas, con la misma urgencia con la que lanzamos propuestas a los clientes?&lt;/p&gt;

&lt;p&gt;Respuesta: &lt;strong&gt;Pasaría lo bueno, escalable y sostenible.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Equipos más enfocados, con mejor energía, con ideas frescas, con soluciones que nacen desde la experiencia… y no desde la fatiga.&lt;/p&gt;

&lt;p&gt;Y sí: Ahí sí podríamos honrar esas frases que tanto usamos:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;“Nos debemos a nuestros clientes.”&lt;/strong&gt;&lt;br&gt;
&lt;strong&gt;“Lo más importante son las personas.”&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Y ahora, ¿qué hacemos?
&lt;/h2&gt;

&lt;p&gt;No tengo todas las respuestas. Pero sí sé que esto hay que conversarlo.&lt;/p&gt;

&lt;p&gt;Porque si queremos que nuestros servicios escalen, primero tenemos que huir del caos y del estancamiento.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Lo insostenible no crece. Lo ordenado, sí.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;No se trata de atacar el trabajo remoto.&lt;br&gt;
Se trata de no seguir normalizando lo insostenible.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;¿Estás gestionando el talento… o solo apagando fuegos?&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>workplace</category>
      <category>trabajoremoto</category>
      <category>sinfiltro</category>
      <category>learning</category>
    </item>
  </channel>
</rss>
