<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Alfalfita ☁️]]></title><description><![CDATA[Software developer motivada y apasionada por la tecnología en la nube (AWS)]]></description><link>https://blog.alfalfita.cloud</link><generator>RSS for Node</generator><lastBuildDate>Wed, 29 Apr 2026 22:41:21 GMT</lastBuildDate><atom:link href="https://blog.alfalfita.cloud/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[Prerequisitos para habilitar MultiVPC sobre MSK]]></title><description><![CDATA[El objetivo del presente documento es dejar el clúster listo (a nivel de: auth, ACLs/policies, red y pruebas) antes de habilitar Multi-VPC, de modo que los clientes existentes consuman y produzcan sin TopicAuthorizationException ni errores de enrutam...]]></description><link>https://blog.alfalfita.cloud/prerequisitos-para-habilitar-multivpc-sobre-msk</link><guid isPermaLink="true">https://blog.alfalfita.cloud/prerequisitos-para-habilitar-multivpc-sobre-msk</guid><category><![CDATA[msk]]></category><dc:creator><![CDATA[Diana Alfaro]]></dc:creator><pubDate>Sat, 22 Nov 2025 05:00:00 GMT</pubDate><content:encoded><![CDATA[<p>El objetivo del presente documento es dejar el clúster listo (a nivel de: auth, ACLs/policies, red y pruebas) antes de habilitar Multi-VPC, de modo que los clientes existentes consuman y produzcan sin TopicAuthorizationException ni errores de enrutamiento.</p>
<blockquote>
<p>El <strong>esquema de autenticación</strong> por cliente en el MSK de las APP permite SCRAM (<strong>SASL/SCRAM</strong>), que tiene <strong>control por ACLs de Kafka</strong>. Y está configurado actualmente como:</p>
<pre><code class="lang-plaintext">allow.everyone.if.no.acl.found=true (permisivo);
</code></pre>
<p>Esta valor está seteado en parameter store de la cuenta Shared (msk-{env})</p>
<p>Se cambiará a <strong>false</strong> una vez que se tenga las ACLs completas.</p>
</blockquote>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1766160619819/8b6c3d03-b642-4e34-831a-7fe8918d576f.png" alt class="image--center mx-auto" /></p>
<p>Con SCRAM, el clúster tiene un usuario con privilegios para gestionar ACLs (que se encuentra almacenado en un secret)</p>
<hr />
<p>0 - Conectarse al clúster de MSK</p>
<hr />
<p>1- Permisos de metadatos del clúster</p>
<pre><code class="lang-plaintext">./kafka-acls.sh --bootstrap-server "$KAFKA_BROKERS_SCRAM" \
  --add --allow-principal User:&lt;user&gt; \
  --operation Describe \
  --operation Create \
  --operation Alter \
  --operation AlterConfigs \
  --operation DescribeConfigs \
  --cluster \
  --command-config client.properties
</code></pre>
<p><em>Reemplazar user con el usuario asociado al clúster.</em></p>
<hr />
<p>2- Dar permisos sobre tópicos que usará la app (prefijos o '*' )</p>
<pre><code class="lang-plaintext">./kafka-acls.sh --bootstrap-server "$KAFKA_BROKERS_SCRAM" \
  --add --allow-principal User:&lt;user&gt; \
  --operation Describe \
  --operation Read \
  --operation Alter \
  --operation Write \
  --operation DescribeConfigs \
  --topic "&lt;prefijo-o-*&gt;" \
  --resource-pattern-type literal \
  --command-config client.properties
</code></pre>
<p><em>Reemplazar user con el usuario asociado al clúster.</em></p>
<hr />
<p>3- Consumer groups (prefijo o '*' )</p>
<pre><code class="lang-plaintext">./kafka-acls.sh --bootstrap-server "$KAFKA_BROKERS_SCRAM" \
  --add --allow-principal User:&lt;user&gt; \
  --operation Read --operation Describe \
  --group "&lt;prefijo-o-*&gt;" --resource-pattern-type literal \
  --command-config client.properties
</code></pre>
<p><em>Reemplazar user con el usuario asociado al clúster.</em></p>
<hr />
<p>4- Dar permiso para crear tópicos por prefijo de topic:</p>
<pre><code class="lang-plaintext">./kafka-acls.sh ... --operation Create --topic &lt;prefijo&gt; --resource-pattern-type literal ...
</code></pre>
<p>No cambiar allow.everyone.if.no.acl.found=false hasta que estas ACLs estén aplicadas; de lo contrario, se puede bloquear.</p>
<hr />
<p>5 - Red y requisitos de Multi-VPC<br />- Misma Región<br />- Mismo número de subredes ↔ clúster y mismos AZ IDs (no confundir con nombres de AZ).<br />- Un VPC Endpoint (Interface) por AZ cliente.<br />- SG/NACL permitiendo 9096 (SASL/SCRAM).</p>
<hr />
<p>6- Pruebas “pre-Multi-VPC” (en la VPC del clúster)<br />- Listar/describe tópicos de destino con el usuario que usarán los clientes.<br />- Producir y consumir mensajes de prueba.</p>
<hr />
<p>7- Activar Multi-VPC<br />- <strong>Cambiar el valor en el parameter store asociado</strong></p>
<pre><code class="lang-plaintext">allow.everyone.if.no.acl.found=false(permisivo);
</code></pre>
<p>Y ejecutar el pipeline<br />- En caso de error: This server does not host this topic-partition, suele ser conectividad parcial hacia el líder; validar DNS/SG/NACL y usa client.dns.lookup=use_all_dns_ips.</p>
<hr />
<p>8 - Observabilidad y troubleshooting<br />- Revisar los logs del MSK (CloudWatch Logs): buscar Session(User:...), Denied, TopicAuthorizationException.<br />- Filtrar en CloudWatch Logs Insights – en los log groups de las lambdas involucradas: error|exception|Authorization|Throttl|ConditionalCheckFailed|ValidationException.<br />- Revisar el estado de Event Source Mappings (list-event-source-mappings): Comprobar State (Active) y LastProcessingResult.</p>
<hr />
<p>En caso los ACL no funcionen correctamente, seguir el siguiente paso para elminar y corregir los ACLs:</p>
<ul>
<li><p>Después de eliminar los archivos "users_jaas.conf" y "client.properties", así como hacer unset de la variable KAFKA_OPTS, ejecutar el siguiente comando y limpiar las ACLs:</p>
<pre><code class="lang-plaintext">  ./kafka-acls.sh --authorizer-properties zookeeper.connect=$ZKSTRING --remove --allow-principal User:msk-prod  --operation Describe --cluster
</code></pre>
</li>
<li><p>Una vez limpias, agregamos las ACLs necesarias para poder modificar permisos posteriormente:</p>
<pre><code class="lang-plaintext">  ./kafka-acls.sh --bootstrap-server $BROKERSSCRAM --add --allow-principal User:msk-prod --operation Describe --operation Create --operation Alter --cluster --command-config client.properties
</code></pre>
</li>
</ul>
<p><strong>Referencias:</strong><br /><a target="_blank" href="https://docs.aws.amazon.com/es_es/msk/latest/developerguide/msk-acls.html">https://docs.aws.amazon.com/es_es/msk/latest/developerguide/msk-acls.html</a></p>
]]></content:encoded></item><item><title><![CDATA[¿Cómo Crear una API Gateway REST Privada con Dominio Personalizado en AWS?]]></title><description><![CDATA[Cuando se desarrollan microservicios internos o APIs para sistemas confidenciales, es común que necesitemos exponer estas APIs solo dentro del entorno privado de AWS, evitando cualquier exposición pública. Para ello, AWS ofrece API Gateway con endpoi...]]></description><link>https://blog.alfalfita.cloud/como-crear-una-api-gateway-rest-privada-con-dominio-personalizado-en-aws</link><guid isPermaLink="true">https://blog.alfalfita.cloud/como-crear-una-api-gateway-rest-privada-con-dominio-personalizado-en-aws</guid><category><![CDATA[AWS]]></category><category><![CDATA[aws-apigateway]]></category><category><![CDATA[Custom Domain]]></category><category><![CDATA[Terraform]]></category><dc:creator><![CDATA[Diana Alfaro]]></dc:creator><pubDate>Thu, 03 Jul 2025 02:24:49 GMT</pubDate><content:encoded><![CDATA[<p>Cuando se desarrollan microservicios internos o APIs para sistemas confidenciales, es común que necesitemos exponer estas APIs solo dentro del entorno privado de AWS, evitando cualquier exposición pública. Para ello, AWS ofrece API Gateway con endpoint <code>PRIVATE</code> combinado con VPC Endpoint Interface.</p>
<p>En este artículo veremos como crear y configurar:</p>
<ul>
<li><p>API Gateway REST configurado como <code>PRIVATE</code></p>
</li>
<li><p>Un <strong>VPC Endpoint Interface</strong> para <code>execute-api</code></p>
</li>
<li><p>Un dominio privado personalizado (ej: <code>api.infra.local</code>)</p>
</li>
<li><p>Validación SSL con ACM</p>
</li>
<li><p>Alias en Route 53 hacia el VPC Endpoint</p>
</li>
</ul>
<hr />
<h2 id="heading-advertencias-y-problemas-resueltos">⚠️ Advertencias y Problemas Resueltos</h2>
<p>Durante la implementación nos enfrentamos a las siguientes restricciones y errores relacionados con las versiones de Terraform:</p>
<h3 id="heading-problema-error-404-al-usar-awsapigatewaybasepathmapping-con-dominios-privados">Problema: Error 404 al usar <code>aws_api_gateway_base_path_mapping</code> con dominios privados</h3>
<ul>
<li><strong>Mensaje:</strong></li>
</ul>
<pre><code class="lang-text">Error: creating API Gateway Base Path Mapping (operation error API Gateway: CreateBasePathMapping, https response error StatusCode: 404, RequestID: xxx, NotFoundException: Invalid domain name identifier specified)
</code></pre>
<ul>
<li><strong>Causa:</strong> En versiones anteriores a Terraform v5.88, el proveedor tenía un bug donde la combinación del campo <code>domain_name</code> junto con <code>domain_name_id</code> generaba una construcción incorrecta en la llamada interna a la API de AWS.</li>
</ul>
<p>Por ejemplo:</p>
<pre><code class="lang-bash">resource <span class="hljs-string">"aws_api_gateway_base_path_mapping"</span> <span class="hljs-string">"example"</span> {
  domain_name    = aws_api_gateway_domain_name.example.domain_name
  domain_name_id = aws_api_gateway_domain_name.example.id
  api_id         = aws_api_gateway_rest_api.example.id
  stage_name     = aws_api_gateway_stage.example.stage_name
  base_path      = <span class="hljs-string">""</span>
}
</code></pre>
<p>Generaba internamente algo como:</p>
<pre><code class="lang-bash">api.dev.mobiles.secure.alfalfita.click//api.dev.mobiles.secure.alfalfita.click/okmnxgsnua
</code></pre>
<p>Esta combinación con doble barra (<code>//</code>) es inválida y resultaba en el error <code>Invalid domain name identifier specified</code>.</p>
<ul>
<li><strong>Solución temporal:</strong> Usar un <code>null_resource</code> con <code>local-exec</code> que ejecute manualmente el CLI de AWS con el <code>domain-name-id</code> correcto.</li>
</ul>
<h3 id="heading-fix-oficial-en-terraform-v588">Fix oficial en Terraform v5.88</h3>
<p>Desde la versión <strong>Terraform v5.88</strong>, el proveedor de AWS para Terraform ya permite el uso adecuado de <code>domain_name_id</code> con dominios privados, sin necesidad de combinarlo con <code>domain_name</code>, y sin generar duplicaciones.</p>
<pre><code class="lang-bash">resource <span class="hljs-string">"aws_api_gateway_base_path_mapping"</span> <span class="hljs-string">"private_api_mapping"</span> {
  domain_name_id = aws_api_gateway_domain_name.private_custom_domain.domain_name_id
  api_id         = aws_api_gateway_rest_api.private.id
  stage_name     = aws_api_gateway_stage.stage.stage_name
  base_path      = <span class="hljs-string">""</span>
}
</code></pre>
<p><strong><mark>👀 Recomendación:</mark></strong> <mark> Asegúrate de estar utilizando Terraform v5.88 o superior para evitar este problema.</mark></p>
<hr />
<h2 id="heading-paso-1-crear-el-dominio-personalizado-privado">Paso 1: Crear el Dominio Personalizado Privado</h2>
<pre><code class="lang-bash">resource <span class="hljs-string">"aws_api_gateway_domain_name"</span> <span class="hljs-string">"private_custom_domain"</span> {
  domain_name     = <span class="hljs-string">"api.infra.local"</span>
  certificate_arn = aws_acm_certificate.cert.arn
  security_policy = <span class="hljs-string">"TLS_1_2"</span>

  endpoint_configuration {
    types = [<span class="hljs-string">"PRIVATE"</span>]
  }
}
</code></pre>
<p>Para la validación de certificado se recomienda usar <code>DNS</code> con una zona Route 53 pública o privada según el caso.</p>
<hr />
<h2 id="heading-paso-2-crear-el-vpc-endpoint-interface-para-api-gateway">Paso 2: Crear el VPC Endpoint Interface para API Gateway</h2>
<pre><code class="lang-bash">resource <span class="hljs-string">"aws_vpc_endpoint"</span> <span class="hljs-string">"execute_api"</span> {
  vpc_id            = var.vpc_id
  service_name      = <span class="hljs-string">"com.amazonaws.<span class="hljs-variable">${var.region}</span>.execute-api"</span>
  vpc_endpoint_type = <span class="hljs-string">"Interface"</span>
  subnet_ids        = var.subnet_ids
  security_group_ids = var.sg_ids
  private_dns_enabled = <span class="hljs-literal">false</span>
}
</code></pre>
<p>Este endpoint permite a las instancias en la VPC comunicarse con la API Gateway privada.</p>
<hr />
<h2 id="heading-paso-3-asociar-el-custom-domain-al-vpc-endpoint">Paso 3: Asociar el Custom Domain al VPC Endpoint</h2>
<pre><code class="lang-bash">resource <span class="hljs-string">"aws_api_gateway_domain_name_access_association"</span> <span class="hljs-string">"assoc"</span> {
  access_association_source      = aws_vpc_endpoint.execute_api.id
  access_association_source_type = <span class="hljs-string">"VPCE"</span>
  domain_name_arn                = aws_api_gateway_domain_name.private_custom_domain.arn
}
</code></pre>
<hr />
<h2 id="heading-paso-4-crear-la-api-gateway-rest-privada">Paso 4: Crear la API Gateway REST Privada</h2>
<pre><code class="lang-bash">resource <span class="hljs-string">"aws_api_gateway_rest_api"</span> <span class="hljs-string">"private_api"</span> {
  name = <span class="hljs-string">"mi-api-privada"</span>

  endpoint_configuration {
    types            = [<span class="hljs-string">"PRIVATE"</span>]
    vpc_endpoint_ids = [aws_vpc_endpoint.execute_api.id]
  }
}
</code></pre>
<hr />
<h2 id="heading-paso-5-crear-los-recursos-y-metodos">Paso 5: Crear los Recursos y Métodos</h2>
<pre><code class="lang-bash">resource <span class="hljs-string">"aws_api_gateway_resource"</span> <span class="hljs-string">"validar"</span> {
  rest_api_id = aws_api_gateway_rest_api.private_api.id
  parent_id   = aws_api_gateway_rest_api.private_api.root_resource_id
  path_part   = <span class="hljs-string">"validar"</span>
}

resource <span class="hljs-string">"aws_api_gateway_method"</span> <span class="hljs-string">"get"</span> {
  rest_api_id   = aws_api_gateway_rest_api.private_api.id
  resource_id   = aws_api_gateway_resource.validar.id
  http_method   = <span class="hljs-string">"GET"</span>
  authorization = <span class="hljs-string">"NONE"</span>
}
</code></pre>
<hr />
<h2 id="heading-paso-6-configurar-integracion-y-deployment">Paso 6: Configurar Integración y Deployment</h2>
<pre><code class="lang-bash">resource <span class="hljs-string">"aws_api_gateway_integration"</span> <span class="hljs-string">"mock"</span> {
  rest_api_id = aws_api_gateway_rest_api.private_api.id
  resource_id = aws_api_gateway_resource.validar.id
  http_method = aws_api_gateway_method.get.http_method
  <span class="hljs-built_in">type</span>        = <span class="hljs-string">"MOCK"</span>

  request_templates = {
    <span class="hljs-string">"application/json"</span> = <span class="hljs-string">"{\"statusCode\": 200}"</span>
  }
}

resource <span class="hljs-string">"aws_api_gateway_deployment"</span> <span class="hljs-string">"deploy"</span> {
  rest_api_id = aws_api_gateway_rest_api.private_api.id
  triggers = {
    redeploy = timestamp()
  }
  lifecycle {
    create_before_destroy = <span class="hljs-literal">true</span>
  }
}
</code></pre>
<hr />
<h2 id="heading-paso-7-mapear-la-api-al-dominio-privado">Paso 7: Mapear la API al Dominio Privado</h2>
<p><mark>Desde </mark> <strong><mark>Terraform v5.88+</mark></strong><mark>, se soporta el mapeo de base path en dominios privados:</mark></p>
<pre><code class="lang-bash">resource <span class="hljs-string">"aws_api_gateway_base_path_mapping"</span> <span class="hljs-string">"map"</span> {
  domain_name_id = aws_api_gateway_domain_name.private_custom_domain.domain_name_id
  api_id         = aws_api_gateway_rest_api.private_api.id
  stage_name     = aws_api_gateway_stage.stage.stage_name
  base_path      = <span class="hljs-string">""</span>
}
</code></pre>
<hr />
<h2 id="heading-paso-8-aplicar-politicas-de-seguridad">Paso 8: Aplicar Políticas de Seguridad</h2>
<p>Restringe acceso a la API por VPC o por VPC Endpoint:</p>
<pre><code class="lang-bash">data <span class="hljs-string">"aws_iam_policy_document"</span> <span class="hljs-string">"private_policy"</span> {
  statement {
    effect = <span class="hljs-string">"Deny"</span>
    actions = [<span class="hljs-string">"execute-api:Invoke"</span>]
    resources = [<span class="hljs-string">"<span class="hljs-variable">${aws_api_gateway_rest_api.private_api.execution_arn}</span>/*/*"</span>]

    principals {
      <span class="hljs-built_in">type</span>        = <span class="hljs-string">"AWS"</span>
      identifiers = [<span class="hljs-string">"*"</span>]
    }

    condition {
      <span class="hljs-built_in">test</span>     = <span class="hljs-string">"StringNotEquals"</span>
      variable = <span class="hljs-string">"aws:SourceVpce"</span>
      values   = [aws_vpc_endpoint.execute_api.id]
    }
  }

  statement {
    effect = <span class="hljs-string">"Allow"</span>
    actions = [<span class="hljs-string">"execute-api:Invoke"</span>]
    resources = [<span class="hljs-string">"<span class="hljs-variable">${aws_api_gateway_rest_api.private_api.execution_arn}</span>/*/*"</span>]
    principals {
      <span class="hljs-built_in">type</span>        = <span class="hljs-string">"AWS"</span>
      identifiers = [<span class="hljs-string">"*"</span>]
    }
  }
}
</code></pre>
<hr />
<h2 id="heading-paso-9-alias-dns-en-route-53">Paso 9: Alias DNS en Route 53</h2>
<pre><code class="lang-bash">resource <span class="hljs-string">"aws_route53_record"</span> <span class="hljs-string">"custom_domain_alias"</span> {
  zone_id = aws_route53_zone.private.id
  name    = <span class="hljs-string">"api.infra.local"</span>
  <span class="hljs-built_in">type</span>    = <span class="hljs-string">"A"</span>

  <span class="hljs-built_in">alias</span> {
    name                   = aws_vpc_endpoint.execute_api.dns_entry[0].dns_name
    zone_id                = aws_vpc_endpoint.execute_api.dns_entry[0].hosted_zone_id
    evaluate_target_health = <span class="hljs-literal">false</span>
  }
}
</code></pre>
<hr />
<h2 id="heading-conclusion">Conclusión</h2>
<p>Con esta configuración, logramos una API REST totalmente privada, expuesta con HTTPS y dominio personalizado, con seguridad a nivel de red (VPC Endpoint) e IAM. Una solución ideal para integraciones internas seguras, cumplimiento de normativas y entornos confidenciales.</p>
<p>Para consumir tu API desde la misma VPC, puedes ejecutar:</p>
<pre><code class="lang-bash">curl -k https://api.infra.local/prod/validar
</code></pre>
]]></content:encoded></item><item><title><![CDATA[Crear un VPC Environment en AWS CloudShell]]></title><description><![CDATA[Crear un VPC Environment en AWS CloudShell, que permita realizar pruebas de conectividad hacia otros recursos dentro de una VPC especifica
1- Ingresamos a AWS CloudShell y hacemos click en +

2- Completar los datos y crear

3 - Luego de eso aparece e...]]></description><link>https://blog.alfalfita.cloud/crear-un-vpc-environment-en-aws-cloudshell</link><guid isPermaLink="true">https://blog.alfalfita.cloud/crear-un-vpc-environment-en-aws-cloudshell</guid><category><![CDATA[AWS CloudShell]]></category><dc:creator><![CDATA[Diana Alfaro]]></dc:creator><pubDate>Sun, 15 Jun 2025 05:00:00 GMT</pubDate><content:encoded><![CDATA[<p>Crear un VPC Environment en AWS CloudShell, que permita realizar pruebas de conectividad hacia otros recursos dentro de una VPC especifica</p>
<p>1- Ingresamos a AWS CloudShell y hacemos click en +</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1766160293869/605e7a3b-9df0-4a1f-95b7-ba4ab058eba0.png" alt class="image--center mx-auto" /></p>
<p>2- Completar los datos y crear</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1766160304826/29e214b7-411e-48bb-a1c3-2dea8bc2295a.png" alt class="image--center mx-auto" /></p>
<p>3 - Luego de eso aparece el entorno VPC creado</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1766160318086/3747a891-3a26-4444-9c1d-e3d85680c3c7.png" alt class="image--center mx-auto" /></p>
]]></content:encoded></item><item><title><![CDATA[Conexión a MSK desde AWS CloudShell]]></title><description><![CDATA[Documentación paso a paso para conectarte a un clúster de Amazon MSK (con autenticación SCRAM-SHA-512) desde AWS CloudShell, utilizando la versión Kafka 3.6.0
Requisitos

Acceso a AWS CloudShell en la misma región del clúster MSK (us-east-1).

Nombre...]]></description><link>https://blog.alfalfita.cloud/conexion-a-msk-desde-aws-cloudshell</link><guid isPermaLink="true">https://blog.alfalfita.cloud/conexion-a-msk-desde-aws-cloudshell</guid><category><![CDATA[msk]]></category><dc:creator><![CDATA[Diana Alfaro]]></dc:creator><pubDate>Sun, 15 Jun 2025 05:00:00 GMT</pubDate><content:encoded><![CDATA[<p>Documentación paso a paso para conectarte a un clúster de <strong>Amazon MSK (con autenticación SCRAM-SHA-512)</strong> desde <strong>AWS CloudShell</strong>, utilizando la versión <strong>Kafka 3.6.0</strong></p>
<h3 id="heading-requisitos"><strong>Requisitos</strong></h3>
<ul>
<li><p>Acceso a AWS CloudShell en la misma <strong>región del clúster MSK</strong> (us-east-1).</p>
</li>
<li><p>Nombre de usuario y contraseña SCRAM habilitados en el clúster (se encuentran como secret en la misma cuenta y región del clúster).</p>
</li>
<li><p>DNS de brokers disponibles.</p>
</li>
<li><p>El clúster debe estar accesible desde el entorno VPC de CloudShell (ver como crear un VPC Environment en AWS CloudShell)</p>
</li>
</ul>
<hr />
<h3 id="heading-1-descargar-kafka"><strong>1. Descargar Kafka</strong></h3>
<pre><code class="lang-plaintext">export KAFKA_VERSION=3.6.0

