"Desplegar sin Miedo: Un Cuento Épico de App Runner, Terraform y GitHub Actions."
Tags: pipeline, github, apprunner, awtwins
Published: 2024-01-15 21:40:37

⏳¡Un mes más tarde del primer post volvemos a la carga!⏳ En el último post exploramos los Parches automáticos para liberar tu agenda y así no quedarte dormido el día siguiente. ¡Pero la aventura acaba de empezar!🪂
En esta tercera entrega, nos adentramos en tierras más actuales, donde los términos serverless, containers, devops y todo su séquito despliegan su magia. Sin embargo, hoy, decidimos darle un toque de luz a un servicio que no es ni ECS ni EKS.🫣 Aunque, ¡no te preocupes! Estos seguro que tendrán su propio espacio en futuras historias que ya estamos preparando... 🥵 ¡Que empiece la locura!🥵

✈️En este post nos surmergimos en un viaje donde desplegaremos nuestra magia utilizando múltiples servicios simultáneamente, todo orquestado para que la experiencia sea lo más automática posible.✈️ ¿El dúo protagonista de esta historia? Terraform, Github Actions y App Runner, dos de las herramientas que están en boca de todos y que liderarán este post. 💥

Antes de nada... 📚 un paso atrás para desvelar los misterios del servicio. El viaje inicial explorando sus rincones de manera manual y a través de la consola de AWS:

[AppRunner](https://aws.amazon.com/apprunner/)

AWS App Runner es un servicio de aplicaciones completamente administrado que le permite crear, desplegar y ejecutar servicios de API y aplicaciones web en sin necesidad de experiencia previa en contenedores o infraestructuras.
￼
![Image 1](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/syl0hcz7xcp2i1jnocw2.png)

Como se señala en la documentación, AppRunner es el héroe que llega para desplegar y ejecutar servicios APIS y aplicaciones web sin requerir conocimientos previos en contenedores o infraestructura. 🥱¡Adiós a las reuniones infinitas sobre configuraciones complejas!🥱 O como mínimo los “no me funciona” 🥴

![Image 2](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4xjq1xnq1o2ihgvgqimm.png)

Nos adentramos en el territorio de despliegue y tenemos dos caminos: uno desde Container registry y otro desde Source Code Repository. Ambos con sus cositas, así que vamos a adentrar un poco en cada uno de ellos y descubrir cuál se adapta mejor a nuestras necesidades.

Si optamos por el camino del Container Registry, podemos elegir entre ECR Private o ECR público , en este caso nuestra misión es desplegar usando el público con la siguiente imagen:

[Hello-app-runner](https://github.com/aws-containers/hello-app-runner)

⛔En el caso de utilizar ECR Public no es posible usar las actualizaciones automáticas pero no te preocupes, que pronto entramos a ver como desplegar con estilo pero sin actualizaciones automáticas.⛔

![Image 3](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4kt3vsdaodp1swuhu3e6.png)

Configuraremos aquí los valores que necesitemos tales como VirtualCPU/Memory,si tenemos variables de entorno, en additional configuration podemos encontrar también el start command, por si necesitamos algún otro momento de magia.🚀

![Image 4](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4gjr1wi08fwg1kxlj8fm.png)

⚡En la parte de AutoScaling veremos el arte de la escalabilidad automática. Aquí configuraremos las solicitudes, establecer el máximo,el mínimo y dejar que AppRunner realice su propia magia basándose en métricas como las solicitudes y alguna que otra métrica interna, dejamos más información para los curiosos. ⚡

[Autoscaling-apprunner](https://docs.aws.amazon.com/es_es/apprunner/latest/dg/manage-autoscaling.html)

Tenemos la capacidad de modificar los Health Checks para asegurarnos que nuestras instancias siempre estén funcionando como deben. 👨‍🔬

![Image 5](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/e6xdpgm6m780oes5mtii.png)

Permisos, WAF y AWS MKS key No vamos a entrenar servicio por servicio puesto que cada uno debe de ser modificado en base a necesidades. Un consejo sabio: siempre activar WAF a todos aquellos que se aventuren a jugar en entornos productivos, que nos conocemos.🕵️

![Image 6](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5m7fg6f1vmwvjekq9xet.png)

Como también nos puede interesar desplegarlo en privado, tenemos una opción para ello:

![Image 7](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/o2ssvwzb8q3yrjpafbgy.png)

Cabe remarcar que para Private endpoint necesitaremos un VPC interface endpoint y un VPC connector. (si lo necesitáis, podemos subir a git un ejemplo, pero dependerá de las reacciones y comentarios así que...)🚀

🕵️Y por último la parte de monitoring que podemos cubrirla con X-RAY 🕵️

![Image 7](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6c4395sfllms3ru3rxy1.png)

No obstante, también está integrado con Cloudwatch por lo que podremos ver los logs de nuestro service y de nuestra app en el mismo.

![Image 8](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/57mhwbeue7d96eo1ph34.png)

Con todos los valores revisados y afinados, el momento mágico ha llegado. Es hora de apretar el botón mágico ‘Create & Deploy’ y ver cómo nuestra app dummy cobra vida.

![Image 9](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2daz5i4t4wdayjvce67i.png)

Un clic en default domain y ¡Voilà! ¡La magia funcionó y nuestro servicio se desplega! 🫡

![Image 10](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/uwh7lffw37riaq939br3.png)

¡Bien! Ya hemos dominado la magia de desplegar con Apprunner pero ahora, llevaremos el servicio a otro step. Como hemos visto nuestro servicio puede conectarse a nuestro repositorio de código, permitiendo así que cada push inicie automáticamente el despliegue de una nueva versión. 

👋¡Adiós a las builds no funcionan! Desde ahora, cada modificación en nuestro código desencadenará una nueva versión de la aplicación, así, desplegando con su flow! 👋

Para poder testear este paso hemos generado un repositorio que contiene una  app en python, como nos gusta decir, de las cutres, pero cutres...que lo único que hace es decir (“Hello from Flask in App Runner! ) donde podrás encontrar el DockerFile, app.py, apprunner.yaml y requirements.txt (Como siempre, si no queréis fracasar, ⛔no usar esto para producción)⛔ PD: No somos developers, no critiquéis mucho 🤭

Dejo el link a continuación: 

[frontend-app](https://github.com/ragerdevops/app-runner-Poc-Repository-app.git)

Para dar inicio a esta odisea, elegiremos la opción ‘Source code repository’ al crear nuestro servicio. Pero antes de pasar al capitulo final tenemos que crear una conexión con nuestro repo.

![Image 11](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/msctrftli4ja497wiftd.png)

En repository seleccionamos nuestro repository:

![Image 12](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3l550oyfg4z52umklmrd.png)

![Image 13](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1zr1kyff6ivgnusxqt8z.png)

Para que cada vez que modifiquemos la imagen se apliquen los cambios debemos de seleccionar Automatic.

✌️ En el siguiente paso podremos configurar si deseamos configurar nuestros valores mediante consola o bien en el mismo repo con un fichero apprunner.yaml, ya que estamos, lo haremos por fichero para no volver a caer en lo manual. ✌️

![Image 14](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/o17eqfuon41b5ys3nd2b.png)

👏 ¡Y así, aplauso y nuestro despliegue se completa! (Si todo va bien, si no, a mirar los logs!) 👏 

![Image 15](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hu5j00zobhfo1iwrl0i2.png)

¡Walaa! Nuestra aplicación se encuentra en todo su esplendor, lista y pública para todos!😋

![Image 16](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/g7s7nh9yiogq85x2c38q.png)

Con la aplicación desplegada nos llega el momento de presenciar la magia de la automatización, Realizaremos un cambio en la aplicación, como por ejemplo añadir v1.0 y veremos que al hacer un push, despliega una nueva versión con un simple push.🕺

![Image 17](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/smuv715nesxk6r2ainu7.png)

![Image 18](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/sh3xyt6t081tbrslg0pa.png)

![Image 19](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/snx8nggybvbn11lrav8t.png)

Como hemos comentado, estamos evitando huir de las cosas manuales, por lo que todo esta parte ha sido únicamente creada a mano para entenderlo, pero en realidad, al hacer la PoC hemos desplegado todo con terraform y GitHub actions. (Ya avisamos de qué son simples y una primera versión, otra vez más,😈 no deberemos usarlas para producción puesto que su única finalidad es la PoC). 😈

En nuestra búsqueda de eficiencia y simplicidad, hemos recurrido a herramientas proporcionadas por la comunidad.
En este caso, utilizamos terraform, aprovechando los módulos que nos brinda la comunidad, además para el despliegue confiamos en la magia de Github Actions, que se sincroniza perfectamente con nuestros repositorios de Github.

[app-runner-module](https://github.com/terraform-aws-modules/terraform-aws-app-runner)

En el directorio podéis ver la carpeta examples (dependiendo de vuestras necesidades).

No obstante, hemos generado un repositorio donde podréis encontrar todo “pre-configurado” y un Readme donde explica como desplegar: 🫣

[app-runner-infra](https://github.com/ragerdevops/app-runner-Poc-Repository-infra)

1. **Configuración de las Credenciales en GitHub:**
   - Configura las [GitHub Secrets](https://docs.github.com/en/actions/security-guides/encrypted-secrets) con las credenciales de AWS necesarias para la pipeline. En este caso deberás de configurarlas en tu repositorio.

2. **Configuración de AWS App Runner:**
   - Ajusta el fichero provider.tf para indicar la region donde quieres desplegar tu infrastructura.(recomiendo dejar eu-west-1 puesto que el script consulta esa region, si no, deberás de modificarlo en script.sh)
   - Modifica backend.tf para apuntar a tu bucket s3 para almacenar el estado de terraform.
   - Ajusta las configuraciones necesarias en el fichero `variables.tf` según tus necesidades, en este caso indicar el repositorio de la app.

3. **Despliegue Automático con GitHub Actions:**
   - Cada vez que realices un push a la rama `main`, la pipeline de GitHub Actions se activará automáticamente, desencadenando el despliegue de la infrastructura necesaria para poder deployar nuestra app en AppRunner.

4. **Testear AppRunner en repositorio de código de la app**:
   - Cuando tengas desplegada la infra y todo funcional ya podrás ir al repositorio de código de tu app para lanzar nuevos deploys automáticos al modificar la app tal y como se explica en este mismo post.

[frontend-app-runner](https://github.com/ragerdevops/app-runner-Poc-Repository-app.git)

Una vez en el paso 4 lo que deberemos hacer es modificar nuestro texto de la app en nuestro repositorio de la app, en nuestro caso modificamos para que nos muestre la nueva versión en el texto, en este caso v2.0.

![Image 20](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/690ftkh7m2hxe9kha2ze.png)

Pusheamos a nuestro repositorio.

Git add .
Git commit -m “update version app”
Git push 

![Image 21](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9ohl18u58sqdr3wqpq44.png)

Accedemos al default domain:

![Image 21](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/kyhcyy4x3xn98cz1cdlv.png)

🪄Ahora, con un cambio en la aplicación, hemos dado vida a una nueva versión, pero esta vez de forma automática con terraform + Github Actions. 🪄

En el mundo de apprunner las imágenes no se almacenan en un repositorio ECR. En lugar de eso, AppRunner controla sus propia magia 🪄 para gestionar las imágenes y permitirnos hacer rollback cuando sea necesario. Si necesitamos volver a una versión anterior, podemos recurrir a métodos como revertir el código de nuestro repositorio usando herramientas como ‘git reverse’. 🧙‍♂️¡Que la magia de GIT nos guíe!🧙‍♂️

Una importante aclaración: los AppRunner que hemos desplegado están configurados como endpoints públicos, facilitando así la realización de nuestra PoC. Sin embargo,si necesitamos elevar la seguridad y configurarlos como privados, podemos lograrlo ajustando los valores correspondientes en el módulo de Terraform.

Para poder complementar esta configuración, también podemos utilizar otro módulo de la comunidad para generar un VPC endpoint necesario. Con esa combinación de ajustes podemos crear un entorno más seguro y controlado, adecuado para aplicaciones que requieren una capa adicional de privacidad.

Y con esto acabamos nuestra travesía por AppRunner, desde luego un servicio como mínimo interesante, ¿Te ha parecido interesante? Esperamos vuestras reacciones y comentarios! :)