[How to] Implementar Ephemeral environments para Pull Request en GitHub
Tags: cloudnative, productivity, developmentcycle, development
Published: 2024-03-15 15:15:06

Hoy te quiero contar cómo puedes crear tus propios ambientes efímeros usando las herramientas de **IaC** (Infrastructure as Code) que ya tienes. En mi caso estaré utilizando **AWS CDK** para el despliegue en la nube, pero el tutorial sirve para cualquier **IaC**. 

---
 {% youtube i3dAuMcQr2U %}
> Tener la posibilidad de usar Ephemeral environments (ambientes efímeros) al momento de crear una Pull Request es sin dudas una de las mejores herramientas para aumentar la productividad en el desarrollo de software nativo usando la nube. Ya que te permite tener un ambiente listo para hacer tus pruebas de integración (E2E) justo al momento de terminar de codear los cambios.


---
##¿Qué es un Ephemeral environments o Preview environment?
Recordemos que los ambientes “ephemeral” tienen un ciclo de vida corto, fueron creados para una finalidad en particular (en nuestro caso validar el código al momento de la creación de una Pull Request), deben ser lo más parecido al ambiente de producción y estar disponibles cuando el programador los necesite. Muy importante luego de ser utilizados deben ser destruidos con herramientas automatizadas. 

_Te dejo un post de mi blog con todos los detalles para que puedas profundizar más..._[https://blog.hectorfernandez.dev/ephemeral-environments-como-crearlos](https://blog.hectorfernandez.dev/ephemeral-environments-como-crearlos)

##¿Qué debes de tener?

1. Repositorio de código (GIT)
1. Cuenta de AWS
1. IaC para el despliegue de tus recursos
1. [AWS CLI](https://aws.amazon.com/cli/) configurado en tu maquina

_Los siguientes pasos están dentro de la [capa gratuita de AWS](https://aws.amazon.com/free/), pero según tu caso de uso puedes incurrir en costos._

---

## 1) Identificar nuestra infraestructura (en el código)
El primer paso que debemos de debemos hacer es identificar nuestra infraestructura, por ejemplo _¿usamos contenedores?_, usamos servicios de almacenamiento persistentes (S3)? _¿Cómo estos servicios están referenciados en nuestro código?_. 

####¿Pero saber en qué parte del código se hace referencia a servicios externos en qué me ayuda?
_por ahora te diría muchísimo._

Al conocer cómo interactúa nuestra aplicación nos permite identificar cuáles parámetros pueden ser pasados por ejemplo mediante variables de entorno. Cuando creamos ambientes de _“preview”_ cómo también se le suele llamar, debemos saber que los nombres de cada entidad son autogenerados, por lo tanto no podremos decidir el nombre o dejar ese nombre de forma estática en el código. 

_Te muestro un ejemplo, para entender mejor el punto anterior._

```
 const msg =
    process.env.BUCKET_NAME === "prod"
      ? "Production Mode "
      : "Preview Enviroment";

  return {
    statusCode: 200,
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify({
      message: `Hello from Lambda ${msg} using CDK`,
    }),
  };
```
Este código es parte de la función [serverless](https://dev.to/aws-builders/que-es-serveless-en-simples-palabras-8m1) de lambda, dónde dependiendo de la variable de entorno pasada se comporta de una u otra manera _(esto puede ser tan complejo cómo tu solución lo necesite)_ es meramente para ilustrar la importancia de **identificar** la parte que el código hace uso de la infraestructura creada. 

---

## 2) High-level architecture

![Preview Environment using AWS CDK](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/23o6qk2dt2om8xfesmx3.png)
_En este template podremos ver la idea general de la implementación y cómo quedaría nuestra cuenta luego de tener más de 1 ambiente temporal desplegado._

Como podemos observar nuestra arquitectura es bastante simple para enseñarles la integración que puede tener. La idea es que un ambiente productivo real siga la misma idea pero escalado a la cantidad de recursos que ya tienes.

---

## 3) Stack de AWS CDK

![Stack de AWS CDK](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/py6jxp5zp4tkmxtti1uw.png)
---

## 4) Github Actions que se encargará de hacer todo esto posible

![GitHub Actions](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6k1z68njxduusd6vjw9k.png)
---

## 5) Puntos importantes

- **Sintetizar nuestra plantilla de cloudformation:** 
[40% más rapido la creación de stacks cloudfromation](https://aws.amazon.com/about-aws/whats-new/2024/03/aws-cloudformation-40-percent-faster-stack-creation/)
_(Si usas otra herramienta de IaC, sigue los pasos que te indica esa otra herramienta)_
- **Hacer el deploy del stack:** Un punto aca super importante es que le pasamos como parámetro el ID del pull request que estamos creando, de esta forma se crea un ID único. 
- Validar los cambios que hicimos

Ya con esto tendríamos nuestro **ambiente desplegado en una cuenta compartida** entre todos los desarrolladores pero a su vez cada quien con su stack propio, permitiendo que las pruebas se puedan hacer de forma aislada. 

## 6)Revisando nuestros recursos en AWS
Si vamos a cloudformation desde la consola tendremos algo similar a esto. Tendremos nuestras _URL listas_ para utilizar ¡Lo logramos!
ya con esto vamos a poder hacer nuestras pruebas e2e o cualquier prueba de humo sin mayor esfuerzo. 


![cloudformation desde la consola](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/n1iomb34xuqofmbkan2v.png)

#Tips para mejorar esta solución:
- Tener una colección de Postman que pueda correr mediante CI / CD cada vez que se cree una Pull Request, de tal manera de asegurar la integridad de la aplicación. 
- Implementar comentarios automáticos en Github, de esta forma la URL del ambiente creado queda disponible para todos los reviewers.
- Solo hacer despliegue de los componente que sean necesarios según el código que se tocó
- Definir un tiempo de vida para el stack, ya que si alguien deja esa PR por mucho tiempo pueda tener un ciclo de vida. 

---

¿Habias utilizado algo similar antes? Me gustaría saber tu opinión de estipo de ambientes en un ciclo de desarrollo continuo. 

---

## Connect with me

LinkedIn : [https://www.linkedin.com/in/hectorfernandezdev/](https://www.linkedin.com/in/hectorfernandezdev/)
GitHub : [https://github.com/hectorfernandezdev](https://github.com/hectorfernandezdev)
Podcast: [https://podcast.hectorfernandez.dev/](https://podcast.hectorfernandez.dev/)

Let's keep building