wget https://archive.apache.org/dist/kafka/$KAFKA_VERSION/kafka_2.13-$KAFKA_VERSION.tgz

tar -xzf kafka_2.13-$KAFKA_VERSION.tgz

cd kafka_2.13-$KAFKA_VERSION/bin
</code></pre>
<hr />
<h3 id="heading-2-copiar-truststore-por-defecto-para-ssl"><strong>2. Copiar truststore por defecto (para SSL)</strong></h3>
<pre><code class="lang-plaintext">cp /usr/lib/jvm/jre/lib/security/cacerts kafka.client.truststore.jks
</code></pre>
<hr />
<h3 id="heading-3-definir-brokers-msk-scram"><strong>3. Definir brokers MSK (SCRAM)</strong></h3>
<pre><code class="lang-plaintext">export KAFKA_BROKERS_SCRAM="b-2.dfhsdf.u4jjft.c2.kafka.us-east-1.amazonaws.com:9096,b-1.dfhsdf.u4jjft.c2.kafka.us-east-1.amazonaws.com:9096"
</code></pre>
<hr />
<h3 id="heading-4-crear-archivo-clientproperties"><strong>4. Crear archivo client.properties</strong></h3>
<pre><code class="lang-plaintext">cat &lt;&lt;EOF &gt; client.properties
security.protocol=SASL_SSL
sasl.mechanism=SCRAM-SHA-512
ssl.truststore.location=$(pwd)/kafka.client.truststore.jks
EOF
</code></pre>
<hr />
<h3 id="heading-5-crear-archivo-usersjaasconf"><strong>5. Crear archivo users_jaas.conf</strong></h3>
<pre><code class="lang-plaintext">cat &lt;&lt;EOF &gt; users_jaas.conf
KafkaClient {
   org.apache.kafka.common.security.scram.ScramLoginModule required
   username="msk-user"
   password="msk-pass";
};
EOF
</code></pre>
<hr />
<h3 id="heading-6-exportar-variable-de-entorno-kafkaopts"><strong>6. Exportar variable de entorno KAFKA_OPTS</strong></h3>
<p>Esta variable asegura que el cliente Kafka use la autenticación SASL/SCRAM configurada.</p>
<pre><code class="lang-plaintext">export KAFKA_OPTS="-Djava.security.auth.login.config=$(pwd)/users_jaas.conf"
</code></pre>
<hr />
<h3 id="heading-7-listar-topicos-del-cluster"><strong>7. Listar tópicos del clúster</strong></h3>
<pre><code class="lang-plaintext">./kafka-topics.sh --bootstrap-server $KAFKA_BROKERS_SCRAM --list --command-config client.properties
</code></pre>
<hr />
<h2 id="heading-validacion-y-troubleshooting"><strong>Validación y Troubleshooting</strong></h2>
<ul>
<li><p>Si ves errores de conexión o certificados, verifica que:</p>
<ul>
<li><p>El VPC Endpoint está configurado (si el MSK es privado).</p>
</li>
<li><p>Estás usando el truststore correcto (cacerts).</p>
</li>
<li><p>El usuario y contraseña SCRAM son válidos.</p>
</li>
<li><p>Tienes conectividad desde CloudShell hacia los brokers.</p>
</li>
</ul>
</li>
</ul>
]]></content:encoded></item><item><title><![CDATA[Identificando ejecuciones concurrentes de lambdas sobre una cuenta con Amazon CloudWatch]]></title><description><![CDATA[Las ejecuciones concurrentes es el número de ejecuciones simultáneas activas de una función Lambda en un momento dado.

Fuente: Concurrencia en lambda. https://docs.aws.amazon.com/lambda/latest/dg/lambda-concurrency.html
Si la concurrencia de una fun...]]></description><link>https://blog.alfalfita.cloud/identificando-ejecuciones-concurrentes-de-lambdas-sobre-una-cuenta-con-amazon-cloudwatch</link><guid isPermaLink="true">https://blog.alfalfita.cloud/identificando-ejecuciones-concurrentes-de-lambdas-sobre-una-cuenta-con-amazon-cloudwatch</guid><category><![CDATA[lambda]]></category><category><![CDATA[monitoring]]></category><category><![CDATA[Amazon Cloudwatch]]></category><dc:creator><![CDATA[Diana Alfaro]]></dc:creator><pubDate>Sat, 18 Jan 2025 17:28:00 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1737221463129/48af7822-1484-4f2e-b5c6-15550f998e38.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Las ejecuciones concurrentes es el número de ejecuciones simultáneas activas de una función Lambda en un momento dado.</p>
<p><img src="https://docs.aws.amazon.com/images/lambda/latest/dg/images/concurrency-4-animation.gif" alt class="image--center mx-auto" /></p>
<p><strong>Fuente:</strong> Concurrencia en lambda. <a target="_blank" href="https://docs.aws.amazon.com/lambda/latest/dg/lambda-concurrency.html">https://docs.aws.amazon.com/lambda/latest/dg/lambda-concurrency.html</a></p>
<p>Si la concurrencia de una función alcanza el límite establecido por AWS (por defecto el límite en cada cuenta es de 1000), se limitarán las invocaciones adicionales a ese límite lo que generará solicitudes fallidas. Este límite puede incrementarse, solicitando su incremento a través de Service Quota.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1737215466768/729fec53-c294-4e1b-973e-ec74f29d2d19.png" alt class="image--center mx-auto" /></p>
<p><strong><em>Figura 1:</em></strong> <em>Service Quota. Fuente AWS Console</em></p>
<p>La métrica en Amazon CloudWatch que contiene este dato a revisar se llama: <strong>ConcurrentExecutions</strong> que se calcula al multiplicar el promedio de solicitudes por segundo por la duración promedio de las solicitudes en segundos.</p>
<pre><code class="lang-bash">Concurrencia = PromSolicitudesxSeg X DuracionPromSolicitudesxSeg
</code></pre>
<p>Eso quiere decir que si tenemos una función que recibe 100 solicitudes por segundo y cada solicitud tarda alrededor de 300 milisegundos en completarse, la concurrencia sería de 30</p>
<pre><code class="lang-bash">Concurrencia = 100 X 0,3
</code></pre>
<p>Con Amazon CloudWatch podemos:</p>
<ul>
<li><p>Seleccionar la métrica <strong>ConcurrentExecutions</strong> para ver el número de ejecuciones concurrentes activas en la cuenta o en funciones específicas.</p>
<p>  <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1737219096115/fc04b361-c3fe-4e11-9a5c-d41a69eef8d6.png" alt class="image--center mx-auto" /></p>
<p>  <strong>Figura 2:</strong> Métrica ConcurrentExecutions. Fuente AWS Console</p>
</li>
<li><p>Crear un gráfico que muestre la cantidad de cuántas ejecuciones concurrentes que se han ejecutado en un intervalo de tiempo dado.</p>
<p>  <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1737217079752/3430da74-689c-406c-a73e-20b38b7ed8f0.png" alt class="image--center mx-auto" /></p>
</li>
</ul>
<p><strong>Figura 3:</strong> Gráfico de ConcurrentExecutions. Fuente AWS Console</p>
<h2 id="heading-usando-amazon-cloudwatch-explorer">Usando Amazon CloudWatch Explorer</h2>
<p>Con esta opción de Amazon Cloudwatch podremos rápidamente consultar varias métricas en simultáneo para un recurso en particular</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1737218077674/1ef94c82-d798-492a-b639-2ddde6943cb1.png" alt class="image--center mx-auto" /></p>
<p><strong>Figura 4:</strong> Amazon CloudWatch Explorer. Fuente AWS Console</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1737218618262/92a0a2e8-8c5b-409b-81a6-d6a13977d8c4.png" alt class="image--center mx-auto" /></p>
<p><strong>Figura 5:</strong> Servicios disponibles en Amazon CloudWatch Explorer. Fuente AWS Console</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1737218663878/450a38a2-b12e-43e9-ba0f-e1733e6e9fb3.png" alt class="image--center mx-auto" /></p>
<p><strong>Figura 6:</strong> Métricas para lambda. Fuente AWS Console</p>
<p>En este caso hemos seleccionado el servicio de Lambda con algunas métricas claves (invocations, errors, throttles, concurrentExecutions). Ajustando el rango de fechas a consultar podemos ver rápidamente el resultado estás métricas segregadas para cada lambda de la cuenta.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1737218874357/acfea423-24fb-4265-803c-63da126f86e1.png" alt class="image--center mx-auto" /></p>
<p><strong>Figura 6:</strong> Resultado de métricas para lambda segregadas por lambda. Fuente AWS Console</p>
<p>En el caso de los resultados de <strong>ConcurrentExecutions sobre todas las lambdas de una cuenta</strong> para un periodo dado observamos picos, <mark>que alcanzan el límite actual de la cuenta</mark>, mientras que <mark>otros tambien tienen picos a observar.</mark></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1737220039505/eaa859f9-162c-488e-9d48-d4221c4477cd.png" alt class="image--center mx-auto" /></p>
<p><strong>Figura 7:</strong> Detalle de la métrica ConcurrentExecutions segregada por lambda. Fuente AWS Console</p>
<p>Al identificar que lambdas son las que están consumiendo la concurrencia de la cuenta, podemos tomar acciones para evitar que vuelva a suceder como:</p>
<ul>
<li><p>Aplicar un <strong>monitoreo activo</strong> con Amazon CloudWatch</p>
</li>
<li><p>Establecer <strong>alertas</strong> que notifiquen <strong>cuando se acerque al límite de concurrencia.​</strong></p>
</li>
<li><p><strong>Cada Lambda debe ser aprovisionada en la cuenta con una alarma que monitoree la métrica</strong> ConcurrentExecutions.</p>
</li>
<li><p>Cuando la alarma se active, se puede <strong>configurar una acción</strong> para que dispare otra Lambda <strong>que ajuste el valor de concurrencia reservada de la Lambda</strong> original.​</p>
</li>
<li><p><strong>Establecer concurrencia reservada</strong> sólo para algunas funciones. lambda​</p>
</li>
<li><p><strong>Desacoplar cargas de trabajo con SQS o SNS</strong>​</p>
</li>
<li><p>Solicitar <strong>aumento de cuota</strong> en el límite de concurrencia (límite actual 1000)</p>
</li>
</ul>
]]></content:encoded></item><item><title><![CDATA[From Waste to Efficiency: Enfoques Prácticos para la Gestión de Costos en AWS]]></title><description><![CDATA[El pasado octubre tuve el honor de participar como speaker en el AWS Community Day Guatemala con esta charla que lleva como título este post, donde compartí algunas sugerencias y acciones a tomar relacionadas a FinOps.
La charla inició con algunas pr...]]></description><link>https://blog.alfalfita.cloud/from-waste-to-efficiency-enfoques-practicos-para-la-gestion-de-costos-en-aws</link><guid isPermaLink="true">https://blog.alfalfita.cloud/from-waste-to-efficiency-enfoques-practicos-para-la-gestion-de-costos-en-aws</guid><category><![CDATA[AWS]]></category><category><![CDATA[cost-optimisation]]></category><category><![CDATA[finops]]></category><dc:creator><![CDATA[Diana Alfaro]]></dc:creator><pubDate>Sat, 04 Jan 2025 08:22:34 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1736995162893/f4605b19-7978-4067-8425-5b1b2567fde6.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>El pasado octubre tuve el honor de participar como speaker en el AWS Community Day Guatemala con esta charla que lleva como título este post, donde compartí algunas sugerencias y acciones a tomar relacionadas a FinOps.</p>
<p>La charla inició con algunas preguntas como:</p>
<ul>
<li><p><em>¿Por qué es tan alta mi factura de AWS? Pensé que debería gastar menos en la nube</em></p>
</li>
<li><p><em>¿Cómo puedo reducir los costos de AWS para los entornos de desarrollo y control de calidad?</em></p>
</li>
<li><p><em>¿Qué opciones tengo para bajar mis costos en AWS?</em></p>
</li>
</ul>
<p>Y una mención al Recap of Werner Vogels Keynote en el re:Invent 2023</p>
<blockquote>
<p><strong>“Sistemas no observados llevan a costos desconocidos”</strong></p>
<p>Wegner Vegels. CTO y vicepresidente de <a target="_blank" href="http://Amazon.com">Amazon.com</a></p>
</blockquote>
<p>Hablamos sobre cómo WeTransfer logró <strong>reducir en un 78% el impacto medioambiental</strong> mediante la <strong>optimización del consumo de recursos</strong> del servidor en 2022.</p>
<h2 id="heading-despilfarro-en-la-nube"><strong>Despilfarro en la nube</strong></h2>
<p>Muchas veces dentro de nuestra organización, tenemos falencias que conllevan a altos costos o costos ocultos que por falta de visibilidad no nos percatamos y pagamos mes a mes. Algunos ejemplos de este despilfarro se muestran a continuación:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1735978663368/1e76d060-7fff-41cf-9ba0-54a067ede0d5.png" alt class="image--center mx-auto" /></p>
<h2 id="heading-causas-comunes-del-despilfarro-en-la-nube"><strong>Causas comunes del despilfarro en la nube</strong></h2>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1735978687148/7f27ecce-d350-44c3-b802-9b1a834753d4.png" alt class="image--center mx-auto" /></p>
<p>Para abordar estos problemas, podemos ejecutar algunas acciones para automatizar la eficiencia de costos en la nube, como:</p>
<ul>
<li><p><strong>Infraestructura como código (IaC):</strong> al aprovisionar recursos en la nube por IaC podemos rápidamente eliminarlos cuando ya no los usemos sin necesidad de hacer una eliminación manual, con esto evitamos que queden recursos huérfanos o recursos sin utilizar.</p>
</li>
<li><p><strong>El apagado de recursos:</strong> lo podemos aplicar en ambientes bajos como DEV, QA y Stagging. Con el fin de minimizar costos apagando los recursos durante las noches y fines de semana y activandolos en horario laboral.</p>
</li>
<li><p><strong>Integración con FinOps:</strong> FinOps es una disciplina que <strong>ayuda</strong> a las organizaciones <strong>a gestionar sus finanzas en la nube</strong>, <strong>mediante</strong> <strong>buenas prácticas</strong> <strong>y</strong> c<strong>olaboración entre equipos</strong> de ingeniería, finanzas y negocios</p>
</li>
</ul>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1735978718675/b15aed2b-21f0-4f2e-bd92-0c92c570f9c0.png" alt class="image--center mx-auto" /></p>
<h2 id="heading-beneficios-de-finops"><strong>Beneficios de FinOps</strong></h2>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1735978763461/fb7355e9-2ef2-46b8-abc7-a623033f5238.png" alt class="image--center mx-auto" /></p>
<h2 id="heading-finops-framework-en-aws"><strong>FinOps - Framework en AWS</strong></h2>
<p>Dentro del framework podemos encontrar ejecutar algunas acciones para cada fase:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1735978813697/6382cfc8-1e3d-4fd7-9980-f073507490cd.png" alt class="image--center mx-auto" /></p>
<h2 id="heading-principios-de-la-optimizacion-de-costos"><strong>Principios de la Optimización de Costos</strong></h2>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1735978833321/c4118f8f-2d1c-41e1-95bb-1429f3e5a60f.png" alt class="image--center mx-auto" /></p>
<p>Además de las acciones antes mencionadas, la optimización de costos se basa en estos principios:</p>
<ul>
<li><p><strong>Stop</strong>: <strong>detén</strong> recursos o servicios que ya no son necesarios o que están en desuso</p>
</li>
<li><p><strong>Resizing: ajusta el tamaño</strong> de los recursos (como máquinas virtuales, bases de datos, etc.) según la necesidad real</p>
</li>
<li><p><strong>Shift</strong>: <strong>mueve</strong> cargas de trabajo o recursos a una infraestructura más eficiente o rentable</p>
</li>
<li><p><strong>Reduce</strong>: <strong>elimina</strong> recursos infrautilizados o <strong>reduce</strong> el uso de servicios costosos</p>
</li>
</ul>
<h2 id="heading-herramientas-nativas-de-aws-para-la-gestion-de-costos"><strong>Herramientas Nativas de AWS para la Gestión de Costos</strong></h2>
<p>Por otro lado AWS, nos proporciona un conjunto de servicios y herramientas que nos pueden ayudar con la gestión de costos.</p>
<p>Algunas de ellas son:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1735978858757/1dc0e52f-a563-40ee-bbd0-cfe0dbe5fc34.png" alt class="image--center mx-auto" /></p>
<h2 id="heading-siguientes-pasos"><strong>Siguientes pasos</strong></h2>
<ul>
<li><p>Define, acuerda y aplica el etiquetado de asignación de costos</p>
</li>
<li><p>Define las métricas, establece objetivos y revisa</p>
</li>
<li><p>Permite que los equipos diseñen teniendo en cuenta los costos</p>
</li>
<li><p>Asigna responsabilidad en la optimización</p>
</li>
</ul>
<h2 id="heading-enlaces-de-interes"><strong>Enlaces de interés</strong></h2>
<p><a target="_blank" href="https://aws.amazon.com/es/blogs/aws-cloud-financial-management/">https://aws.amazon.com/es/blogs/aws-cloud-financial-management/</a></p>
<p><a target="_blank" href="https://www.finops.org/introduction/what-is-finops/">https://www.finops.org/introduction/what-is-finops/</a></p>
<p><a target="_blank" href="https://aws-experience.com/emea/smb/cost-optimization">https://aws-experience.com/emea/smb/cost-optimization</a></p>
]]></content:encoded></item><item><title><![CDATA[Automatizando la creación de un cluster de EKS con CloudFormation]]></title><description><![CDATA[En un entorno de nube, donde los recursos se pueden escalar dinámicamente y las necesidades cambian rápidamente, DevOps ofrece la flexibilidad necesaria para integrar el desarrollo y las operaciones en un flujo continuo. La automatización de tareas r...]]></description><link>https://blog.alfalfita.cloud/automatizando-la-creacion-de-un-cluster-de-eks-con-cloudformation</link><guid isPermaLink="true">https://blog.alfalfita.cloud/automatizando-la-creacion-de-un-cluster-de-eks-con-cloudformation</guid><category><![CDATA[AWS]]></category><category><![CDATA[EKS]]></category><category><![CDATA[Terraform]]></category><dc:creator><![CDATA[Diana Alfaro]]></dc:creator><pubDate>Mon, 30 Dec 2024 05:00:00 GMT</pubDate><content:encoded><![CDATA[<p>En un entorno de nube, donde los recursos se pueden escalar dinámicamente y las necesidades cambian rápidamente, DevOps ofrece la flexibilidad necesaria para integrar el desarrollo y las operaciones en un flujo continuo. La automatización de tareas rutinarias como la implementación y el monitoreo minimiza los errores humanos y acelera el tiempo de entrega, lo que es crucial en mercados altamente competitivo. Para automatizar el proceso, se ha realizado un flujo de trabajo de CI/CD que se acciona desde un push al repositorio hasta el despliegue de un clúster Kubernetes .</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1736997459647/bb5e7789-94da-4f46-9e05-a07397ab8ce1.png" alt class="image--center mx-auto" /></p>
<p><strong>Figura 1:</strong> <em>Conexión entre componentes.</em> Fuente: Elaboración propia</p>
<p>En la imagen anterior se muestra la conexión entre los diferentes componentes. El proceso se detalla a continuación:</p>
<ul>
<li><ul>
<li><p>Los desarrolladores suben su código a GitHub.</p>
<ul>
<li><p>Con GithubActions orquesta el proceso de compilación y pruebas.</p>
</li>
<li><p>CloudFormation crea y configura los recursos, como la instancia EC2 desde la que se creará mediante un script el clúster de Kubernetes en EKS.</p>
</li>
<li><p>EKS despliega aplicaciones utilizando las imágenes Docker almacenadas en ECR.</p>
</li>
</ul>
</li>
</ul>
</li>
</ul>
<p>Las herramientas seleccionadas son:</p>
<ul>
<li><ul>
<li><p>Uso de GitHub como repositorio principal.</p>
<ul>
<li><p>CloudFormation para gestionar la infraestructura.</p>
</li>
<li><p>EKS como plataforma de ejecución para contenedores.</p>
</li>
<li><p>S3, KMS y Secrets Manager para almacenamiento y seguridad.</p>
</li>
</ul>
</li>
</ul>
</li>
</ul>
<h2 id="heading-configuracion-de-un-pipeline-de-cicd"><strong>Configuración de un pipeline de CI/CD</strong></h2>
<p>Se ha definido un pipeline de CI/CD (Integración Continua y Despliegue Continuo) como secuencia automatizada de pasos para desarrollar, probar, y desplegar infraestructura en AWS de manera eficiente y controlada. El yaml que se ha definido para el pipeline se encuentra en el repositorio</p>
<p><a target="_blank" href="https://github.com/dicaalba/eks-cluster/blob/main/.github/workflows/github-actions.yml">https://github.com/dicaalba/eks-cluster/blob/main/.github/workflows/github-actions.yml</a></p>
<p>En este escenario, se está utilizando GitHub Actions y AWS CloudFormation:</p>
<ol>
<li>Configuración de Credenciales y Parámetros:</li>
</ol>
<ul>
<li><p>Se configuran las credenciales de AWS (con un rol IAM) para que GitHub Actions pueda interactuar con la cuenta de AWS.</p>
</li>
<li><p>Se definen variables globales como AWS_REGION y STACK_NAME que se usan en todo el pipeline para definir la configuración de infraestructura.</p>
</li>
</ul>
<ol start="2">
<li>Despliegue de Infraestructura con CloudFormation:</li>
</ol>
<ul>
<li><p>Se emplea un archivo CloudFormation (YAML) que describe la IaC.</p>
</li>
<li><p>El pipeline verifica si ya existe el stack y lo crea/actualiza según sea necesario.</p>
</li>
</ul>
<ol start="3">
<li>Conexión con Instancia EC2:</li>
</ol>
<ul>
<li>Una vez creada la infraestructura, se conecta a la instancia EC2 mediante SSH y se configura el entorno para que esté listo para ejecutar Kubernetes.</li>
</ul>
<ol start="4">
<li>Descarga del Kubeconfig:</li>
</ol>
<ul>
<li>El pipeline extrae el archivo kubeconfig de la instancia EC2 para interactuar con el clúster Kubernetes localmente.</li>
</ul>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1736997584203/1c5da929-eea8-442f-a0c9-935ed8b808e9.png" alt class="image--center mx-auto" /></p>
<p><strong>Figura 2:</strong> <em>Ejecución de pipeline con github actions.</em> Fuente: Github Actions</p>
<h2 id="heading-implementacion-de-cluster-en-eks"><strong>Implementación de clúster en EKS</strong></h2>
<p>Se ha definido un script que automatiza la creación y configuración de un clúster de Kubernetes en Amazon EKS <a target="_blank" href="https://github.com/dicaalba/eks-cluster/blob/main/ec2_user_data.sh">(ver repositorio de GitHub)</a>, con todas las herramientas necesarias instaladas y configuradas para su administración y uso, eliminando la necesidad de intervenciones manuales.</p>
<p>Instala herramientas como Docker, kubectl, eksctl, AWS CLI, aws-iam-authenticator y Helm. </p>
<p>A través del script, se emplea eksctl para crear el clúster EKS, definiendo además el tipo de nodos y la cantidad de nodos. </p>
<p>De esta forma podemos implementar un pipeline CI/CD usando GitHub Actions y AWS CloudFormation para automatizar el aprovisionamiento y la configuración de una infraestructura reproducible y escalable.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1736997842885/8b23945e-aca9-403a-8eae-2f3817f4f2fd.png" alt class="image--center mx-auto" /></p>
<p><strong>Figura 3:</strong> <em>Clúster de EKS.</em> Fuente: AWS</p>
<p>Ahora que ya podemos levantar rápidamente un clúster de Kubernetes y administrarlo desde un bastión host, ¿ qué te parece si en próximas entradas trabajamos como levantar un sistema de monitoreo de costos sobre el clúster?</p>
]]></content:encoded></item><item><title><![CDATA[Utilizando una función lambda con una IP estática]]></title><description><![CDATA[En ocasiones, puede ser necesario contar con una dirección IP para registrarla dentro de una whitelist y permitir conexiones solo desde una dirección específica o un rango de IP determinado. Este proceso es clave cuando interactuamos con servicios qu...]]></description><link>https://blog.alfalfita.cloud/utilizando-una-funcion-lambda-con-una-ip-estatica</link><guid isPermaLink="true">https://blog.alfalfita.cloud/utilizando-una-funcion-lambda-con-una-ip-estatica</guid><category><![CDATA[serverless]]></category><dc:creator><![CDATA[Diana Alfaro]]></dc:creator><pubDate>Sun, 06 Oct 2024 05:00:00 GMT</pubDate><content:encoded><![CDATA[<p>En ocasiones, puede ser necesario contar con una dirección IP para registrarla dentro de una whitelist y permitir conexiones solo desde una dirección específica o un rango de IP determinado. Este proceso es clave cuando interactuamos con servicios que requieren controles de seguridad más estrictos.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1735599725022/afb508aa-45dd-4427-be5e-60697e344c49.png" alt class="image--center mx-auto" /></p>
<p><em>Imagen: AWS Lambda invocando un proveedor de API que solo permite conexiones desde direcciones IP específicas</em></p>
<p>AWS Lambda es un servicio "sin servidor" y, cuando trabajamos con funciones Lambda, estas no se crean dentro de una VPC, por lo que no tienen una dirección IP asignada. Entonces, ¿cómo podemos resolver este requisito utilizando funciones Lambda?</p>
<p>AWS Lambda, junto con otros servicios como DynamoDB, S3, SQS, SNS, entre otros, pertenece al espacio público de AWS. Cada vez que un recurso dentro de una VPC interactúa con estos servicios, lo hace a través de la red pública.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1735599450306/814a1bd9-cb5e-4db2-b14a-7c4e4e8e5c15.png" alt class="image--center mx-auto" /></p>
<p>Imagen: <em>Servicios en Zona Pública de AWS. Fuente: Elaboración propia</em></p>
<p>Sin embargo, si queremos que esta comunicación se realice dentro de la misma red o, por razones de seguridad, necesitamos que un servicio se ejecute dentro de una VPC específica, en una o más subredes, y tenga un grupo de seguridad, podemos utilizar los <a target="_blank" href="https://docs.aws.amazon.com/es_es/whitepapers/latest/aws-privatelink/what-are-vpc-endpoints.html"><strong>VPC endpoints</strong></a> que AWS nos proporciona. Estos VPC endpoints pueden ser de dos tipos:</p>
<ul>
<li><p><a target="_blank" href="https://docs.aws.amazon.com/es_es/whitepapers/latest/aws-privatelink/what-are-vpc-endpoints.html"><strong>Interface</strong></a>: Abastece una mayor cantidad de servicios (como en este caso, Lambda) y tiene un costo asociado a la ENI (Interfaz de Red Elástica) que se genera con la creación del VPC endpoint.</p>
</li>
<li><p><a target="_blank" href="https://docs.aws.amazon.com/es_es/whitepapers/latest/aws-privatelink/what-are-vpc-endpoints.html"><strong>Gateway</strong></a>: Actualmente solo cubre servicios como DynamoDB y S3, y no tiene costo alguno.</p>
</li>
</ul>
<p><a target="_blank" href="https://docs.aws.amazon.com/es_es/whitepapers/latest/aws-privatelink/what-are-vpc-endpoints.html"><img src="https://docs.aws.amazon.com/images/whitepapers/latest/aws-privatelink/images/connectivity.png" alt="Connectivity to AWS services using VPC endpoints" /></a></p>
<p>Imagen: <em>Conectividad con servicios de AWS mediante VPC endpoints. Fuente: AWS</em></p>
<p>Por lo tanto, asociar un VPC endpoint a una función lambda nos ayudará a que el tráfico entre mi lambda y otros servicios de AWS se mantengan dentro de la misma red privada de AWS sin salir a Internet (reduce los costos de transferencia de datos externa y mejora la latencia); además de poder aplicar mayores controles de seguridad (a través de un grupo de seguridad).</p>
<p>Para asociar una VPC a una función lambda, basta con ir al tab Configuración → VPC</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1735600857402/fc7ef56c-ff94-429f-b66b-d408c79f2fcd.png" alt class="image--center mx-auto" /></p>
<p>Imagen: Configuración función lambda</p>
<p>Y seleccionar la VPC, las subredes y el grupo de seguridad que vamos a asociar a la función lambda</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1735601031190/697a0af0-a617-4af3-bc41-f0d40268bb88.png" alt class="image--center mx-auto" /></p>
<p>Para este ejemplo, hemos desarrollado un código de ejemplo para la función lambda.</p>
<pre><code class="lang-python"><span class="hljs-keyword">import</span> json
<span class="hljs-keyword">import</span> urllib.request

