Crear una AWS VPC para nuestros recursos usando Terrafom
Crear un cluster de AWS EKS con Fargate usando Terraform
Actualizar CoreDNS para que pueda correr en Fargate
Crear un registry para nuestras imagenes de las aplicaciones frontend y backend en AWS ECR
Publicar nuestras imagenes en nuestro registry de ECR
Desplegar nuestros pods (Frontend y Backend) con sus respectivos secrets
Crear servicios para nuestros pods
Mejorar la estabilidad de nuestros pods con Pod Disruption Budget
Crear un IAM OIDC provieder usando Terraform
Desplegar un AWS Load Balancer controller (que creara un ALB por cada ingress que tengamos) en nuestro cluster usando Terraform
Crear un ingress para nuestros pods (frontend y backend)
Adjuntar dominios a nuestro ALB
Secure Ingress con SSL/TLS
Habilitar Fargate Loggin para logear a CloudWatch
Y vamos a automatizar todos estos pasos con GitHub Actions.
Pre requisitos
Crear un repositorio en GitHub
Lo primero es crear el repositorio de GitHub para poder automatizar el proceso de provisioning con Terraform. Para eso debemos crear un repositorio.
Para eso ejecutaremos los siguiente comandos:
Crear un Terraform Provider
Para comenzar a usar terraform primero necesitamos declarar un aws terraform provider. Para eso crearemos una carpeta llamada terraform y un archivo dentro de ella llamado 0-provider.tf con el siguiente codigo.
Dentro de terraform/0-provider.tf
Este archivo iniciara nuestro provider de terraform y guardara el estado de los recursos que vamos creando en un bucket de S3 en nuestro AWS. Recuerde tener un access key y un secret key con los roles necesarios para crear recursos.
Debemos crear una carpeta en la raiz del proyecto llamada .github y dentro de ella otra carpeta llamada workflows. En la carpeta workflows crearemos un archivo provisioning.yml con el siguiente codigo dentro. Este archivo se ejecutara cada vez pusheemos y que cambiemos algo dentro de la carpeta terraform.
Dentro de .github/workflows/provisioning.yml
El proposito de este job es aplicar los archivos terraform para crear los recursos necesarios en aws.
Para que este archivo se ejecute correctamente debemos agregar nuestro AWS_ACCESS_KEY_ID y AWS_SECRET_ACCESS_KEY como secrets en nuestro repositorio.
Una vez configurado los secrets podemos commitear y pushear nuestro codigo. Esto activara por primera vez el pipeline y iniciara el terraform provider y creara el archivo con nuestro estado de terraform en el bucket.
Bucket
Crear una AWS VPC para nuestros componentes usando Terraform
Dentro de esta seccion crearemos algunos recursos de networking como:
VPC
Subnets (Publics & Privates)
Internet Gateway
NAT Gateway
Route Tables
VPC
Ahora es momento de crear una VPC (Virtual Private Cloud) para nuestros componentes.
Para eso dentro de la carpeta terraform debemos crear el siguiente archivo 1-vpc.tf y dentro:
Internet Gateway
Luego un Internet Gateway, este sera usado para proveer acceso a internet directo a las Subnets publicas y acceso a internet indirecto a las Subnets privadas usando un NAT Gateway.
Crearemos un archivo terraform/2-igw.tf con**:**
Subnets
Ahora debemos crear nuestras subnets, 2 publicas y 2 privadas.
Crear el archivo terraform/3-subnets.tf con el siguiente codigo:
Se necesitan al menos dos subnets publicas y dos subnets privadas porque los load balancer que crearemos necesitan al menos 2 subredes.
El Internal-elb tag es usado por EKS para seleccionar las subnets privada y crearles private load balancer y el elb tag para crear public load balancers. Ademas necesitamos un cluster tag con un valor de owned or shared.
NAT
Para el NAT Gateway crearemos una ip elastica para no ocuparnos de alocarlo en una ip especifica (que podria estar en uso) y luego el NAT Gateway en si especificando sobre que Internet Gateway y que public subnet depende.
Crear archivo terraform/4-nat.tf con:
Route Tables
Por ultimo antes de empezar a crear nuestro EKS Cluster debemos crear Route Tables.
Crearemos el archivo terraform/5-routes.tf con el codigo:
La primera es una tabla de ruta privada con ruta default al NAT Gateway. La segunda es una tabla de ruta publica con ruta default al Internet Gateway. Finalmente, debemos asociar las subnets creadas anteriormente a estas route tables.
Luego de crear estos archivos para el networking, pusheamos para que se active el pipeline y terraform cree la VPC por nosotros.
Create a AWS EKS with Fargate using Terraform
El siguiente paso es crear el cluster de Kubernetes en EKS con nodos gestionados por Fargate. Para eso debemos crear el EKS control plane sin nodos (luego fargate los creara por nosotros).
El control plane consiste en nodos que corren Kubernetes software como etcd o la Kubernetes API server.
Lo primero de todo es crear un IAM role para EKS. Este rol se usara para poder crear el cluster. Recordemos que ante cada creacion de recurso necesitamos tener ciertos permisos para crearlos. Para eso creamos un archivo terraform/6-eks.tf con esto:
Despues tenemos que adjuntarle la AmazonEKSClusterPolicy a este rol.
Dentro de 6-eks.tf
Y, por supuesto, el propio EKS control plane. Debemos usar el rol creado para crear el cluster.
Además, hay que especificar al cluster las dos subnets privadas y las dos públicas. AWS Fargate solo puede usar subnets privadas con NAT Gateway para deployar nuestros pods. Las subnets públicas se pueden usar para que los load balancers que expongan la aplicación a Internet.
Creamos 6terraform/6-eks.tf con
Una vez pusheado y creado el cluster deberiamos poder verlo en nuestro EKS.
Y desde nuestra consola de comandos podemos conectarnos al cluster y ejecutar comandos de kubernetes. Para eso debemos correr
Si todo fue correcto, podemos listar todos los pods de nuestro cluster (que por ahora son 2 de CoreDNS que necesita nuestro cluster de Kubernetes para funcionar)
Si podemos observar, los pods estan en status Pending, eso lo solucionaremos en el siguiente paso.
Actualizar CoreDNS
Para que Fargate pueda crear nodos para los pods de CoreDNS debemos hacer lo siguiente.
Primero debemos crear un perfil de Fargate. Un Fargate profile, configurado en un cluster de EKS, permite crear nodos de manera automatica, para los pods de un namespace de cluster.
Necesitamos crear un único rol de IAM que se pueda compartir entre todos los perfiles de Fargate. Al igual que EKS, Fargate necesita permisos para activar los nodos y conectarlos al EKS control plane.
Para eso crearemos el archivo 7-kube-system-profile.tf con lo siguiente:
Luego tenemos que adjuntar la IAM policy llamada AmazonEKSFargatePodExecutionRolePolicy.
Y por ultimo el Fargate profile con el rol
Ahora, si obtenemos los pods nuevamente, esperariamos que CoreDNS ya este con los pods corriendo y con nodos asignados. Pero lo más probable es que, si el equipo de EKS no lo soluciona en versiones posteriores, esos pods de coreDNS seguirán en estado pendiente, ya que no tienen nodos asignados.
Podemos intentar describir el pod para obtener algún tipo de error de Kubernetes (kubectl describe pod). Deberíamos ver algo como: no hay nodos disponibles. Si te scrolleamos hacia arriba, veremos la razón. Estos pods vienen con la anotacion compute-type: ec2 que evita que Fargate cree los nodos para dichos pods. La solución es simple, simplemente hay que eliminar la anotación.
Para eliminar debemos correr el siguiente comando
Una vez eliminada la anotacion, AWS Fargate proveera un par de nodos para que puedan correr los pods.
Luego de unos minutos si volvemos a correr kubectl get pods -A podremos ver que no estos pods estan status ready.