lambda_handler = <span class="hljs-keyword">lambda</span> event, context: {
    <span class="hljs-string">'statusCode'</span>: <span class="hljs-number">200</span>,
    <span class="hljs-string">'body'</span>: json.dumps({
        <span class="hljs-string">'ip_address'</span>: urllib.request.urlopen(<span class="hljs-string">"http://checkip.amazonaws.com"</span>).read().decode(<span class="hljs-string">'utf-8'</span>).strip()
    })
}
</code></pre>
<p><em>Código función lambda: Python 3.9</em></p>
<p>Este código realiza una solicitud HTTP a <a target="_blank" href="http://checkip.amazonaws.com"><code>http://checkip.amazonaws.com</code></a> para obtener la IP pública desde la que la función Lambda se está ejecutando. El resultado se devuelve en formato JSON.</p>
<p>Cuando una función Lambda se ejecuta en una subred privada, el tráfico de salida a Internet generalmente pasa a través de un <strong><em>NAT Gateway</em></strong>. Este <strong><em>NAT Gateway</em></strong> asigna una IP pública al tráfico de salida, que normalmente es una <strong><em>Elastic IP (EIP)</em></strong>, y esa será la dirección IP utilizada para las solicitudes HTTP/HTTPS externas realizadas por Lambda.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1735602119898/4ecd8ddc-9726-430f-b246-1b26f01ee933.png" alt class="image--center mx-auto" /></p>
<p>Imagen: Arquitectura de una lambda con VPC endpoint en subredes privadas.</p>
<p>Al ejecutar la función lambda, vemos que como resultado nos trae una dirección IP</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1735600447716/5d99cf24-8cfb-44e8-aefb-82324b4eb59b.png" alt class="image--center mx-auto" /></p>
<p><em>Imagen: Resultado de ejecución de la lambda</em></p>
<p>Esa dirección IP corresponde con una IP elástica, como podemos verificar en la consola.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1735600487004/dd011d1f-e8ff-4b0f-8ac9-1ffe9dd961cb.png" alt class="image--center mx-auto" /></p>
<p><em>Imagen: IP elástica</em></p>
<p>Y esa IP elástica es la que se encuentra asociada al NAT Gateway de la VPC donde se encuentra la lambda. De esta forma cada vez que la función lambda se ejecute está será su IP asociada, la cual podrá ser registrada en un whitelist de un data center de ser el caso.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1735600526310/23e98f9e-c209-4880-8903-759e3d29d28e.png" alt class="image--center mx-auto" /></p>
<p><em>Imagen: NatGateway de la VPC Egress</em></p>
<p>Cuando una función Lambda necesita realizar una solicitud HTTP/HTTPS a una API externa, se sigue el siguiente proceso:</p>
<ol>
<li><p>El tráfico sale de la VPC a través de la <strong>NAT Gateway</strong>.</p>
</li>
<li><p>La Lambda utilizará la <strong>IP pública</strong> de la NAT Gateway para acceder a los servicios externos.</p>
</li>
<li><p>Si tienes una <strong>Elastic IP (EIP)</strong> asociada a la NAT Gateway, esta será la dirección IP utilizada para la salida del tráfico.</p>
</li>
</ol>
<p>Aunque, la Lambda no cuenta con una IP estática propia, podemos emplear la IP de salida de la NAT Gateway. Si requerimos que esta dirección IP sea fija, debemos asociar una Elastic IP a la NAT Gateway.</p>
<p>De esta forma, asignar una IP estática a una función Lambda dentro de una VPC es una estrategia eficaz para cumplir con los requisitos de seguridad de servicios que exigen conexiones desde direcciones IP específicas.</p>
]]></content:encoded></item><item><title><![CDATA[¿Cómo usé AWS Amplify para desplegar mis microfrontends?]]></title><description><![CDATA[Primero empecemos hablando sobre ¿qué son los microfrontends?
Es la misma idea que existe en el backend con los microservicios pero trasladadas al front; es decir, tendremos BD, backend y front independientes.
Por ejemplo si tuviéramos una tienda de ...]]></description><link>https://blog.alfalfita.cloud/despliegue-de-microfrontends</link><guid isPermaLink="true">https://blog.alfalfita.cloud/despliegue-de-microfrontends</guid><category><![CDATA[AWS]]></category><category><![CDATA[AWS Amplify Hackathon]]></category><category><![CDATA[AWS Amplify]]></category><category><![CDATA[Cloud Computing]]></category><category><![CDATA[Microfrontend]]></category><dc:creator><![CDATA[Diana Alfaro]]></dc:creator><pubDate>Fri, 31 Mar 2023 18:27:20 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1680287013424/51c7f05d-9712-461b-a8ee-6c7a14d631c1.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p><strong>Primero empecemos hablando sobre ¿qué son los microfrontends?</strong></p>
<p>Es la misma idea que existe en el backend con los microservicios pero trasladadas al front; es decir, tendremos BD, backend y front independientes.</p>
<p>Por ejemplo si tuviéramos una tienda de e-commerce tendríamos las siguientes aplicaciones:</p>
<ul>
<li><p><strong>Para el registro/login del usuario:</strong> sería una micro-aplicación que puede estar en React</p>
</li>
<li><p><strong>Para el producto:</strong> sería una micro-aplicación que puede estar en Angular</p>
</li>
<li><p><strong>Para el carrito de compras:</strong> sería una micro-aplicación que puede estar en Vue</p>
</li>
<li><p><strong>Para el checkout:</strong> esta micro-aplicación podría estar en React</p>
</li>
</ul>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1680287737651/8f87b121-55ca-4f80-8bb0-3e7972dccb76.png" alt class="image--center mx-auto" /></p>
<p><strong>¿Que ventajas nos ofrecen los microfrontends?</strong></p>
<p>Es ideal porque te permite reutilizar los microfrontends en otras aplicaciones, manteniendo un solo código.</p>
<p>Cada microfrontend tiene <strong>su propio repositorio de código</strong>, <strong>su propio archivo package.json</strong> y su propia configuración de implementación de compilación. De esta manera, cada microfrontend <strong>tiene un proceso de compilación independiente y una implementación/CI independiente.</strong> Lo que nos brinda tiempos de construcción rápidos.</p>
<p>En un futuro todo el frontend en las grandes empresas, con equipos alrededor del mundo irán usando este enfoque, para aplicaciones muy grandes que requiere que diferentes equipos hagas diferentes cosas</p>
<p><strong>¿Cómo orquestar los microfrontends?</strong></p>
<p>Para esta solución se ha usado <a target="_blank" href="https://single-spa.js.org/"><strong>Single SPA</strong></a></p>
<p>Single SPA es un framework que trabaja como orquestador de microfronts, gestiona tu microfronts con frameworks y librerías como React, Vue, y Angular, lo que nos permite usarlos en la misma página sin tener tener que actualizarla.</p>
<p><strong>El proyecto</strong></p>
<p>Ahora que ya tenemos más claro, que son los microfronts, vamos a comentar sobre la solución de esta oportunidad: es un proyecto que consume algunas API’s para mostrar información de personajes de Rick and Morty y Harry Potter.</p>
<p>Para los microfrontends se utilizó React y se crearon 5 microfrontends, los cuales se alojan en repos diferentes, los cuales los puedes descargar desde los siguientes enlaces:</p>
<ul>
<li><p><a target="_blank" href="https://github.com/alfalfita/fr-shell/">fr-shell</a></p>
</li>
<li><p><a target="_blank" href="https://github.com/alfalfita/fr-header">fr-header</a></p>
</li>
<li><p><a target="_blank" href="https://github.com/alfalfita/fr-list">fr-list</a></p>
</li>
<li><p><a target="_blank" href="https://github.com/alfalfita/fr-category">fr-category</a></p>
</li>
<li><p><a target="_blank" href="https://github.com/alfalfita/fr-utils">fr-utils</a></p>
</li>
</ul>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1680285440450/390d2b93-3bc8-4221-b962-bf372b9def2e.png" alt class="image--center mx-auto" /></p>
<p>Ahora para su despliegue utilice <strong>AWS Amplify</strong></p>
<p><strong>¿Qué es AWS Amplify?</strong></p>
<p>Es un framework que nos ayuda en todo el ciclo de vida de nuestras aplicaciones en la nube.</p>
<p>Tiene diferentes componentes que podemos usar, en este caso usaremos el componente de hosting. El cual nos permitirá desplegar  todos los micro-frontends en S3 y CloudFront.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1680285489709/45a4615e-3924-4e8e-b741-661cee6544f5.png" alt class="image--center mx-auto" /></p>
<p><strong>¿Cómo desplegar nuestro microfrontends usando AWS Amplify?</strong></p>
<p>Para la configuración podemos seguir la <a target="_blank" href="https://docs.amplify.aws/lib/project-setup/prereq/q/platform/js/">documentación</a></p>
<p>Una vez listo, podemos continuar con nuestro siguiente paso para crear los recursos necesarios para desplegar nuestra aplicación con AWS Amplify</p>
<p>Primero nos ubicaremos en la carpeta de nuestro microfront padre (<em>fr-shell</em>) y ejecutaremos el siguiente comando:</p>
<p><code>amplify init</code></p>
<p>El cual nos pedirá ingresar información sobre el proyecto. Podemos revisar más detalles en la <a target="_blank" href="https://docs.amplify.aws/cli/start/workflows/#optional-update-projects-using-latest-amplify-cli">documentación</a></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1680285536785/467220e5-d837-4b5f-b8dc-24e22baad1d9.png" alt class="image--center mx-auto" /></p>
<p>Tomará un tiempo hasta que el despliegue de los recursos termine. Luego de ello tendremos una aplicación creada dentro del panel de AWS Amplify.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1680285544071/a439b061-d585-4a91-9dbb-dce3c5df9be9.png" alt class="image--center mx-auto" /></p>
<p>Así como una pila de CloudFormation con un bucket S3 con archivos de metadatos de Amplify y dos roles de IAM</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1680285558412/a8b2661b-e95c-4f1b-aa00-50d1508743b4.png" alt class="image--center mx-auto" /></p>
<p>El comando anterior, nos crea esta estructura de proyecto</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1680285571212/01a9a38c-a00a-43e9-a956-1697a414cc79.png" alt class="image--center mx-auto" /></p>
<p>Como mencione anteriormente, AWSAmplify nos permite agregar hosting, para ello dentro de nuestro proyecto (fr-shell) ejecutaremos el siguiente comando:</p>
<p><code>amplify add hosting</code></p>
<p>Y seleccionaremos la opción de Amazon CloudFront and S3</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1680285589118/d2539219-44db-4c53-9196-0ddd64de6cf5.png" alt class="image--center mx-auto" /></p>
<p>Nos pedirá ingresar el nombre de nuestro bucket S3. Y una vez completado, la estructura de nuestro proyecto se actualizará con una nueva carpeta con el nombre <strong>hosting</strong> dentro de la carpeta amplify/backend.</p>
<p>Este hosting que hemos agregado, permitirá acceder al bucket S3 solo a través de la distribución de CloudFront, mediante la creación de una Identidad de acceso de origen (OAI) de CloudFront.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1680285600510/6033354a-f74b-4063-a6bb-78c082327cf0.png" alt class="image--center mx-auto" /></p>
<p>Ahora queda publicar nuestros cambios</p>
<p><code>amplify publish</code></p>
<p>Este comando además de subir nuestros cambios al bucket S3 y crear la distribución de CloudFront, también genera el build del proyecto.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1680285623244/4aa970bd-70a0-47cf-9566-1cbb1ef3145e.png" alt class="image--center mx-auto" /></p>
<p>Una vez completado el proceso, nos arrojará el endpoint de la distribución de CloudFront que usaremos para acceder a nuestro sitio web.</p>
<p><strong><em>Pero eso no termina aquí, necesitamos desplegar los otros microfrontends que tenemos (en total son 5). Así que repetiremos los pasos previamente para cada uno de los microfrontends:</em></strong></p>
<p><code>amplify init</code></p>
<p><code>amplify add hosting</code></p>
<p><code>amplify publish</code></p>
<p>Tomaremos nota de cada uno de los endpoints de la distribuciones de CloudFront de cada microfrontend.</p>
<p>Luego en el archivo <em>fr-shell/src/index.ejs</em> pueden configurar sus entornos, en mi caso solo tengo local y prod, por ese motivo es que le pondré un else y el valor sería el endpoint de la distribución de CloudFront que corresponda.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1680285659634/313fecbe-f6b8-4d4d-a7ca-6e3eada42d1a.png" alt class="image--center mx-auto" /></p>
<p>Una vez hecho el cambio haremos nuevamente un <code>amplify publish</code> sobre nuestro microfrontend <em>fr-shell</em></p>
<p>Como necesitamos acceder a archivos distribuidos en CloudFront directamente en el código, debemos configurar los ajustes de CORS, para ello entraremos en cada distribución de CloudFront y haremos la siguiente configuración:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1680286698898/66c2a2ca-6329-45ef-bc2d-9ebce264d0b9.gif" alt class="image--center mx-auto" /></p>
<p>¡Listo! Podemos acceder a nuestros microfrontends desplegados, usando el endpoint de fr-shell. Teniendo el <a target="_blank" href="https://d9qz0hjql6kvy.cloudfront.net/">siguiente resultado</a></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1680287006005/a45da5ee-2a74-401d-a16f-692a0416ed1f.png" alt class="image--center mx-auto" /></p>
<p>To cloud and beyond! 🚀</p>
]]></content:encoded></item><item><title><![CDATA[Configurando nuestro entorno de trabajo con AWS Organization y AWS Identity Center]]></title><description><![CDATA[En entornos reales muchas empresas usan una sola cuenta de AWS, por el contrario emplean muchas cuentas quizás cientos de cuentas de AWS. Y es aquí donde entra el servicio de AWS Organizations, un servicio sin costo que nos permite administrar y cont...]]></description><link>https://blog.alfalfita.cloud/configurando-nuestro-entorno-de-trabajo-con-aws-organization-y-aws-identity-center</link><guid isPermaLink="true">https://blog.alfalfita.cloud/configurando-nuestro-entorno-de-trabajo-con-aws-organization-y-aws-identity-center</guid><category><![CDATA[AWS]]></category><category><![CDATA[Cloud]]></category><category><![CDATA[#AWSOrganization]]></category><category><![CDATA[ #AWSIdentityCenter]]></category><dc:creator><![CDATA[Diana Alfaro]]></dc:creator><pubDate>Sun, 12 Feb 2023 18:45:22 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1676302796261/62b29390-e57d-42bf-a204-8b5c04f97262.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>En entornos reales muchas empresas usan una sola cuenta de AWS, por el contrario emplean muchas cuentas quizás cientos de cuentas de AWS. Y es aquí donde entra el servicio de AWS Organizations, un servicio sin costo que nos permite administrar y controlar las cuentas de AWS de nuestra organización en un solo lugar (<a target="_blank" href="https://aws.amazon.com/organizations/">https://aws.amazon.com/organizations/</a>)</p>
<p>En el sitio web nos indica el funcionamiento de este servicio: <em>“AWS Organizations le permite crear cuentas nuevas de AWS sin costo adicional. Con cuentas en la organización, puede asignar recursos, agrupar cuentas y aplicar políticas de gobernanza a cuentas o grupos fácilmente.”</em></p>
<p>Podemos crear cuentas para los distintos departamentos de una organización: TI, Marketing, Finanzas, etc; o bien podemos crear cuentas para entornos o proyectos: Producción, Desarrollo, Pruebas, etc. De esta manera podemos aprovechar algunas ventajas como:</p>
<ul>
<li><p>Los limites de servicio serán por cuenta y ya no serán compartidos entre los distintos proyectos dentro una cuenta en común</p>
</li>
<li><p>Podemos establecer políticas de control de servicio (SCP) a nivel de cuenta para evitar ciertas acciones o creación de recursos de un servicio en particular o en una region en particular</p>
</li>
<li><p>Podemos invitar cuentas que ya existen o bien podemos crear una cuenta ingresando el correo</p>
</li>
<li><p>Podemos compartir recursos entre cuentas</p>
</li>
<li><p>Podemos tener una mayor visibilidad sobre los gastos realizados por un departamento o proyecto, ya que los gastos se verán reflejados para esa cuenta en particular</p>
</li>
<li><p>Facturación consolidada, podemos obtener descuentos al agrupar los costos de todas las cuentas</p>
</li>
</ul>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1676227076217/f6191a04-126d-485c-a5a8-a83bd90c4c41.png" alt="Fuente: https://docs.aws.amazon.com/organizations/latest/userguide/orgs_getting-started_concepts.html" class="image--center mx-auto" /></p>
<p>Fuente: <a target="_blank" href="https://docs.aws.amazon.com/organizations/latest/userguide/orgs_getting-started_concepts.html">https://docs.aws.amazon.com/organizations/latest/userguide/orgs_getting-started_concepts.html</a></p>
<p>Sabiendo todo esto, quise configurar mi cuenta de organización, anteriormente tenia mi cuenta principal con mi usuario root, el cual tenia el MFA habilitado y había creado un usuario con acceso administrador (y también con el MFA habilitado) el cual era el que usaba para ingresar a la consola o con sus credenciales de acceso realizar operaciones a través de AWS CLI. Pero esta vez, tendría mi organización con 2 cuentas: una para cada uno de los proyectos que estoy realizando. Hoy quiero compartir como fue que realice esta configuración:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1676302505207/7f944b06-d566-4bcf-97bc-ca23a8025cd9.png" alt class="image--center mx-auto" /></p>
<h2 id="heading-1-crear-una-cuenta-de-aws"><strong>1- Crear una cuenta de AWS</strong></h2>
<p>Para ello necesitamos un correo electrónico y una tarjeta de debito/crédito para poder registrarla.</p>
<p>En el caso de AWS cuando creamos una cuenta, ésta tiene una capa gratuita durante un año pero si en algún momento nos excedemos en algún servicio o usamos algún servicio no incluido en la capa gratuita ese monto se nos debitara de la tarjeta que hemos registrado.</p>
<p>Para evitar ello, es importante revisar que incluye esa capa gratuita,</p>
<p><a target="_blank" href="https://aws.amazon.com/es/free/">https://aws.amazon.com/es/free/</a></p>
<p>Y para crear la cuenta, te dejo el enlace a la documentación oficial</p>
<p><a target="_blank" href="https://aws.amazon.com/es/premiumsupport/knowledge-center/create-and-activate-aws-account/">https://aws.amazon.com/es/premiumsupport/knowledge-center/create-and-activate-aws-account/</a></p>
<h2 id="heading-2-ir-a-aws-organizations-y-crear-nuestra-estructura-de-organizacion">2- Ir a AWS Organizations y crear nuestra estructura de organización</h2>
<p>Para ello, con nuestro usuario root ingresaremos a la opción de Organización en el menu superior izquierdo</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1676227171276/d09aed12-1f72-46f6-8705-8ca8f6c7c8b5.png" alt class="image--center mx-auto" /></p>
<p>Una vez dentro, podremos ver mas información y enlace a la documentación de este servicio</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1676227188740/9a237269-4cac-4773-bb35-830079d528b7.png" alt class="image--center mx-auto" /></p>
<p>Ingresaremos a la opción: Cuentas de AWS</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1676227201399/e3474ee8-1390-43a9-8d9b-0a45f15c1fc5.png" alt class="image--center mx-auto" /></p>
<p>Esta es mi estructura de organización que he creado, partimos de la raíz y podemos tener varias unidades organizativas (OU), que pueden ir anidadas, es decir podemos tener una OU dentro de otra OU.</p>
<p>Dentro de cada OU vamos a tener nuestras cuentas de AWS, una cuenta solo puede pertenecer a una OU a la vez.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1676227216372/5660e0b8-dd9e-4278-a5c3-e55c9c09b998.png" alt class="image--center mx-auto" /></p>
<p>Para crear una OU, basta con seleccionar el check de Root e ir al menú de Acciones</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1676227233076/3306e1c8-8fc3-47e8-8f4b-66e4378ba673.png" alt class="image--center mx-auto" /></p>
<p>Una vez allí, ingresamos el nombre de la OU y la creamos.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1676227242627/21dcb70c-c7f4-45b7-94d9-e22031f3fa22.png" alt class="image--center mx-auto" /></p>
<p>Repetiremos el proceso tantas veces sea necesario.</p>
<p>Ahora el siguiente paso es agregar las cuentas de AWS a la OU que corresponda</p>
<h2 id="heading-3-invitar-una-cuenta-que-ya-existe">3- Invitar una cuenta que ya existe</h2>
<p>En este caso, si tenemos una cuenta de AWS que ya existe y queremos que sea parte de la organización podemos invitarla a formar parte.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1676227272200/3bf10daa-12ea-48a2-a1e5-5bab6fcea41a.png" alt class="image--center mx-auto" /></p>
<p><em>Nota: Una cuenta de AWS solo puede pertenecer a una organización a la vez, si la cuenta que quieres agregar ya pertenece a otra organización, primero deberá retirarse de esa organización antes de pertenecer a la nueva organización</em></p>
<h2 id="heading-4-agregar-una-cuenta-no-existe">4 -  Agregar una cuenta no existe</h2>
<p>En este caso ingresaremos los datos que nos piden para crear la cuenta</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1676227307586/2578e69e-7caa-4f16-ba9b-666db12ac5d0.png" alt class="image--center mx-auto" /></p>
<p>Y al cabo de unos minutos nos llegará al correo ingresado un mensaje indicándonos que la cuenta ha sido creada</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1676227337739/3b1d0b69-211e-40b9-999b-cc177aca2fc1.png" alt class="image--center mx-auto" /></p>
<h2 id="heading-5-trasladar-una-cuenta-a-una-ou">5- Trasladar una cuenta a una OU</h2>
<p>Una vez tengamos listas nuestras cuentas necesitamos trasladarlas</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1676227355733/2f69fbe8-514d-4502-b7a8-d95bca166f75.png" alt class="image--center mx-auto" /></p>
<p>Y seleccionamos la OU a la que pertenecer la cuenta</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1676227367395/634efc1e-48a3-476a-a915-0ad8ba09b9f8.png" alt class="image--center mx-auto" /></p>
<h2 id="heading-6-habilitar-aws-identity-center">6 - Habilitar AWS Identity Center</h2>
<p>Ahora debemos establecer los usuarios y permisos a las cuentas que hemos creado, para ello necesitamos ir al panel de AWS Identity Center y habilitar el servicio</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1676227685347/8d217332-f711-478f-8040-72b01167b96a.png" alt class="image--center mx-auto" /></p>
<p>Una vez habilitado, nos mostrará la URL por la cual accederemos para loguearnos. La cual si queremos la podemos personalizar.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1676227718302/e246f7da-afac-4478-92ea-d2a9fb7be979.png" alt class="image--center mx-auto" /></p>
<h2 id="heading-7-conjunto-de-permisos">7 - Conjunto de permisos</h2>
<p>Los conjuntos de permisos definen el nivel de acceso que los usuarios del Centro de identidades de IAM tienen a las cuentas de AWS asignadas. Los nombres de los conjuntos de permisos aparecen como roles disponibles en el portal de acceso de AWS. Los usuarios asignadas a varios conjuntos de permisos de AWS pueden iniciar sesión en el portal de acceso de AWS, elegir una cuenta y, a continuación, elegir un rol que AWS haya creado a partir de un conjunto de permisos asignado. <a target="_blank" href="https://docs.aws.amazon.com/console/singlesignon/aws-accounts/permission-sets-tab/intro">Más información</a></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1676227737470/f9f976fa-6995-4235-beb9-ad2245db25bd.png" alt class="image--center mx-auto" /></p>
<p><strong>Para un usuario administrador:</strong></p>
<p>Seleccionaremos el conjunto de permisos predefinido: <strong><em>AdministratorAccess</em></strong></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1676227753067/ffcaa6fe-64ec-4b52-b068-bf343821415b.png" alt class="image--center mx-auto" /></p>
<p>Hay otros permisos predefinidos que podemos usar según el caso</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1676227765389/8b4b1909-ea5b-4e14-b754-884a590f1d84.png" alt class="image--center mx-auto" /></p>
<p>Establecemos el nombre del conjunto de permisos y la duración de la sesión</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1676227778090/e4d361d6-0fe5-43cf-93ae-19b713f3c4f5.png" alt class="image--center mx-auto" /></p>
<p><strong>Para usuarios no administradores</strong></p>
<p>Para mi caso, usaré el permiso predefinido: <strong><em>PowerUserAccess</em></strong></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1676227802758/ba5d28a9-fed3-43d4-af9a-b2f6eb4c924e.png" alt class="image--center mx-auto" /></p>
<p>Una vez creados los conjuntos de permisos, estos se aprovisionarán y estarán listos para usar</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1676227816980/23d48096-8e97-4b50-8330-7671ca6cdc6d.png" alt class="image--center mx-auto" /></p>
<h2 id="heading-8-creacion-de-usuarios">8 - Creación de usuarios</h2>
<p>Estos usuarios pueden iniciar sesión en el portal de acceso de AWS para obtener acceso a las cuentas y aplicaciones en la nube de AWS asignadas.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1676227890463/7ccaa4df-4d55-4d09-89e6-80c0d385d776.png" alt class="image--center mx-auto" /></p>
<p>Ingresamos los datos solicitados</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1676227910606/a857ca3d-49e4-4c9c-b69e-f4a7523a6717.png" alt class="image--center mx-auto" /></p>
<p>En mi caso no he creado grupos, así que ire al siguiente paso</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1676227934555/2f468fdd-0d3f-4bcb-82ff-6d06b6f3499e.png" alt class="image--center mx-auto" /></p>
<p>Verificamos que todo este bien y creamos el usuario</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1676227954402/3b455077-4a7b-437e-b5ee-c27ade98c31d.png" alt class="image--center mx-auto" /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1676227987514/3c3252c2-64ee-4849-aef9-4b6f471296dd.png" alt class="image--center mx-auto" /></p>
<p>Cuando creamos un usuario, se envía un correo de verificación al correo del usuario creado</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1676228016106/f05a5938-e460-4d5e-af47-c452e29a5ceb.png" alt class="image--center mx-auto" /></p>
<p>El cual nos pedirá establecer una contraseña</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1676228038866/c9c2fa01-5002-4416-8342-8d6f436b1407.png" alt class="image--center mx-auto" /></p>
<p>Ahora debemos habilitar el MFA del usuario, para lo cual entraremos en el detalle</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1676228065463/1cac86ab-ff62-466d-bbc1-f27a940d80fd.png" alt class="image--center mx-auto" /></p>
<p>Y seleccionaremos la opción de Registro MFA</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1676228105044/e6dd1a20-d995-4055-a336-177b7d00dbbf.png" alt class="image--center mx-auto" /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1676228116601/43742cb5-3f69-43be-9094-260677f6fbbd.png" alt class="image--center mx-auto" /></p>
<p>Seguimos los pasos de acuerdo al tipo de dispositivo MFA que tengamos. Y una vez listo, nos pedirá cada vez que iniciemos sesión un código aleatorio además del usuario/contraseña</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1676228134871/3bca7e53-195e-4a11-90e7-43c8e8f84bfd.png" alt class="image--center mx-auto" /></p>
<h2 id="heading-9-asignar-usuarios-a-las-cuentas-que-tendran-acceso">9 - Asignar usuarios a las cuentas que tendrán acceso</h2>
<p>Seleccionamos una o más cuentas de AWS para el acceso de múltiples cuentas a usuarios</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1676228184974/aeb25256-b063-43d6-a909-6f44a4a864ce.png" alt class="image--center mx-auto" /></p>
<p>Luego seleccionamos el o los usuarios a agregar</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1676228419778/6ca38c17-30d7-41cb-9893-b8dc9b4618dc.png" alt class="image--center mx-auto" /></p>
<p>Seleccionamos los permisos que tendrá ese usuario en esa cuenta</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1676228362053/2a750556-59b3-4a98-a9af-c7038ec5d4ff.png" alt class="image--center mx-auto" /></p>
<p>Revisamos y confirmamos</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1676228328248/e27ea5a2-4f95-4db2-9083-86e5802bc922.png" alt class="image--center mx-auto" /></p>
<p>Para verificar el acceso iniciamos sesión en la URL proporcionada en el punto 6</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1676228305842/c739d31a-3525-4e47-9bcc-b7414557a2cd.png" alt class="image--center mx-auto" /></p>
<p>Una vez ingresado los datos podremos ver las cuentas de AWS a las que tenemos acceso y en caso de tener mas de un tipo de permiso podremos elegir cual usar</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1676228277569/fa69dd19-c772-43f4-af98-8ecdd65827f1.png" alt class="image--center mx-auto" /></p>
<p>Si ingresamos con la opción de consola de administración podremos observar en el desplegable del menu superior derecho información relacionada a nuestra cuenta</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1676228266786/e0b8ba3f-a4f2-4fd5-a0e6-43ab58695685.png" alt class="image--center mx-auto" /></p>
<h2 id="heading-10-para-la-configuracion-de-aws-cli">10 - Para la configuración de AWS CLI</h2>
<p>Debemos tener instalado AWS CLI<br /><a target="_blank" href="https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-getting-started.html">https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-getting-started.html</a></p>
<p>Luego ejecutamos <code>aws configure</code> e ingresaremos los datos que nos provee AWS</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1676228239747/e5470ee8-21fe-42f1-95f9-9d0a1569b683.jpeg" alt class="image--center mx-auto" /></p>
<p>Y listo, así podemos configurar un entorno multicuenta con AWS Organizations, estableciendo usuarios y permisos para estas cuentas con AWS Identity Center</p>
<p><strong>Más información:</strong></p>
<p><a target="_blank" href="https://docs.aws.amazon.com/organizations/latest/userguide/orgs_tutorials_basic.html">https://docs.aws.amazon.com/organizations/latest/userguide/orgs_tutorials_basic.html</a></p>
]]></content:encoded></item><item><title><![CDATA[¿Cómo empezó mi camino en la nube?]]></title><description><![CDATA[Mi camino en la nube empezó en el 2021, en el que por motivos de la vida y dado que estábamos confinados en casa por el COVID empece a leer al respecto y quede encantada con todo lo que leía a tal punto que empece a leer más y más.
Recuerdo que vi un...]]></description><link>https://blog.alfalfita.cloud/como-empezo-mi-camino-en-la-nube</link><guid isPermaLink="true">https://blog.alfalfita.cloud/como-empezo-mi-camino-en-la-nube</guid><category><![CDATA[AWS]]></category><category><![CDATA[Cloud]]></category><category><![CDATA[Cloud Computing]]></category><category><![CDATA[AWSUserGroup]]></category><dc:creator><![CDATA[Diana Alfaro]]></dc:creator><pubDate>Sun, 22 Jan 2023 19:09:46 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1674405375097/706cf6f0-7785-4077-ac10-0506d3790bdb.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Mi camino en la nube empezó en el 2021, en el que por motivos de la vida y dado que estábamos confinados en casa por el COVID empece a leer al respecto y quede encantada con todo lo que leía a tal punto que empece a leer más y más.</p>
<p>Recuerdo que vi un curso de <a target="_blank" href="https://aws.amazon.com/es/training/digital/aws-cloud-practitioner-essentials/">Cloud Essentials</a> donde explicaban los conceptos de la tecnología en la nube y algunos de los servicios de AWS haciendo referencia al funcionamiento de una cafetería, el cual me ayudo muchísimo a comprender todos esos conceptos.</p>
<h2 id="heading-descubriendo-los-aws-user-groups">Descubriendo los AWS User Groups</h2>
<p>Seguí <a target="_blank" href="https://aws.amazon.com/es/certification/certified-cloud-practitioner/?ch=tile&amp;tile=getstarted">buscando más información y material para leer</a>, y fue así como descubrí los AWS User Groups que están presentes en muchísimos países como Perú y además había una comunidad de <a target="_blank" href="https://linktr.ee/awsgirlsperu?utm_source=linktree_profile_share">AWS Girls Perú</a> ahí fue cuando quede completamente enamorada, porque chicas como yo que les gustaba la tecnología habían armado una comunidad y daban charlas sobre tecnología en la nube y los distintos servicios de AWS en nuestro idioma: español.</p>
<p>Empece a seguir los AWS User Groups en las redes sociales, en ese entonces debido al confinamiento los eventos eran online por lo que podía asistir sin problemas de horario y ver también los eventos pasados. También descubrí las comunidades de <a target="_blank" href="https://www.linkedin.com/company/aws-women-colombia?originalSubdomain=co">AWS Girls Women Colombia</a> y <a target="_blank" href="https://cl.linkedin.com/company/aws-girls-cl">AWS Girls Chile</a> que también daban sus charlas de manera remota.</p>
<p>Descubrí las certificaciones que ofrece AWS y la vi como una oportunidad de darle un impulso a mi carrera, aprender sobre una tecnología que me gustaba mucho y que cada vez es mas demandada por las empresas. Así que me puse a investigar un poco mas sobre ellas, inicialmente quería presentar la certificación Developer Associate porque estaba mas relacionada con mis tareas del día a día (soy desarrolladora de software) pero la realidad era que no tenia experiencia en la nube de AWS y en ninguna otra, por lo que preferí presentar primero el examen de certificación Cloud Practitioner.</p>
<h2 id="heading-preparandome-para-la-certificacion-cloud-practitioner">Preparándome para la certificación: Cloud Practitioner</h2>
<p>Para este examen de certificación aun no tenia el voucher comprado, pero empece a estudiar como si ya lo hubiese agendado (esto fue a finales del 2021), me registre en la plataforma de SkillBuilder con mi correo personal y empece a llevar los cursos recomendados para el examen, también estuve revisando la playlist de las comunidades de AWS Girls Peru y AWS Girls Women Colombia.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1674413824151/af565e29-2754-4d15-861c-71b802b8b3b4.png" alt class="image--center mx-auto" /></p>
<p>Luego a inicios del 2022, en mi empresa nos avisan de una capacitación que estaba ofreciendo AWS y que podíamos acceder por ser partner de ellos, el <a target="_blank" href="https://pages.awscloud.com/GLOBAL-other-GC-traincert-partner-Rocket-Journey-AWS-Spanish-2021-reg.html">Rocket Journey</a> un programa intensivo de 4 semanas que nos capacitaba y brindaba material de apoyo para lograr la certificación de Cloud Practitioner junto con otras mas.</p>
<p><img src="https://pages.awscloud.com/rs/112-TZM-766/images/AWS_T%26C_Rocket_Journey_september-2021-1342x348.png" alt="accredation paths" /></p>
<p>Ahí descubrí que si me registraba a AWS SkillBuilder con mi correo corporativo tenia acceso a mas cursos que no tenia acceso con mi cuenta personal y por si fuera poco, al final del Rocket Journey darían 120 vouchers a las personas con la mejor puntuación en una actividad que habían en la semana final (yo aun no tenia el voucher para el examen de certificación) así que sentí que mi momento había llegado y debía darlo todo para ser una de las 120 beneficiadas 💪</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1664393942242/8RnW6Gbbo.png?auto=compress,format&amp;format=webp" alt="image.png" class="image--center mx-auto" /></p>
<p>Y así fue, gracias a Dios conseguí estar dentro de los 120. A los pocos días me llego el voucher a mi correo y agendé mi examen semanas después y logre pasarlo (Abril 2022) para este examen se necesitaba una nota de 70% o mas para aprobar. Había logrado mi primera certificación y estaba muy emocionada, había aprendido tantas cosas y sentía la necesidad de seguir aprendiendo mas, esta vez me prepararía para mi siguiente examen: Architect Associate.</p>
<h2 id="heading-preparandome-para-la-certificacion-solution-architect-associate">Preparándome para la certificación: Solution Architect Associate</h2>
<p><img src="https://d3m889aznlr23d.cloudfront.net/img/events/id/458/458596840/assets/4e76bd29af79debe7befef9a4d46a444.logo-cloudup.jpg" alt /></p>
<p>En la búsqueda de información encontré un programa que busca darle oportunidades a las mujeres en el mundo cloud de AWS, asi fue como me tope con el programa de <a target="_blank" href="https://awscloudupforher-saa.splashthat.com/">AWS CloudUp for her</a> (antes <em>AWS She Builds</em>), un programa de entrenamiento que esta disponible en 2 versiones: para la certificación Cloud Practioner y para la certificación Architect Associate. Me registre y espere la próxima fecha de inicio. Este programa ofrece no solo entrenamiento para el examen sino que también te da la posibilidad de obtener un voucher de certificación si apruebas un examen de practica con mas de 80%. Yo ya venia de aprobar mi examen de Cloud Practitioner y por aprobar cualquiera de los exámenes de certificación AWS te brinda un código de descuento del 50% para que lo puedas usar ya sea para tu próxima certificación o para revalidar la que tienes (ya que tienen una duración de 3 años).</p>
<p>Aunque el contenido del programa estaba en ingles y los horarios de las charlas no siempre se ajustaban a mi zona horaria, hacia lo posible por asistir mientras continuaba estudiando con otros recursos por mi cuenta.</p>
<p>Ciertamente, el contenido de esta certificación era más extenso, debías conocer al detalle más servicios y también ganar experiencia practica en la consola. Ya tenia un background de redes de mi época universitaria que me toca desempolvar de mi mente y lo cual lo hizo mas llevadero, pero ciertamente el realizar laboratorios y talleres prácticos ayudaban a afianzar los conocimientos. También empece a tomar notas que en algunos casos iban acompañados de gráficos y tips de los servicios que iba a aprendiendo.</p>
<p>Durante este proceso me integre a 2 comunidades: AWS Girls Perú y AWS Girls Chile, con el grupo de AWS Girls Perú tuve la oportunidad de asistir a sus eventos presenciales y así poder conocer a otras chicas que como yo tienen esa misma pasión por la tecnología en la nube y los servicios de AWS; con el grupo de AWS Girls Chile aunque hay una distancia de muchos kilómetros hicimos match de inmediato y formamos también una bonita comunidad en la que intercambiamos ideas, recursos y materiales de estudio.</p>
<p><img src="https://media.licdn.com/dms/image/sync/C4E27AQGLI8-1E__hdQ/articleshare-shrink_1280_800/0/1673983929208?e=1675018800&amp;v=beta&amp;t=W_x7zkUFcf6l76cxWvZFg8td0d-onRnCGJDwtCyou0M" alt /></p>
<p>A finales de agosto (2022) presente y aprobé mi examen. Mas que feliz por lo logrado, y ya con la siguiente meta trazada: mi examen de Developer Associate, del cual ya escribí una entrada de cómo me prepare y de los recursos que tome que pueden consultar <a target="_blank" href="https://alfalfita.cloud/empezando-la-ruta-hacia-una-nueva-certificacion">en este enlace.</a></p>
<h2 id="heading-mi-primera-charla-en-la-comunidad"><strong>Mi primera charla en la comunidad</strong></h2>
<p>Si hay un tema que me ha gustado mucho desde que empece mi camino a la nube ha sido: <strong><em>Serveless</em></strong> <em>(del que hablare en otro post para no hacer este demasiado extenso)</em></p>
<p>Surgió la oportunidad de dar una charla virtual desde la comunidad de AWS Girls Chile, así que quise hablar de Lambda y Event Bridge. <a target="_blank" href="https://www.youtube.com/watch?v=cmBR1BxFSj0">Acá les dejo el video de la charla.</a></p>
<iframe width="560" height="315" src="https://www.youtube.com/embed/cmBR1BxFSj0"></iframe>

<p>Compartir tus conocimientos en comunidad es una oportunidad maravillosa de seguir aprendiendo, porque siempre he pensado que la mejor manera de aprender es enseñando a los demás y en ese proceso ambas partes aprenden y no solo la que enseña)</p>
<p><img src="https://media.licdn.com/dms/image/C4E22AQEyAnsh05NANw/feedshare-shrink_1280/0/1668726403469?e=1677110400&amp;v=beta&amp;t=BRIiwvp0LK9dGmK-dLehXVWGlzZVsU26d8CGmYtr4kY" alt="No hay descripción alternativa para esta imagen" /></p>
<p>Ser parte de las comunidades y ser ponente en las charlas o asistir a los eventos presenciales, te da la oportunidad de hacerte visible y generar mas networking, en mi caso me ofrecieron la oportunidad de ser instructora del programa de AWS re/start (luego creare una entrada para hablar mas al respecto) </p>
<h2 id="heading-me-ofrecieron-ser-parte-del-team-organizador-de-aws-girls-peru"><strong>Me ofrecieron ser parte del team organizador de AWS Girls Perú</strong></h2>
<p><img src="https://media.licdn.com/dms/image/D4E3DAQFt5GQ01k7qyQ/image-scale_191_1128/0/1673623540995?e=1675018800&amp;v=beta&amp;t=gG9SpNOYDSywUh_8KDFsMt5LIhV6X5AH-7ouJOGhkpA" alt /></p>
<p>Empece este año (2023) celebrando con mi familia haber pasado mi examen de Developer Associate y justo ese mismo día, me invitan a formar parte del team organizador de la comunidad de AWS Girls Perú dije: <em>sí!</em> sin dudarlo, me gusta ser parte de la comunidad y me gusta el poder motivar a otras personas a que empiecen su camino en la nube.</p>
<p>Así que iniciamos este 2023 llenas de energía y coordinando lo que fue nuestro primer evento del año. Acá les dejo el video</p>
<iframe width="560" height="315" src="https://www.youtube.com/embed/ltGANrQWPvc"></iframe>

<p>Se vienen muchas actividades para la comunidad que ya iremos informando en <a target="_blank" href="https://linktr.ee/awsgirlsperu">nuestras redes</a>.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1674411322998/46dd7e6e-ecbd-4c5d-925c-813de554092a.png" alt="https://linktr.ee/awsgirlsperu" class="image--center mx-auto" /></p>
<h2 id="heading-palabras-finales">¿Palabras finales?</h2>
<p>Escribir esta entrada del blog me ha emocionado al ver hacia atrás y ver dónde estoy ahora. Emocionada de ver todo lo que se viene y de hacer lo que me gusta y me apasiona.</p>
<p><img src="https://media.licdn.com/dms/image/C4E22AQHvgrjvP4-vTQ/feedshare-shrink_800/0/1667794786156?e=1677110400&amp;v=beta&amp;t=YLL7gd9q_bx_HfrSqBcGVL309U4JNIIhPHPAym0Egdc" alt="No hay descripción alternativa para esta imagen" /></p>
<p>Si por ahí estas queriendo empezar tu camino en la nube, adelante, hazlo!  Hay un montón de comunidades y personas dispuestas a ayudarte en el proceso.</p>
]]></content:encoded></item><item><title><![CDATA[AWS Application Composer]]></title><description><![CDATA[En Noviembre pasado se realizó el AWS re:Invent 2022 el máximo evento de AWS que se realizó en Las Vegas, Nevada que nos proporcionó una gran cantidad de anuncios, nuevos servicios y actualizaciones.
AWS Application Composer
Uno de esos servicios nue...]]></description><link>https://blog.alfalfita.cloud/aws-application-composer</link><guid isPermaLink="true">https://blog.alfalfita.cloud/aws-application-composer</guid><category><![CDATA[arquitectura]]></category><category><![CDATA[lambda]]></category><category><![CDATA[AWS]]></category><category><![CDATA[aws lambda]]></category><category><![CDATA[serverless]]></category><dc:creator><![CDATA[Diana Alfaro]]></dc:creator><pubDate>Mon, 09 Jan 2023 01:24:45 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1673226903765/9bf0dfa1-738a-4b6f-a903-f46ca91b2372.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>En Noviembre pasado se realizó el AWS re:Invent 2022 el máximo evento de AWS que se realizó en Las Vegas, Nevada que nos proporcionó una gran cantidad de anuncios, nuevos servicios y actualizaciones.</p>
<h2 id="heading-aws-application-composer">AWS Application Composer</h2>
<p>Uno de esos servicios nuevos llamo mi atencion: AWS Application Composer (<a target="_blank" href="https://docs.aws.amazon.com/application-composer/latest/dg/what-is-composer.html">https://docs.aws.amazon.com/application-composer/latest/dg/what-is-composer.html</a> ), un servicio que permite desde una interfaz Drag-and-Drop arrastrar y soltar distintos servicios asi como interconectarlos para poder crear una arquitectura cloud serverless, entregando el código en cloudformation.</p>
<p>De esta manera podemos concentrarnos en diseñar nuestra arquitectura y  dejar que Application Composer construya cómo se logra,  sin necesidad de ser un experto en AWS CloudFormation.</p>
<p>Podemos usarlo creando un proyecto de cero o cargando uno ya existente, en ambos casos tenemos 2 modos disponibles: conectados o no conectados,si elegimos el estado conectado los cambios que hagamos en las fuentes se verán reflejados en AWS Application Composer y viceversa, los cambios realizados en AWS Application Composer se reflejarán en el código fuente de nuestra aplicación.</p>
<p>Después de diseñar la aplicación serverless con AWS Application Composer, podemos usar cualquier servicio compatible con AWS CloudFormation para la implementación.</p>
<p>En mi caso, utilice: AWS SAM, que me permite realizar depuración y pruebas locales, así como ayudarme con el empaquetado y despliegue de mi aplicación.</p>
<p><img src="https://lh6.googleusercontent.com/wOQaIedRWga2j1jZVsLDhUShR6a79bghkU7KRU5CclIxLy8RzXkF_vcD7p-XGlXNMKel2pipzhCPo0-pdVRsw7JoiOGJXw9-6sAENzWDmAK6VrwIXwHJ1WGzAzr10sE5MSET60xnpyO-YlkpsrGSG_xxdrtInXxtoWbdm-r_h01zCNKgGjfumAgM-kv8Fw" alt /></p>
<p>La aplicación que desarrollé es un servicio de procesamiento de video. Para ello emplee un servicio que me ayuda con esta tarea que es  AWS Elemental MediaConvert (<a target="_blank" href="https://aws.amazon.com/es/mediaconvert/">https://aws.amazon.com/es/mediaconvert/</a>) que funciona tomando un video como entrada y, transcodificando el video a una o más versiones diferentes y luego coloca estas versiones en otro bucket S3.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1673890114060/4c5e6722-120f-4d97-977b-987937760890.png" alt class="image--center mx-auto" /></p>
<p>Para hacer la aplicación serverless, utilice un bucket S3 en donde se cargan los archivos a procesar, cada vez que se detectaba el evento cuando se cargaba un video al bucket, éste se enviaba a una cola SQS que era consumida por una función Lambda (está basada en NodeJS versión 18) que se encarga de llamar a AWS Elemental MediaConvert para el procesamiento del video.</p>
<h2 id="heading-manos-a-la-obra"><strong>Manos a la obra!</strong></h2>
<h3 id="heading-1-configuracion-de-aws-cli"><strong>1-  Configuración de AWS CLI</strong></h3>
<p>Necesitamos configurar AWS CLI en nuestro entorno local.</p>
<p><a target="_blank" href="http://docs.aws.amazon.com/cli/latest/userguide/installing.html">http://docs.aws.amazon.com/cli/latest/userguide/installing.html</a></p>
<p>Tenemos que tener nuestras credenciales de seguridad (<code>Access keys</code>)</p>
<p><a target="_blank" href="https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_access-keys.html#Using_CreateAccessKey_CLIAPI">https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_access-keys.html#Using_CreateAccessKey_CLIAPI</a></p>
<p>Luego ejecutamos desde una terminal en su sistema:</p>
<p>aws configure</p>
<p>La CLI de AWS solicita varias cosas:</p>
<p>Las credenciales de usuario (<code>Access keys</code>)</p>
<p>La región que usaremos: <code>us-east-1</code></p>
<p>El formato de salida predeterminado:  <code>json</code>.</p>
<h3 id="heading-2-obtener-el-endpoint-de-la-api-de-mediaconvert">2 - Obtener el endpoint de la API de MediaConvert</h3>
<p>Para ello iremos al panel del AWS Elemental MediaConvert  y luego iremos al menú lateral izquierdo en la sección Account, este endpoint lo usaremos para una variable de entorno de nuestra función lambda</p>
<p><img src="https://lh4.googleusercontent.com/K9uXOYIAuMyyDYe0XS4k3MZE36PicTfmv8E3wkb1TOCsICCVgeo7Ul4tGLS4z5kXzHtDkg3Eo_4PJ_s3hm6trQAQ_h5cMbHatRzfKDQCUG6ocj2Vu2vGShijbR6XBYzOQ7Qp-PLaa2BQ5lmZOCySBI2K8DzIG0-TiyLr3LkcNsd4c-qhd_NWTytzP3geVQ" alt /></p>
<h3 id="heading-3-crear-un-rol-media-convert-role">3- Crear un rol: media-convert-role</h3>
<p>Necesitamos crear un rol para nuestra función lambda, MediaConvert necesita tener acceso a S3, así como a API Gateway. Sin esta función, MediaConvert simplemente no se ejecutará cuando intente invocarlo desde Lambda.</p>
<p>Iremos al panel <strong>IAM</strong> y luego a <strong>Roles</strong>, haremos clic en <strong>Crear ro</strong>l</p>
<p><img src="https://lh4.googleusercontent.com/x7r5pDRrkeOR0OH7ygA_fkd_RzIAlWNquUgLcI5v4RRsyQc2u5gR62ipvQaNTw-AjgnH3J946y7hScX5u_wj2MHLAFHpwFMEjUvXdYY7l3b6jthPK1QNYI5gvB4ETo7Iv8Fipn8yQdj6j22QsqBvAtD23nOg2fXfDFd-Vj3hhEGRIdN79kRW43f0mFOiFg" alt /></p>
<p>Seleccionamos AWS Service y luego en el select buscamos <strong>MediaConvert</strong>, clic en el botón <strong>Siguiente</strong></p>
<p><img src="https://lh4.googleusercontent.com/xtbqNXI0cDhhACRmg3kEvEIPksxXnahZpilfK9NMnEiUEdGlMRmVTi0VhemuL63FKnCee49zreNDsc7p1JinK_P66gx9MbH4wYn7V4nsZ5hDTfI0C_qt-AaboAxjU30AfDjo7LW78jVRTJkX81hpLVkIinZ1r2kYOl5D0oawF_xrVUHjw_rPUeIBQsBt7Q" alt /></p>
<p>AWS ya ha predefinido qué políticas necesita para este rol.</p>
<p>Elegimos <strong>Siguiente</strong></p>
<p>Establecemos el nombre</p>
<p>Asigne a su función el nombre <em>media-convert-role</em> y luego haga clic en <strong>Crear rol</strong>.</p>
<p><img src="https://lh4.googleusercontent.com/Q8iJQOlski9lzPCI_eQsxLqMshY820IKmZznZLmUFIgt9igRDZ_RIsMv_M4W1PzhmncdBC_o5wKtNZqJq4nL9A8H3IqSC5TAU39krgR2svDAnU9rCVDHIpnHD3nRvFIWUJDJeMxFyID5ZX2dHEZCLcYfZ4wPvTAuk_UwN8B_1EqTeVIZ_HBYLJb_4KTw9g" alt /></p>
<p>Necesitaremos el ARN del rol para una variable de entorno de nuestra función lambda.</p>
<p><img src="https://lh4.googleusercontent.com/SoPqPCWa6bCzuJTdCQYuT9xIeRtmUtk6X2ZSjZeItWNIYo13SM9OwKYUGF-fEq1mao2q5xBALnBMqW9zT-FI29NXJ5tBfz_DSBcsqDwOwXtcKg1cXVeCTS6GRfCiw59QRxfIGqu-DSix_G80wN-GrQtu9F3zBaQuHtRY6NIsRvenJPAD-2T-vYyHGze8lg" alt /></p>
<h3 id="heading-4-bucket-de-carga-de-videos-a-procesar">4 - Bucket de carga de videos a procesar</h3>
<p>Desde AWS Application Composer tenemos el primer bucket que es donde se cargaran los videos a procesar, el nombre de este bucket por defecto es el nombre de nuestra pila o stack junto con el número de nuestra cuenta de AWS:</p>
<p><code>BucketName: !Sub ${AWS::StackName}-bucket-${AWS::AccountId}</code></p>
<p>Lo podemos encontrar en la pestaña Template o bien desde nuestras fuentes en template.yaml  y buscar dentro de recursos a nuestro Bucket, podemos cambiarlo a otro nombre de nuestra preferencia.</p>
<p><img src="https://lh6.googleusercontent.com/-DduNt9BfRKJhkymkI9PLAf-kDHK14p6H8CLXJck6gr9I_3arLGKRd70d24fOxUoG1xT8FtK1e2F8Qwl_-4vdMgq-iXGe1yJhmg1T5IR6ZO_bixlpu-ZcCmyeAsP39e92qZ4RB5MGb11fW7Ol8T5H8-iKbKWmCTGEzahsvfZbKbPDuOqNRfn76pB6RuqeA" alt /></p>
<h3 id="heading-5-nuestra-cola-sqs">5- Nuestra cola SQS</h3>
<p>Cada vez que un video se cargue al bucket S3 definido en el paso 4, este evento es enviado a una cola SQS que se creará cuando despleguemos nuestro proyecto.</p>
<h3 id="heading-6-la-funcion-lambda">6- La función Lambda</h3>
<p>En el caso de nuestra función Lambda podemos indicar varios parámetros dentro de AWS Application Composer, seleccionando el elemento y luego la opción <strong><em>Details</em></strong> que mostrará más opciones en el lateral derecho de la pantalla</p>
<p><img src="https://lh5.googleusercontent.com/g1uP_Xhry9X8hivI8jt45fzPXckLDDsUgZO4UQfJobuzkEbBctAe30oOvWdcCKkLTK-tb_mDwkpYJuo_c4uj0ese_mZWixkfkvtFSOH1tviJbOH5VWgzauA7bS4Y-ExiX_-DJ04UkgBCpnTybwvDK1RLslP20JqzBnLemv0XnfUmOQmy5A-KuqMymfitsQ" alt /></p>
<p>Podemos especificar el runtime de nuestra Lambda, así como la ubicación del código de nuestra función (<strong><em>src/Function</em></strong>) y el método que se ejecuta cuando nuestra función es invocada (<code>index.handler</code>)</p>
<p><img src="https://lh6.googleusercontent.com/5Gw5CHrk5ud_DZ90WfUTPru-MesZe2aGGuMpBjSdXxTHSvhPg_KqZYsNUR5Lb7ntmdDJ7wFI3Bzhm24vp7KA5NVzNGIpYSVk_KYOv6h3YBjuADkaB2MLeT5vZvJmn0pJEGlRYS-Mgpba-3gRtd6zB4e1wMjTAS3EDc46pNgSquhM1G-KLCv6iFFv9emKqw" alt /></p>
<p>También podemos especificar otros valores desde esta pantalla, como es el caso de las políticas de permisos:</p>
<p><code>Version: '2012-10-17'</code></p>
<p><code>Statement:</code></p>
<p><code>- Effect: Allow</code></p>
<p><code>Action:</code></p>
<p><code>- iam:GetRole</code></p>
<p><code>- iam:PassRole</code></p>
<p><code>- mediaconvert:*</code></p>
<p><code>Resource: arn:aws:iam::619747668685:role/media-convert-role</code></p>
<p><img src="https://lh6.googleusercontent.com/EkEQ3OJ7PkkcdVQBQ923agLbtfzGn1X7dYnC89qlU9n0aAkrFbebJwJ6KzJyi0wgRgMc1RcNZZiNgD1ESMSNPqLLRfcnUtEeAMKFophUGeS9EJLcAbbb1msKU5JH0jrI3BvDdlx1awxtYxEe4C353xqJ6dhMoVggEVW6ySFPtM1k-D6oUZxbFK8AawceCA" alt /></p>
<p>Y también las variables de entorno que necesitamos especificar:</p>
<ul>
<li><p><code>MEDIA_ENDPOINT: el endpoint de mediaConvert</code></p>
</li>
<li><p><code>MEDIA_ROLE: el ARN del rol previamente creado</code></p>
</li>
<li><p><code>TRANSCODED_VIDEO_BUCKET:  el nombre de nuestro bucket de salida donde almacenaremos los videos procesador por MediaConvert</code></p>
</li>
</ul>
<p><img src="https://lh3.googleusercontent.com/SEjgH4nQaLaRGOc3Si_MB0zO02Sp3X-xRqzSBjQcss0gRbho6EUKN9YBO_bm3SQYrmcE0fPuj6Ym1zsGjF4h7HlYpyhbHeh2uqfsT72qRTzLX8yl4Rfpo3jYv18h-eOVv5s6geO0YNpc0o2FUKX3DYHkhz7r63ypkdaJnuy1btqjel04mdl5JvSSCC2epA" alt /></p>
<p>Todas las modificaciones que hagamos desde AWS Application Composer las veremos reflejadas en nuestro archivo local <code>template.yaml</code></p>
<p><img src="https://lh3.googleusercontent.com/YTjRENP8B_WILBZVs1Cf-DVnq1aBCrLEdxm_WLX7yCEBx5wWMVwDRvjk5PZZaByroAEojLT7DbaZ9vvX1b3BQ5B4LOSgcwJoFnDOG-nVPqEmmbXMl4ZY22EXcv13z36VJ7iv4I5MM2gMMUBH41-ybzuURf-HjyfqsqReJ0yMQDErxzhutl9_2C1xuvwkMQ" alt /></p>
<p>También debemos definir nuestro rol para la función lambda: <code>aws-sam-lambda-role</code></p>
<p><img src="https://lh4.googleusercontent.com/IuMQTLjUSrK6FFwmux9Q2REmqd6IASRze1MlOwy_zIHB3WpmGXQVn3lghzb0wLMwfw4O2Gw5KbSv74aSXwV28Y26yym3xZad784zcSda_OCrD05dgm5jV-tsfaOF4uuUGkk2KtU1IvfZUkMaDfHLlI71VVAanyckhVJIszRBPLjnvcxdK3YjlNv6Y5qaFA" alt /></p>
<p>El cual haremos referencia  en nuestro archivo local <code>template.yaml</code></p>
<p><img src="https://lh6.googleusercontent.com/CCGib4AbaA0aIy_nVXfu2K7vcbjunPNA_3ZBz2oYeJNXUNLfYs3fg6swkVtGGDn4Nceqe4TRXNMAOlCQNsqMga0GJ22Aj1pnZTCaBEFszdpbCoTObJ9g49cS9DL9H-KNLRYgWB1RXDTab7SHV_v5IKbcwo-8gj-pF1ZXjohVHU5bzja6wmBeDnLg0mKAgw" alt /></p>
<p>El código fuente de la función lambda es:</p>
<pre><code class="lang-javascript"><span class="hljs-meta">'use strict'</span>;

<span class="hljs-keyword">const</span> AWS = <span class="hljs-built_in">require</span>(<span class="hljs-string">'aws-sdk'</span>)

<span class="hljs-comment">// Obtiene el valor de la variable de entorno MEDIA_ENDPOINT que está configurada en template.yml</span>
<span class="hljs-keyword">const</span> mediaConvert = <span class="hljs-keyword">new</span> AWS.MediaConvert({
    <span class="hljs-attr">endpoint</span>: process.env.MEDIA_ENDPOINT
});
<span class="hljs-comment">// Obtiene el nombre del bucket donde se enviaran los videos procesados de la variable de entorno TRANSCODED_VIDEO_BUCKET que está configurada en template.yml</span>
<span class="hljs-keyword">const</span> outputBucketName = process.env.TRANSCODED_VIDEO_BUCKET;

<span class="hljs-built_in">exports</span>.handler = <span class="hljs-keyword">async</span> (event) =&gt; {

    <span class="hljs-keyword">const</span> s3Event = <span class="hljs-built_in">JSON</span>.parse(event.Records[<span class="hljs-number">0</span>].body)

    <span class="hljs-keyword">try</span> {
        <span class="hljs-keyword">const</span> key = s3Event.Records[<span class="hljs-number">0</span>].s3.object.key;
        <span class="hljs-keyword">const</span> sourceKey = <span class="hljs-built_in">decodeURIComponent</span>(key.replace(<span class="hljs-regexp">/\+/g</span>, <span class="hljs-string">' '</span>));
        <span class="hljs-keyword">const</span> outputKey = sourceKey.split(<span class="hljs-string">'.'</span>)[<span class="hljs-number">0</span>];

        <span class="hljs-comment">// Establece la ubicación del video de entrada para la definición de trabajo de MediaConvert</span>
        <span class="hljs-keyword">const</span> input = <span class="hljs-string">'s3://'</span> + s3Event.Records[<span class="hljs-number">0</span>].s3.bucket.name + <span class="hljs-string">'/'</span> + key;

        <span class="hljs-comment">// Create S3 service object</span>
        <span class="hljs-keyword">const</span> outputBucket = <span class="hljs-keyword">new</span> AWS.S3({<span class="hljs-attr">apiVersion</span>: <span class="hljs-string">'2006-03-01'</span>});

        <span class="hljs-comment">// Create the parameters for calling createBucket</span>
        <span class="hljs-keyword">var</span> bucketParams = {
          <span class="hljs-attr">Bucket</span> : outputBucketName
        };

        <span class="hljs-comment">// call S3 to create the bucket</span>
        outputBucket.createBucket(bucketParams, <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">err, data</span>) </span>{
          <span class="hljs-keyword">if</span> (err) {
            <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"Error"</span>, err);
          } <span class="hljs-keyword">else</span> {
            <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"Success"</span>, data.Location);
          }
        });

        <span class="hljs-comment">// Establece el bucket de salida para los nuevos archivos de video</span>
        <span class="hljs-keyword">const</span> output = <span class="hljs-string">'s3://'</span> + outputBucketName + <span class="hljs-string">'/'</span> + outputKey + <span class="hljs-string">'/'</span>;


        <span class="hljs-keyword">const</span> job = {
          <span class="hljs-comment">//  Obtiene el ARN del rol MediaConvert que se especifica en template.yml</span>
            <span class="hljs-string">"Role"</span>: process.env.MEDIA_ROLE,
            <span class="hljs-string">"Settings"</span>: {
                <span class="hljs-string">"Inputs"</span>: [{
                    <span class="hljs-string">"FileInput"</span>: input,
                    <span class="hljs-comment">// Especifica el selector de audio para la definición de trabajo de MediaConvert. De manera predeterminada, nombrará una sola pista de audio en el video.</span>
                    <span class="hljs-string">"AudioSelectors"</span>: {
                        <span class="hljs-string">"Audio Selector 1"</span>: {
                            <span class="hljs-string">"SelectorType"</span>: <span class="hljs-string">"TRACK"</span>,
                            <span class="hljs-string">"Tracks"</span>: [<span class="hljs-number">1</span>]
                        }
                    }
                }],
                <span class="hljs-string">"OutputGroups"</span>: [{
                    <span class="hljs-string">"Name"</span>: <span class="hljs-string">"File Group"</span>,
                    <span class="hljs-string">"Outputs"</span>: [{
                        <span class="hljs-string">"Preset"</span>: <span class="hljs-string">"System-Generic_Hd_Mp4_Avc_Aac_16x9_1920x1080p_24Hz_6Mbps"</span>,
                        <span class="hljs-string">"Extension"</span>: <span class="hljs-string">"mp4"</span>,
                        <span class="hljs-string">"NameModifier"</span>: <span class="hljs-string">"_16x9_1920x1080p_24Hz_6Mbps"</span>
                    }, {
                        <span class="hljs-string">"Preset"</span>: <span class="hljs-string">"System-Generic_Hd_Mp4_Avc_Aac_16x9_1280x720p_24Hz_4.5Mbps"</span>,
                        <span class="hljs-string">"Extension"</span>: <span class="hljs-string">"mp4"</span>,
                        <span class="hljs-string">"NameModifier"</span>: <span class="hljs-string">"_16x9_1280x720p_24Hz_4.5Mbps"</span>
                    }, {
                        <span class="hljs-string">"Preset"</span>: <span class="hljs-string">"System-Generic_Sd_Mp4_Avc_Aac_4x3_640x480p_24Hz_1.5Mbps"</span>,
                        <span class="hljs-string">"Extension"</span>: <span class="hljs-string">"mp4"</span>,
                        <span class="hljs-string">"NameModifier"</span>: <span class="hljs-string">"_4x3_640x480p_24Hz_1.5Mbps"</span>
                    }],
                    <span class="hljs-string">"OutputGroupSettings"</span>: {
                        <span class="hljs-string">"Type"</span>: <span class="hljs-string">"FILE_GROUP_SETTINGS"</span>,
                        <span class="hljs-string">"FileGroupSettings"</span>: {
                            <span class="hljs-string">"Destination"</span>: output
                        }
                    }
                }]
            }
        };

        <span class="hljs-keyword">const</span> mediaConvertResult = <span class="hljs-keyword">await</span> mediaConvert.createJob(job).promise();
        <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'mediaConvertResult '</span> , mediaConvertResult);

    } <span class="hljs-keyword">catch</span> (error) {
        <span class="hljs-built_in">console</span>.error(error);
    }
};
</code></pre>
<p>Nuestra función lambda utiliza AWS SDK por lo que necesitamos agregar dicha dependencia dentro de nuestro <code>package.json.</code></p>
<pre><code class="lang-json">{
  <span class="hljs-attr">"name"</span>: <span class="hljs-string">"function"</span>,
  <span class="hljs-attr">"version"</span>: <span class="hljs-string">"1.0.0"</span>,
  <span class="hljs-attr">"devDependencies"</span>: {
    <span class="hljs-attr">"aws-sdk"</span>: <span class="hljs-string">"^2.1270.0"</span>
  }
}
</code></pre>
<p>Y luego de ello ejecutar <code>npm i</code>  dentro de la carpeta donde su ubica este archivo  <strong><em>src/Function/</em></strong>  y debemos agregar unas líneas a nuestro <code>template.yaml.</code></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1673227134706/4cf134c8-9053-491e-ab47-901ae0650eb4.png" alt class="image--center mx-auto" /></p>
<p>Quedando finalmente así:</p>
<pre><code class="lang-yaml"><span class="hljs-attr">Resources:</span>
  <span class="hljs-attr">Bucket:</span>
    <span class="hljs-attr">Type:</span> <span class="hljs-string">AWS::S3::Bucket</span>
    <span class="hljs-attr">Properties:</span>
      <span class="hljs-attr">BucketName:</span> <span class="hljs-type">!Sub</span> <span class="hljs-string">${AWS::StackName}-alfalfita-cloud-bucket-${AWS::AccountId}</span>
      <span class="hljs-attr">BucketEncryption:</span>
        <span class="hljs-attr">ServerSideEncryptionConfiguration:</span>
          <span class="hljs-bullet">-</span> <span class="hljs-attr">ServerSideEncryptionByDefault:</span>
              <span class="hljs-attr">SSEAlgorithm:</span> <span class="hljs-string">aws:kms</span>
              <span class="hljs-attr">KMSMasterKeyID:</span> <span class="hljs-string">alias/aws/s3</span>
      <span class="hljs-attr">PublicAccessBlockConfiguration:</span>
        <span class="hljs-attr">IgnorePublicAcls:</span> <span class="hljs-literal">true</span>
        <span class="hljs-attr">RestrictPublicBuckets:</span> <span class="hljs-literal">true</span>
      <span class="hljs-attr">NotificationConfiguration:</span>
        <span class="hljs-attr">QueueConfigurations:</span>
          <span class="hljs-bullet">-</span> <span class="hljs-attr">Event:</span> <span class="hljs-string">s3:ObjectCreated:*</span>
            <span class="hljs-attr">Queue:</span> <span class="hljs-type">!GetAtt</span> <span class="hljs-string">Queue.Arn</span>
          <span class="hljs-bullet">-</span> <span class="hljs-attr">Event:</span> <span class="hljs-string">s3:ObjectRemoved:*</span>
            <span class="hljs-attr">Queue:</span> <span class="hljs-type">!GetAtt</span> <span class="hljs-string">Queue.Arn</span>
    <span class="hljs-attr">DependsOn:</span>
      <span class="hljs-bullet">-</span> <span class="hljs-string">BucketToQueuePermission</span>
  <span class="hljs-attr">BucketBucketPolicy:</span>
    <span class="hljs-attr">Type:</span> <span class="hljs-string">AWS::S3::BucketPolicy</span>
    <span class="hljs-attr">Properties:</span>
      <span class="hljs-attr">Bucket:</span> <span class="hljs-type">!Ref</span> <span class="hljs-string">Bucket</span>
      <span class="hljs-attr">PolicyDocument:</span>
        <span class="hljs-attr">Id:</span> <span class="hljs-string">RequireEncryptionInTransit</span>
        <span class="hljs-attr">Version:</span> <span class="hljs-string">'2012-10-17'</span>
        <span class="hljs-attr">Statement:</span>
          <span class="hljs-bullet">-</span> <span class="hljs-attr">Principal:</span> <span class="hljs-string">'*'</span>
            <span class="hljs-attr">Action:</span> <span class="hljs-string">'*'</span>
            <span class="hljs-attr">Effect:</span> <span class="hljs-string">Deny</span>
            <span class="hljs-attr">Resource:</span>
              <span class="hljs-bullet">-</span> <span class="hljs-type">!GetAtt</span> <span class="hljs-string">Bucket.Arn</span>
              <span class="hljs-bullet">-</span> <span class="hljs-type">!Sub</span> <span class="hljs-string">${Bucket.Arn}/*</span>
            <span class="hljs-attr">Condition:</span>
              <span class="hljs-attr">Bool:</span>
                <span class="hljs-attr">aws:SecureTransport:</span> <span class="hljs-string">'false'</span>
  <span class="hljs-attr">Queue:</span>
    <span class="hljs-attr">Type:</span> <span class="hljs-string">AWS::SQS::Queue</span>
  <span class="hljs-attr">BucketToQueuePermission:</span>
    <span class="hljs-attr">Type:</span> <span class="hljs-string">AWS::SQS::QueuePolicy</span>
    <span class="hljs-attr">Properties:</span>
      <span class="hljs-attr">PolicyDocument:</span>
        <span class="hljs-attr">Version:</span> <span class="hljs-string">'2012-10-17'</span>
        <span class="hljs-attr">Statement:</span>
          <span class="hljs-bullet">-</span> <span class="hljs-attr">Effect:</span> <span class="hljs-string">Allow</span>
            <span class="hljs-attr">Principal:</span>
              <span class="hljs-attr">Service:</span> <span class="hljs-string">s3.amazonaws.com</span>
            <span class="hljs-attr">Action:</span> <span class="hljs-string">sqs:SendMessage</span>
            <span class="hljs-attr">Resource:</span> <span class="hljs-type">!GetAtt</span> <span class="hljs-string">Queue.Arn</span>
            <span class="hljs-attr">Condition:</span>
              <span class="hljs-attr">ArnEquals:</span>
                <span class="hljs-attr">aws:SourceArn:</span> <span class="hljs-type">!Sub</span> <span class="hljs-string">arn:${AWS::Partition}:s3:::${AWS::StackName}-alfalfita-cloud-bucket-${AWS::AccountId}</span>
      <span class="hljs-attr">Queues:</span>
        <span class="hljs-bullet">-</span> <span class="hljs-type">!Ref</span> <span class="hljs-string">Queue</span>
  <span class="hljs-attr">Function:</span>
    <span class="hljs-attr">Type:</span> <span class="hljs-string">AWS::Serverless::Function</span>
    <span class="hljs-attr">Properties:</span>
      <span class="hljs-attr">Description:</span> <span class="hljs-type">!Sub</span>
        <span class="hljs-bullet">-</span> <span class="hljs-string">Stack</span> <span class="hljs-string">${AWS::StackName}</span> <span class="hljs-string">Function</span> <span class="hljs-string">${ResourceName}</span>
        <span class="hljs-bullet">-</span> <span class="hljs-attr">ResourceName:</span> <span class="hljs-string">Function</span>
      <span class="hljs-attr">CodeUri:</span> <span class="hljs-string">src/Function</span>
      <span class="hljs-attr">Handler:</span> <span class="hljs-string">index.handler</span>
      <span class="hljs-attr">Role:</span> <span class="hljs-string">arn:aws:iam::619747668685:role/aws-sam-lambda-role</span>
      <span class="hljs-attr">Runtime:</span> <span class="hljs-string">nodejs18.x</span>
      <span class="hljs-attr">MemorySize:</span> <span class="hljs-number">3008</span>
      <span class="hljs-attr">Timeout:</span> <span class="hljs-number">30</span>
      <span class="hljs-attr">Tracing:</span> <span class="hljs-string">Active</span>
      <span class="hljs-attr">Events:</span>
        <span class="hljs-attr">Queue:</span>
          <span class="hljs-attr">Type:</span> <span class="hljs-string">SQS</span>
          <span class="hljs-attr">Properties:</span>
            <span class="hljs-attr">Queue:</span> <span class="hljs-type">!GetAtt</span> <span class="hljs-string">Queue.Arn</span>
            <span class="hljs-attr">BatchSize:</span> <span class="hljs-number">1</span>
      <span class="hljs-attr">Environment:</span>
        <span class="hljs-attr">Variables:</span>
          <span class="hljs-attr">MEDIA_ENDPOINT:</span> <span class="hljs-string">https://lxlxpswfb.mediaconvert.us-east-1.amazonaws.com</span>
          <span class="hljs-attr">MEDIA_ROLE:</span> <span class="hljs-string">arn:aws:iam::619747668685:role/media-convert-role</span>
          <span class="hljs-attr">TRANSCODED_VIDEO_BUCKET:</span> <span class="hljs-string">serverless-video-transcoded-alfalfita-cloud-06122022</span>
      <span class="hljs-attr">Policies:</span>
        <span class="hljs-attr">Version:</span> <span class="hljs-string">'2012-10-17'</span>
        <span class="hljs-attr">Statement:</span>
          <span class="hljs-bullet">-</span> <span class="hljs-attr">Effect:</span> <span class="hljs-string">Allow</span>
            <span class="hljs-attr">Action:</span>
              <span class="hljs-bullet">-</span> <span class="hljs-string">iam:GetRole</span>
              <span class="hljs-bullet">-</span> <span class="hljs-string">iam:PassRole</span>
              <span class="hljs-bullet">-</span> <span class="hljs-string">mediaconvert:*</span>
            <span class="hljs-attr">Resource:</span> <span class="hljs-string">arn:aws:iam::619747668685:role/media-convert-role</span>
    <span class="hljs-attr">Metadata:</span>
      <span class="hljs-attr">BuildProperties:</span>
        <span class="hljs-attr">UseNpmCi:</span> <span class="hljs-literal">true</span>
  <span class="hljs-attr">FunctionLogGroup:</span>
    <span class="hljs-attr">Type:</span> <span class="hljs-string">AWS::Logs::LogGroup</span>
    <span class="hljs-attr">DeletionPolicy:</span> <span class="hljs-string">Retain</span>
    <span class="hljs-attr">Properties:</span>
      <span class="hljs-attr">LogGroupName:</span> <span class="hljs-type">!Sub</span> <span class="hljs-string">/aws/lambda/${Function}</span>
<span class="hljs-attr">Transform:</span> <span class="hljs-string">AWS::Serverless-2016-10-31</span>
</code></pre>
<p><img src="https://lh6.googleusercontent.com/7BVK2-bF10-6imZ_PkJXtKlffk19Py-4pIQ0Fvw9WiuOD6dV0Lr4e7Hiwshb0_BwmUuB_OapiA-WyOLfIuE3an1B1vAp1jbuXXIflKPppLAT1gxOSoD2n4ZGZ2B8FPvr8CFJzGLk79Z_MnK06dNzSW_QNsxRCGX3yrW0iUYadYGyCtOFJSoQuSvAH1i6Ng" alt /></p>
<p>Para más información:</p>
<p><a target="_blank" href="https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-sam-cli-using-build.html">https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-sam-cli-using-build.html</a></p>
<h3 id="heading-6-instalar-aws-sam-cli">6 - Instalar AWS SAM CLI</h3>
<p>Para prepararnos para desplegar nuestra aplicación en la nube, necesitamos un servicio compatible con Cloudformation para la implementación, en este caso AWS SAM, la  documentación para la instalación la podemos encontrar en:</p>
<p><a target="_blank" href="https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/install-sam-cli.html">https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/install-sam-cli.html</a></p>
<p>Una vez instalado AWS SAM CLI podemos usarlo desde la terminal, con los diversos comandos que proporciona</p>
<p><img src="https://lh3.googleusercontent.com/I1SoCL1wdpFl3Bq7TMDTlDpqkJLWOJNs6Pokkqhj9nrrEfhMv3gUELGwv2n0y8MmXmtuevZ0wmRa18E_daSNtge_phMLbTDX739Fqvg-UBiCmbSdcfBltDE7vpUrNulF2aePhqqNHtaG1DU3aBoaQF8vlA_p7oNLrkMxF6pWyDZifF7m-qsb0fF8DavphA" alt /></p>
<p>Ejecutamos primero <code>sam-build</code></p>
<p><img src="https://lh4.googleusercontent.com/vL7Q4UUNc0zBLec5gCuiHCesdFAWmdT1uj1CIte9NK58XtQCw6bU6fyoc_b03lF-dKs4hOgOvOPOz1DalHJ-BD6On1IaTgBcDyKR6C6LN9IurrAW-XI0vcgLyy-zcpf8xZ0kgLXSrzkngJUJzn7SIa9B7MW4rodcsUm1ZvoooHDIRqZSCnoqYXmf6FPSlw" alt /></p>
<p>Y luego preparamos el despliegue guiado que nos permitirá establecer ciertos valores:</p>
<p><img src="https://lh3.googleusercontent.com/rgFzh2SvLoRwCMr4bjPMcGLeTMTrqfVFjfiU__3SdzeNXIso1bvm6u5p0TleA7ryHJ9-a4NzJAvPpUcjC9Yq43W5eD9TdpESJZQA_mauG9ktV16-HKr6-71O4F55A0CCLPwmfikMcAyiiJnywgv0StUpfM--3si-1GA1vzSwJAhmbGMbp1_33kOBCuq63w" alt /></p>
<p><img src="https://lh3.googleusercontent.com/nxG-WblI1szfo4XHjJRkSvyvWeqY7u3553i5i5ov_HL5SinadgOlKK3twe11tipLqXByIG_1nhuDmr0Z0UWCAwY1dZA2HbK6jyspSS-wU6_81RRHJXuZEG_lKd6EcCvBm-cCwX5hh0-W6RJr20t7d3cPS_pkRKicEIldhl0WQml-WPN-4GeI5N0SkXDKTQ" alt /></p>
<p>Confirmamos los cambios, y veremos como los recursos se irán creando:</p>
<p><img src="https://lh6.googleusercontent.com/qWyrKvts2nn_rA9LOln6pfIN_jRz1NSyQ79Y8XGfoQCUVs_AXfEHMSlg6Xv60BGFoW_odVmDV4HJ6mR74U4OzwfAxv9cBKZVYkMwr_Lm_MrIew81OkSIDEiEjds7Sl-uCKsxUnABFHIRMsUZly26JjenBQ2lcnfyIekSDEYiJ64xEP2OFNmWZY875xkEbw" alt /></p>
<p>Confirmamos que la pila existe en el panel de CloudFormation</p>
<p><img src="https://lh5.googleusercontent.com/_No5kzQKM9ipxv877AzcHfBVI0Adf1Oy3ZPFyL9YSZhK6O-CbpGIEtZ_chz-yvG20ihuyvoDEAk7SHosAiggjDKOQBWDnRs8nR0IOT_tkM3szI07jWfeO74wozrGrO0B-LE3jPNK-Qm9VaeUZtkevoHT7VwB06rWm9kCq5PSBFM5j-HJ6oFB-ngn37FMLQ" alt /></p>
<p>Ahora probamos nuestra función, subiendo un video al bucket S3</p>
<p><img src="https://lh4.googleusercontent.com/fbu7ipj_WAyHTy_WtbvaNgEpWoqGtY3pfgIWkSlNuYetMVK-tK5MLTzkez30PwkixGDc75nRR3ey-XPUXx4jUEC23reXqAjcw9A1TbFrKPbXw9OXyOkuLUNd12zbCYUWPkLGTZJZYdUs1HVWSsRREZlw3YT6nqqWPzKsnxfrlb_cVl0YpN7ynmr7bZLvvg" alt /></p>
<p><img src="https://lh5.googleusercontent.com/8Y25wnjJKOrBir91O2CSDNUmk0ASVpkxqnJu6fPC17WI2lBmIGC2Gl1ntc2ryMuUanHvwHeTcSXEMxEVw1ymChi5BsX1cDDnNa_LpuaSYUM2wBre5OGiSX1JmS4Z2Il9AsduLhty-gHmEEOtZ9-xMJuKqMs6NzvvE39dXQGZvNghsB3QkvGxcRfy6dGVhA" alt /></p>
<p>Veremos que tendremos un nuevo bucket donde encontraremos diversos formatos de nuestro video original</p>
<p><img src="https://lh4.googleusercontent.com/PIHpEhP8nBTipXt9TVlCLiYRsyWGOFST3A4NBTVPpTxLWAck_o_j4Ije3codvDSYJEeXtxefX-TbdHJVqao_WZjwPbcuGyLUqmQrt4RHsUj7mswRTi8-G4-0VZ4IXSdw-nMOzyPu38rZBm5JytHXWzpds2qY2dPuwH3g50cwWgFDApSxR4ToNDxpGWLpWw" alt /></p>
<p><strong>AWS Elemental MediaConvert:</strong> <a target="_blank" href="https://docs.aws.amazon.com/mediaconvert/index.html">https://docs.aws.amazon.com/mediaconvert/index.html</a></p>
<p>El repositorio con la solución lo encuentras en:</p>
<p><a target="_blank" href="https://github.com/alfalfita/decoder-video-with-sam-and-lambda">https://github.com/alfalfita/decoder-video-with-sam-and-lambda</a></p>
]]></content:encoded></item><item><title><![CDATA[Sitio web sin servidor con AWS SAM]]></title><description><![CDATA[AWS tiene una amplia variedad de servicios serverless. En esta ocasión estaremos creando un sitio web serverless (sin servidor) con ReactJS. La tecnología serverless ha permitido que nos concentremos en el valor comercial de nuestro negocio, en lugar...]]></description><link>https://blog.alfalfita.cloud/sitio-web-sin-servidor-con-aws-sam</link><guid isPermaLink="true">https://blog.alfalfita.cloud/sitio-web-sin-servidor-con-aws-sam</guid><category><![CDATA[aws sam]]></category><category><![CDATA[serverless]]></category><category><![CDATA[Amazon S3]]></category><category><![CDATA[aws lambda]]></category><category><![CDATA[AWS]]></category><dc:creator><![CDATA[Diana Alfaro]]></dc:creator><pubDate>Sun, 08 Jan 2023 23:34:18 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1673393611511/b455c320-ea36-4c12-a0bc-f04278cfc657.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>AWS tiene una <a target="_blank" href="https://aws.amazon.com/es/serverless/">amplia variedad de servicios serverless</a>. En esta ocasión estaremos creando un sitio web serverless (sin servidor) con ReactJS. La tecnología serverless ha permitido que nos concentremos en el valor comercial de nuestro negocio, en lugar de preocuparnos por la administración de infraestructura, como el aprovisionamiento de capacidad y la aplicación de parches, dejando estas tareas en manos de AWS.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1673393242681/13a2bdbd-17f6-42d1-b491-4dd06210833f.png" alt class="image--center mx-auto" /></p>
<p>Para esta solución usaremos:</p>
<ul>
<li><p>ReactJS</p>
</li>
<li><p>Amazon S3</p>
</li>
<li><p>Amazon CloudFront</p>
</li>
<li><p>AWS Lambda</p>
</li>
<li><p>AWS CLI</p>
</li>
<li><p>SAM CLI</p>
</li>
</ul>
<p>Utilizaremos <a target="_blank" href="https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/install-sam-cli.html">SAM CLI</a> para construir nuestra aplicación a través de una plantilla de CloudFormation para crear los recursos necesarios en la nube y de esta manera tener también una plantilla que puede ser reutilizada en otros proyectos.</p>
<p>Empezaremos creando nuestro proyecto de ReactJS. Para ello necesitamos tener instalado  <a target="_blank" href="https://nodejs.org/en/">Node &gt;= 14.0.0 y npm &gt;= 5.6</a>.</p>
<p><a target="_blank" href="https://reactjs.org/docs/create-a-new-react-app.html">¿Cómo crear una aplicación con React?</a></p>
<p>Una vez creado nuestro proyecto en la raíz del mismo crearemos un archivo template.yaml que sera nuestro template de CloudFormation que desplegaremos usando SAM CLI.</p>
<p><a target="_blank" href="https://github.com/alfalfita/website-with-aws-sam/blob/main/template.yaml"><strong>CODIGO</strong></a></p>
<pre><code class="lang-yaml"><span class="hljs-attr">AWSTemplateFormatVersion:</span> <span class="hljs-string">'2010-09-09'</span>
<span class="hljs-attr">Transform:</span> <span class="hljs-string">AWS::Serverless-2016-10-31</span>
<span class="hljs-attr">Description:</span> <span class="hljs-string">&gt;
  Sitio web con AWS SAM
</span>
<span class="hljs-attr">Parameters:</span>
  <span class="hljs-attr">DomainName:</span>
    <span class="hljs-attr">Type:</span> <span class="hljs-string">String</span>
    <span class="hljs-attr">Description:</span> <span class="hljs-string">"Nombre de dominio"</span>
  <span class="hljs-attr">IndexDocument:</span>
    <span class="hljs-attr">Type:</span> <span class="hljs-string">String</span>
    <span class="hljs-attr">Description:</span> <span class="hljs-string">"Documento index"</span>
    <span class="hljs-attr">Default:</span> <span class="hljs-string">"index.html"</span>

<span class="hljs-attr">Resources:</span>
  <span class="hljs-attr">CloudFrontOriginAccessIdentity:</span>
    <span class="hljs-attr">Type:</span> <span class="hljs-string">'AWS::CloudFront::CloudFrontOriginAccessIdentity'</span>
    <span class="hljs-attr">Properties:</span>
      <span class="hljs-attr">CloudFrontOriginAccessIdentityConfig:</span>
        <span class="hljs-attr">Comment:</span> <span class="hljs-string">'Desplegando un sitio web con AWS SAM'</span>

  <span class="hljs-attr">S3Bucket:</span>
    <span class="hljs-attr">Type:</span> <span class="hljs-string">AWS::S3::Bucket</span>
    <span class="hljs-attr">Properties:</span>
      <span class="hljs-attr">BucketName:</span> <span class="hljs-type">!Ref</span> <span class="hljs-string">DomainName</span>

  <span class="hljs-attr">S3BucketPolicy:</span>
    <span class="hljs-attr">Type:</span> <span class="hljs-string">AWS::S3::BucketPolicy</span>
    <span class="hljs-attr">Properties:</span>
      <span class="hljs-attr">Bucket:</span> <span class="hljs-type">!Ref</span> <span class="hljs-string">S3Bucket</span>
      <span class="hljs-attr">PolicyDocument:</span>
        <span class="hljs-attr">Statement:</span>
          <span class="hljs-bullet">-</span> <span class="hljs-attr">Effect:</span> <span class="hljs-string">Allow</span>
            <span class="hljs-attr">Action:</span> <span class="hljs-string">'s3:GetObject'</span>
            <span class="hljs-attr">Resource:</span>
              <span class="hljs-bullet">-</span> <span class="hljs-type">!Sub</span> <span class="hljs-string">"arn:aws:s3:::${S3Bucket}/*"</span>
            <span class="hljs-attr">Principal:</span>
              <span class="hljs-attr">AWS:</span> <span class="hljs-type">!Sub</span> <span class="hljs-string">"arn:aws:iam::cloudfront:user/CloudFront Origin Access Identity ${CloudFrontOriginAccessIdentity}"</span>

  <span class="hljs-attr">CloudfrontDistribution:</span>
    <span class="hljs-attr">Type:</span> <span class="hljs-string">"AWS::CloudFront::Distribution"</span>
    <span class="hljs-attr">Properties:</span>
      <span class="hljs-attr">DistributionConfig:</span>
        <span class="hljs-attr">Comment:</span> <span class="hljs-string">"Distribucion de Cloudfront"</span>
        <span class="hljs-attr">DefaultRootObject:</span> <span class="hljs-string">"index.html"</span>
        <span class="hljs-attr">Enabled:</span> <span class="hljs-literal">true</span>
        <span class="hljs-attr">HttpVersion:</span> <span class="hljs-string">http2</span>
        <span class="hljs-attr">Origins:</span>
          <span class="hljs-bullet">-</span> <span class="hljs-attr">Id:</span> <span class="hljs-string">s3-website</span>
            <span class="hljs-attr">DomainName:</span> <span class="hljs-type">!Sub</span> <span class="hljs-string">"${S3Bucket}.s3.${AWS::Region}.amazonaws.com"</span>
            <span class="hljs-attr">S3OriginConfig:</span>
              <span class="hljs-attr">OriginAccessIdentity:</span>
                <span class="hljs-attr">Fn::Sub:</span> <span class="hljs-string">'origin-access-identity/cloudfront/${CloudFrontOriginAccessIdentity}'</span>
        <span class="hljs-attr">DefaultCacheBehavior:</span>
          <span class="hljs-attr">Compress:</span> <span class="hljs-string">'true'</span>
          <span class="hljs-attr">AllowedMethods:</span>
            <span class="hljs-bullet">-</span> <span class="hljs-string">GET</span>
            <span class="hljs-bullet">-</span> <span class="hljs-string">HEAD</span>
            <span class="hljs-bullet">-</span> <span class="hljs-string">OPTIONS</span>
          <span class="hljs-attr">ForwardedValues:</span>
            <span class="hljs-attr">QueryString:</span> <span class="hljs-literal">false</span>
          <span class="hljs-attr">TargetOriginId:</span> <span class="hljs-string">s3-website</span>
          <span class="hljs-attr">ViewerProtocolPolicy :</span> <span class="hljs-string">redirect-to-https</span>

<span class="hljs-attr">Outputs:</span>
  <span class="hljs-attr">BucketName:</span>
    <span class="hljs-attr">Description:</span> <span class="hljs-string">"Nombre del bucket"</span>
    <span class="hljs-attr">Value:</span> <span class="hljs-type">!Ref</span> <span class="hljs-string">S3Bucket</span>
  <span class="hljs-attr">CloudFrontDistribution:</span>
    <span class="hljs-attr">Description:</span> <span class="hljs-string">"ID de la distribucion de CloudFormation"</span>
    <span class="hljs-attr">Value:</span> <span class="hljs-type">!Ref</span> <span class="hljs-string">CloudfrontDistribution</span>
  <span class="hljs-attr">WebsiteUrl:</span>
    <span class="hljs-attr">Description:</span> <span class="hljs-string">"Sitio web"</span>
    <span class="hljs-attr">Value:</span> <span class="hljs-type">!Sub</span> <span class="hljs-string">"https://${DomainName}/"</span>
</code></pre>
<p>Esta plantilla nos permitirá crear los siguientes servicios:</p>
<ul>
<li><p><strong>CloudFrontOriginAccessIdentity</strong>: no necesitamos otorgar acceso al publico al bucket S3 directamente ni habilitar el alojamiento de sitios web usando una OriginAccessIdentity, en su lugar podemos conectar nuestro bucket S3 con CloudFront, la manera más segura para dirigir el acceso a los archivos del bucket a las solicitudes que llegan a través de CloudFront.</p>
<p>  Más información: <a target="_blank" href="https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/private-content-restricting-access-to-s3.html">https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/private-content-restricting-access-to-s3.html</a></p>
<p>  <a target="_blank" href="https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/quickref-cloudfront.html">https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/quickref-cloudfront.html</a></p>
</li>
<li><p><strong>S3Bucket</strong>: nuestro bucket de S3 donde subiremos nuestra carpeta build del proyecto.</p>
</li>
<li><p><strong>S3BucketPolicy</strong>: política que define quién puede acceder y qué tipo de operaciones se permiten en el bucket. Aquí restringimos con OriginAccessIdentity el acceso de lectura solo a CloudFront.</p>
</li>
<li><p><strong>CloudFrontDistribution</strong>:  distribución de CloudFront para indicar a CloudFront desde dónde desea enviar el contenido y los detalles acerca de cómo realizar un seguimiento y administrar la entrega de contenido con  baja latencia a nivel mundial.</p>
</li>
</ul>
<p><strong>Implementación de la solución</strong></p>
<ul>
<li><p>Primero necesitamos generar el build de nuestro proyecto ReactJS. Para ello ejecutamos el siguiente comando en la raíz del proyecto donde esta ubicado el archivo <em>package.json</em></p>
<p>  <code>npm run build</code></p>
</li>
<li><p>Esto generará una carpeta con el compilado de nuestra solución que subiremos luego a nuestro bucket S3 usando AWS CLI</p>
</li>
<li><p>Ahora necesitamos desplegar nuestra plantilla de CloudFormation para que se creen los recursos en nuestra cuenta de AWS en la nube</p>
</li>
<li><p>Para ello ejecutamos el siguiente comando en la raíz de nuestro proyecto donde tenemos el archivo <em>template.yaml</em></p>
<p>  <code>sam build</code></p>
<p>  <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1673393340014/6f62e172-239d-4716-b7ec-138090fc92d9.png" alt class="image--center mx-auto" /></p>
</li>
</ul>
<p>Luego para el despliegue, ejecutamos el siguiente comando y completamos la información solicitada:</p>
<p><code>sam deploy --guided</code></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1673393350747/6940aac5-db23-4d27-80a2-8968e12669fe.png" alt class="image--center mx-auto" /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1673393362004/0e4c0ec9-00fe-483b-bf67-cad6e73aba85.png" alt class="image--center mx-auto" /></p>
<p>Veremos que los recursos que definimos en nuestra plantilla se empezarán a crear. La distribución de CloudFront llevará al inicio algo de tiempo completar, una vez completada la implementación, tendrá un nombre de dominio generado por AWS con el formato <a target="_blank" href="http://d3ue2ep9txxx01.cloudfront.net">d3ue2ep9txxx01.cloudfront.net</a>  que usaremos para realizar nuestra solicitud al sitio web.</p>
<p>Ahora debemos subir el contenido de nuestra carpeta build del proyecto de ReactJS al bucket podemos usar el comando :</p>
<p><code>aws s3 sync ./build s3://my-bucket-with-oac</code></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1673393382238/2c8d56df-42e3-4a46-b947-6bd04f967918.png" alt class="image--center mx-auto" /></p>
<p>Una vez que se carguen los archivos, deberíamos poder ver en nombre de dominio de Cloudfront  <a target="_blank" href="https://d3ue2ep9txxx01.cloudfront.net/">nuestro sitio web</a></p>
<p><a target="_blank" href="https://d3ue2ep9txxx01.cloudfront.net/">https://d3ue2ep9txxx01.cloudfront.net/</a></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1673393389195/8493e216-ccf8-4702-b26e-2898814257ca.png" alt class="image--center mx-auto" /></p>
<p>Ahora nos queda pendiente la opción de invalidar la distribución de CloudFront (que veremos en otra entrada) cuando se detecten cambios en el bucket S3, para ello utilizaremos una función lambda que nos ayudará con ese trabajo.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1673393413185/e7bacaf8-dadf-4c43-a14d-89d2ebc32e1e.png" alt class="image--center mx-auto" /></p>
<p><strong>Nota:</strong></p>
<p>En ocasiones me sucedia, que al deployar los cambios estos no se veian reflejados. Por lo que tenia que ejecutar este comando para forzar la actualización</p>
<p><code>sam deploy --force-upload</code></p>
<p><a target="_blank" href="https://github.com/alfalfita/website-with-aws-sam">Enlace al repositorio github con las fuentes</a></p>
]]></content:encoded></item><item><title><![CDATA[Empezando la ruta hacia una nueva certificación]]></title><description><![CDATA[Este año he tenido la oportunidad de poder obtener 2 certificaciones de AWS: Cloud Practitioner y Solution Architect, esta ultima la obtuve antes que cambiara a la nueva versión (SAA-C03).


Ahora voy en busca de mi tercera certificación: Developer -...]]></description><link>https://blog.alfalfita.cloud/empezando-la-ruta-hacia-una-nueva-certificacion</link><guid isPermaLink="true">https://blog.alfalfita.cloud/empezando-la-ruta-hacia-una-nueva-certificacion</guid><category><![CDATA[Certification]]></category><category><![CDATA[AWS]]></category><category><![CDATA[Developer]]></category><category><![CDATA[Cloud]]></category><category><![CDATA[Cloud Computing]]></category><dc:creator><![CDATA[Diana Alfaro]]></dc:creator><pubDate>Wed, 28 Sep 2022 20:00:45 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1664395219541/lWbKcpsLP.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Este año he tenido la oportunidad de poder obtener 2 certificaciones de AWS: Cloud Practitioner y Solution Architect, esta ultima la obtuve antes que cambiara a la nueva versión (SAA-C03).</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1664393942242/8RnW6Gbbo.png" alt="image.png" class="image--center mx-auto" />
<img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1664393928272/zWD4vQQWx.png" alt="image.png" class="image--center mx-auto" /></p>
<p>Ahora voy en busca de mi tercera certificación: Developer - Associate, algunas compañeras me han comentado que tanto la certificación de arquitecto como la de developer tienen temas en común, que por ahí quizás primero pude haber tomado la de developer y luego la de arquitecto, pero en fin, supongo que el orden de los productos no altera el resultado. </p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1664394014211/_f1uBS7t3.png" alt="image.png" class="image--center mx-auto" /></p>
<p>Empezando esta nueva ruta de estudios, ya tengo algunos materiales/cursos que he ido adquiriendo (y que use para prepararme para las anteriores certificaciones) y quiero compartir con ustedes cuales son:</p>
<ul>
<li>Empezando con la guía del examen, que nos permitirá tener un abreboca de la certificación y conocer que es lo que nos van a evaluar y que porcentaje tiene cada tema</li>
</ul>
<p><a href="https://d1.awsstatic.com/es_ES/training-and-certification/docs-dev-associate/AWS-Certified-Developer-Associate_Exam-Guide.pdf"><strong>Guía del examen</strong></a></p>
<p>Luego tomo un par de cursos, en este punto (y muy a criterio de cada uno) suelo hacer apuntes, porque es muchísima la información que estamos por ver, muchísimos servicios y términos que probablemente sean nuevos, los apuntes nos ayudan a luego poder echar un vistazo rápido a ellos sin tener que irnos a buscar el video X en el minuto Z"Y. Ademas que cuando tomas apuntes refuerzas lo que aprendes, porque le das tu propia interpretación y puedes tomar nota de esos tips que siempre están presentes.</p>
<ul>
<li><p>El curso de Udemy de <a href="https://www.udemy.com/course/aws-certified-developer-associate-dva-c01/">Stephane Maarek</a> . Esta en inglés pero tienes opción de ponerle subtítulos, un curso bien estructurado, que combina los conceptos teóricos con la practica y adicional un conjunto de preguntas para evaluar lo que vas aprendiendo.</p>
</li>
<li><p>El curso de <a href="https://learn.cantrill.io/p/aws-certified-developer-associate">Adrian Cantrill</a> , un curso para poner en practica aplicando los conceptos a un ejemplo de la vida real, también refuerzo los temas del curso anterior y me ayuda a complementar mi estudio</p>
</li>
<li><p>El libro <a href="https://www.amazon.com/Certified-Developer-Official-Study-Guide/dp/1119508193/ref=sr_1_1?crid=1FHUGGF0DDLR8&amp;keywords=certified+Developer+-+Associate&amp;qid=1664394697&amp;sprefix=certified+developer+-+associate%2Caps%2C266&amp;sr=8-1">AWS Certified Developer Official Study Guide: Associate (DVA-C01) Exam</a>, a pesar que es del año 2019, nos ayuda a leer con mayor profundidad de los temas, algunas imágenes ya quedan desfasadas por el cambio de UI de la consola de AWS pero igual es un buen complemento.</p>
</li>
<li><p>El sitio web de <a href="https://explore.skillbuilder.aws/learn">Skillbuilder</a>, proporciona una gran cantidad de recursos entre videos, labs, juegos interactivos (<a href="https://explore.skillbuilder.aws/learn/course/external/view/elearning/7636/cloud-quest">Cloud Quest</a>) para reforzar aún más el conocimiento. Y por si fuera, si en tu caso la empresa para la que trabajas es Partner de AWS, podrás acceder a más materiales, inclusive a cursos en vivo que ayudarán a obtener la certificación. En ocasiones AWS lanza cursos de preparación para Partners de AWS para las certificaciones que suelen durar varias semanas y te van haciendo acompañamiento, enviando material y videos sugeridos para complementar tu formación.</p>
</li>
<li><p>El <a href="https://www.amazon.com/Certified-Developer-Associate-Training-Notes-ebook/dp/B08BR3VDT5/ref=sr_1_3?crid=1FHUGGF0DDLR8&amp;keywords=certified+Developer+-+Associate&amp;qid=1664394697&amp;sprefix=certified+developer+-+associate%2Caps%2C266&amp;sr=8-3">set de exámenes de Neal Davis</a> aquí me concentro en las preguntas que explican las respuestas, y busco leer tanto las respuestas buenas como malas, a la vez que me ayuda a identificar los temas que debo repasar.</p>
</li>
<li><p>El set de exámenes de <a href="https://portal.tutorialsdojo.com/courses/aws-certified-developer-associate-practice-exams/">Tutoriales Dojo</a> un set bastante completo. Suelo empezar con un test antes de iniciar con los cursos de teoría/practica. Esto me ayuda a ver mis resultados antes de mi preparación y luego al terminar los cursos (1 y 2) vuelvo a hacerlo para evaluar si mejore. Una vez que hago eso, procuro realizar 2 exámenes a la semana (dependiendo de cuanto tiempo me queda para presentar el examen puede ser mas)</p>
</li>
<li><p>El set de exámenes de <a href="https://www.whizlabs.com/aws-developer-associate/">Whizlasbs</a>, otro abanico de preguntas para complementar los test de Tutoriales Dojo.</p>
</li>
</ul>
<blockquote>
<p>Respecto a los exámenes de practica, no suelo repetirlos en un tiempo corto, pero si anoto los temas en los que veo que siempre fallo y también trato de identificar cuales son los servicios que mas preguntan, de esa lista de servicios me leo los FAQ's.</p>
</blockquote>
<p>El link de los FAQ's de los servicios de AWS suele tener este formato:</p>
<pre><code>https:<span class="hljs-comment">//aws.amazon.com/es/**nombreServicio**/faqs/</span>
</code></pre><p>Leerlos te ayuda a conocer mas sobre los servicios y algunos datos o características particulares que te pueden preguntar en el examen</p>
<blockquote>
<p>Una vez que termine con los cursos, el libro, las  FAQ's y he practicado varios exámenes de practica, debería poder lograr una puntuación mayor a 80% en todos los casos, si aún no lo alcanzo entonces debo detenerme ver en que estoy fallando y buscar mas información al respecto (que me despeje las dudas que tengo). Una vez que me alcance y supere el 80% en los exámenes de practica, estamos listos para presentar el examen de certificación. Si aún no lo obtengo y se acerca la fecha de examen que agende, entonces lo mejor será reprogramarlo <strong>hasta que me sienta segura</strong>.</p>
</blockquote>
<p>El día antes del examen, suelo practicar un par de exámenes y es todo, para el día del examen no reviso ningún material más para no sobrecargarme. Trato de descansar bien, y alimentarme bien para ir con muchas energías a presentar el examen.</p>
<p>Para conocer más sobre el examen de certificación, visite:
<a href="https://aws.amazon.com/es/certification/certified-developer-associate/">https://aws.amazon.com/es/certification/certified-developer-associate/</a></p>
]]></content:encoded></item><item><title><![CDATA[AWS Power Hour: Architecting]]></title><description><![CDATA[Aprenda a diseñar arquitecturas resilientes, de alto rendimiento, seguras y rentables en la nube de AWS. 
Si te estás preparando para el examen AWS Certified Solutions Architect - Associate (SAA-C03), o simplemente desea comprender mejor la arquitect...]]></description><link>https://blog.alfalfita.cloud/aws-power-hour-architecting</link><guid isPermaLink="true">https://blog.alfalfita.cloud/aws-power-hour-architecting</guid><category><![CDATA[AWSPowerHour]]></category><category><![CDATA[AWS]]></category><category><![CDATA[Cloud]]></category><category><![CDATA[Twitch]]></category><category><![CDATA[solutionarchitect]]></category><dc:creator><![CDATA[Diana Alfaro]]></dc:creator><pubDate>Tue, 20 Sep 2022 20:24:26 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1664395640814/kJgL11tQZ.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<blockquote>
<p>Aprenda a diseñar arquitecturas resilientes, de alto rendimiento, seguras y rentables en la nube de AWS. </p>
<p>Si te estás preparando para el examen AWS Certified Solutions Architect - Associate (SAA-C03), o simplemente desea comprender mejor la arquitectura en AWS, esta opción es para usted.</p>
</blockquote>
<p>Aprende en un entorno divertido, gratuito e interactivo. Haga sus preguntas en vivo en el chat para interactuar con los anfitriones y la comunidad. O use el hashtag #AWSPowerHour y etiquete a su anfitrión @trevorspires en LinkedIn. ¡Él buscará interactuar contigo!</p>
<p>Serán 6 episodios, desde este <a target="_blank" href="https://pages.awscloud.com/GLOBAL-other-T2-Traincert-Twitch-AWS-Power-Hour-Architecting-2022.html">link</a> encontrarás la fecha y hora en la que debes conectarte. ¡No olvides agendarlo!</p>
]]></content:encoded></item><item><title><![CDATA[Prepárate para el examen de AWS]]></title><description><![CDATA[Hace poco aprobé mi examen de certificación de AWS Solutions Architect - Associate, fueron muchos meses de estudio, dedicando varias horas al día. Lleve cursos, leí libros y todo material que encontraba por internet, incluyendo muchas prácticas (lueg...]]></description><link>https://blog.alfalfita.cloud/preparate-para-el-examen-de-aws</link><guid isPermaLink="true">https://blog.alfalfita.cloud/preparate-para-el-examen-de-aws</guid><category><![CDATA[Cloud]]></category><category><![CDATA[AWS]]></category><category><![CDATA[AWS Certified Solutions Architect Associate]]></category><category><![CDATA[Cloud Computing]]></category><dc:creator><![CDATA[Diana Alfaro]]></dc:creator><pubDate>Thu, 08 Sep 2022 19:10:20 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1662664380521/Y-veB1UqV.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Hace poco aprobé mi examen de certificación de AWS Solutions Architect - Associate, fueron muchos meses de estudio, dedicando varias horas al día. Lleve cursos, leí libros y todo material que encontraba por internet, incluyendo muchas prácticas (luego estaré compartiendo mis guías de estudio y mis recomendaciones).</p>
<p>Hoy quiero hablarte de dos programas: el programa acelerador de SAA el cual fue esencial para que aprobará el examen. Es un programa disponible para los socios (partners) de AWS, un programa de capacitación de 7 semanas y sesiones de revisión en línea dirigidas por entrenadores de AWS para ayudarlo a aprobar el examen. El entrenamiento es en inglés pero puedes acceder luego a las clases grabadas en caso necesites repasar el contenido.</p>
<p>El programa arranca el lunes 26 de septiembre y puedes inscribirte aquí:</p>
<p>https://mpa-saa-accelerator.splashthat.com/</p>
<p>Otro programa que también arranca este mes es el Rocket Journey: Solutions Architect - Associate, un programa de capacitación de 7 semanas también para los socios (partners) de AWS, destinado a una audiencia en español.</p>
<p>El programa arranca el viernes 9 de septiembre y puedes inscribirte aquí:</p>
<p>https://rocket-journey-saa-spa.splashthat.com/</p>
<p>Si tienes la oportunidad de inscribirte, aprovecha la oportunidad 🚀</p>
]]></content:encoded></item><item><title><![CDATA[Conociendo los servicios de cómputo de AWS]]></title><description><![CDATA[Comprender lo que implica poner en marcha un sitio web o cualquier otra aplicación o carga de trabajo vs. utilizar la nube para llevar a cabo ese trabajo, nos permitirá tener un mejor entendimiento de los servicios que nos proporciona AWS.

En esta o...]]></description><link>https://blog.alfalfita.cloud/conociendo-los-servicios-de-computo-de-aws</link><guid isPermaLink="true">https://blog.alfalfita.cloud/conociendo-los-servicios-de-computo-de-aws</guid><category><![CDATA[ec2]]></category><category><![CDATA[aws lambda]]></category><category><![CDATA[ECS]]></category><category><![CDATA[AWS]]></category><category><![CDATA[Cloud]]></category><dc:creator><![CDATA[Diana Alfaro]]></dc:creator><pubDate>Thu, 08 Sep 2022 18:44:09 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1662662552814/SgyLMxtKA.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<blockquote>
<p>Comprender lo que implica poner en marcha un sitio web o cualquier otra aplicación o carga de trabajo vs. utilizar la nube para llevar a cabo ese trabajo, nos permitirá tener un mejor entendimiento de los servicios que nos proporciona AWS.</p>
</blockquote>
<p>En esta ocasión estaremos hablando de algunos servicios de cómputo de AWS como: <strong>EC2, ECS y Lambda</strong>, veremos también algunos conceptos claves de éstos servicios con algunos ejemplos para hacer más fácil su compresión.</p>
<iframe width="760" height="515" src="https://www.youtube.com/embed/gVbZoNvgeS8"></iframe>
]]></content:encoded></item><item><title><![CDATA[Ahorrando costos de hasta un 70% en instancias EC2]]></title><description><![CDATA[¿Quizás a más de uno le ha pasado que ha dejado corriendo una instancia EC2 y olvido apagarla? 💸

Ahora imagina que tienes corriendo no 1 sino varias instancias EC2 con las que tu equipo trabaja semana tras semana, eso se traduce en 168 horas semana...]]></description><link>https://blog.alfalfita.cloud/ahorrando-costos-de-hasta-un-70-en-instancias-ec2</link><guid isPermaLink="true">https://blog.alfalfita.cloud/ahorrando-costos-de-hasta-un-70-en-instancias-ec2</guid><category><![CDATA[AWS]]></category><category><![CDATA[aws lambda]]></category><category><![CDATA[Cloud Computing]]></category><category><![CDATA[ec2]]></category><category><![CDATA[eventbridge]]></category><dc:creator><![CDATA[Diana Alfaro]]></dc:creator><pubDate>Mon, 29 Aug 2022 15:35:20 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1661866436241/egEa40Pm8.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<blockquote>
<p>¿Quizás a más de uno le ha pasado que ha dejado corriendo una instancia EC2 y olvido apagarla? 💸</p>
</blockquote>
<p>Ahora imagina que tienes corriendo no 1 sino varias instancias EC2 con las que tu equipo trabaja semana tras semana, eso se traduce en 168 horas semanales, en un horario laboral digamos de unas 10 horas (LUN-VIE de 8:30 am a 6:30 pm) menos de la mitad de las horas son donde realmente se hace uso de esas instancias.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1661780825226/fjAFhV9lK.png" alt="image.png" class="image--center mx-auto" /></p>
<p>Y si te digo que podemos iniciar y detener las instancias EC2 en función de las etiquetas (tags) para ahorrar costos de hasta un 70% en instancias que solo son necesarias durante ese u otro horario laboral (utilización semanal reducida de 168 horas a ~50 horas).</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1661780765283/wQU0zKk0v.png" alt="image.png" class="image--center mx-auto" /></p>
<p>Para lograr vamos a hacer uso de funciones lambda para programarlo en función de las horas de trabajo.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1661784325819/9xC4a6GSw.png" alt="Captura de Pantalla 2022-08-29 a la(s) 09.45.21.png" /></p>
<h2 id="heading-pero-que-es-lambda">Pero ¿qué es Lambda?</h2>
<blockquote>
<p>Con serverless no necesitas aprovisionar infraestructura, ni hacer mantenimiento, ni ocuparte del autoescalado. Es altamente disponible y seguro. Serverless no solo es para computo, puede ser para base de datos, almacenamiento u otros servicios</p>
</blockquote>
<ul>
<li><p>Es una de las opciones de computo que nos ofrece AWS, en este caso una opción <em>serverless</em></p>
</li>
<li><p>La unidad de escala es una función y el nivel de abstracción es un <em>runtime</em></p>
</li>
<li><p>Configuramos el código para que se ejecute cuando lo necesite (a demanda) en base por ejemplo a ciertos eventos.</p>
</li>
<li><p>Su modelo de pago es por uso (ms) de acuerdo al tiempo de ejecución de la función lambda con incrementos de 1 ms</p>
</li>
</ul>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1661781028943/Cspx33E-k.png" alt="Captura de Pantalla 2022-08-29 a la(s) 08.50.26.png" /></p>
<h2 id="heading-y-que-es-eventbridge">y ¿qué es EventBridge?</h2>
<blockquote>
<p>La versión 2 de Amazon CloudWatch Events</p>
</blockquote>
<ul>
<li><p>Facilita la creación de aplicaciones basadas en eventos a escala mediante eventos generados</p>
</li>
<li><p>Puede configurar reglas de enrutamiento para determinar a dónde enviar los datos</p>
</li>
<li><p>Cuenta con un bus de evento por defecto (en CloudWatch Events tiene solo un bus)</p>
</li>
<li><p>Puede tener buses de eventos adicionales</p>
</li>
</ul>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1661781572504/ZaTRWFrxh.png" alt="Diseño sin título (9).png" /></p>
<h2 id="heading-cron">CRON</h2>
<ul>
<li><p>Cron es un programa de utilidad de Unix que <strong>se utiliza para ejecutar comandos o scripts programados.</strong></p>
</li>
<li><p>Con una expresión cron, <strong>puede definir una regla que se active a una hora especificada</strong> de un determinado día de cada semana o mes</p>
</li>
<li><p>Las expresiones Cron <strong>tienen seis campos obligatorios</strong>, que están separados por un espacio en blanco.</p>
</li>
</ul>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1661781423378/BCYChKLmE.png" alt="Captura de Pantalla 2022-08-29 a la(s) 08.56.58.png" /></p>
<h2 id="heading-manos-a-la-obra">¡Manos a la obra!</h2>
<h3 id="heading-que-necesitamos">¿Qué necesitamos?</h3>
<ol>
<li><p>Crear una <strong>política y un rol de ejecución</strong> de AWS Identity and Access Management (IAM) personalizados **para la función Lambda **</p>
</li>
<li><p><strong>Crear las funciones Lambda</strong> que detengan e inicien las instancias de EC2 en base al tag de la instancia</p>
</li>
<li><p><strong>Probar</strong> las funciones Lambda</p>
</li>
<li><p><strong>Crear reglas de EventBridge</strong> que desencadenen la función en un horario.</p>
</li>
</ol>
<p>En este video junto a la comunidad de AWS Girls Chile, les explico el paso a paso de la solución 😊</p>
<iframe width="560" height="315" src="https://www.youtube.com/embed/cmBR1BxFSj0"></iframe>]]></content:encoded></item><item><title><![CDATA[AWS Game Day World Championship!]]></title><description><![CDATA[En esta especie de hackathon podrás poner a prueba tus habilidades para resolver distintos problemas dentro de un entorno seguro usando un handbox de AWS. 
Puedes participar solo o en equipos (de hasta 4 personas), desde el sitio web   podrás realiza...]]></description><link>https://blog.alfalfita.cloud/aws-game-day-world-championship</link><guid isPermaLink="true">https://blog.alfalfita.cloud/aws-game-day-world-championship</guid><category><![CDATA[events]]></category><category><![CDATA[AWS]]></category><category><![CDATA[Cloud]]></category><category><![CDATA[Cloud Computing]]></category><category><![CDATA[eventos]]></category><dc:creator><![CDATA[Diana Alfaro]]></dc:creator><pubDate>Tue, 02 Aug 2022 17:28:41 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1659461722037/_1wlra9nZ.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>En esta especie de hackathon podrás poner a prueba tus habilidades para resolver distintos problemas dentro de un entorno seguro usando un handbox de AWS. 
Puedes participar solo o en equipos (<em>de hasta 4 personas</em>), desde el <a target="_blank" href="https://pages.awscloud.com/GLOBAL-gamedev-OE-AWS-GameDay-WorldChampionship-2022-reg-event.html#form">sitio web</a>   podrás realizar la inscripción y conocer  las distintas fechas y horarios disponibles según tu ubicación.
<img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1659460544960/IrNcEKosK.png" alt="AWS-GameDay-Championships-V2.png" /></p>
<p>La actividad de 3 horas de duración te permitirá acumular puntos conforme vayas resolviendo lols desafíos. El ganador obtendrá como <strong><em>premio un viaje todo pagado al AWS re:Invent Las Vegas 2022!</em></strong></p>
<p>https://pages.awscloud.com/GLOBAL-gamedev-OE-AWS-GameDay-WorldChampionship-2022-reg-event.html#form</p>
<p>¿Qué esperas para participar ?</p>
<hr />
<p>Saludos,</p>
<p>Diana</p>
]]></content:encoded></item></channel></rss>