En la era actual de la computación en la nube, la infraestructura como código (IaC) se ha convertido en una práctica esencial para los equipos de desarrollo y/o DevOps. AWS, como uno de los principales proveedores de servicios en la nube, ofrece varias opciones para gestionar y desplegar infraestructura como código. En este artículo, exploraremos algunas de estas opciones y que nos permiten hacer para lograr entender cuál podría ser la mejor opción para cada proyecto.

¿Que es la “Infraestructura como código”?

Infraestructura como código, que habitualmente lo veremos escrito como “IaC”, del ingles “Infrastructure as Code” es la capacidad para crear y mantener recursos usando código en lugar de procesos y configuraciones manuales.

Algunos de los principios fundamentales de IaC son la automatización y el versionado del código. Mediante la automatización, se elimina la necesidad de realizar tareas manuales repetitivas que habitualmente generar errores, ya sea por olvidarnos de deployar algún recurso o bien por tener parámetros mal configurados.

Por otro lado, el versionado del código permite a los equipos mantener un registro de todos los cambios realizados en la configuración de la infraestructura, facilitando el seguimiento y la resolución de problemas como así también la realización de rollbacks en caso de fallas en el despliegue.

Ademas de los puntos antes mencionados, otra gran ventaja del uso de IaC es la capacidad de respuesta ante incidentes graves en nuestra infraestructura, como pueden ser la caída de determinadas zonas de disponibilidad o regiones de nuestro proveedor cloud, permitiendo tener una plan de recuperación ante desastres (DR o Disaster Recovery en ingles).

Por ultimo, otro aspecto donde la infraestructura como código puede proveer mucho valor es en el control y reducción de los gastos. Por una parte podemos mediante definiciones en nuestros frameworks limitar los recursos o configuraciones que se permiten desplegar, como podrían ser determinados tipos de instancias EC2, como así también permitir la rápida eliminación de entornos en desuso como pueden ser aquellos utilizados en el proceso de desarrollo o testing.

A continuación haremos un repaso por las principales herramientas disponibles para desplegar infraestructura en AWS, como son CloudFormation, SAM y CDK, y hablaremos también de uno de los principales referentes en este rubro, Terraform.

CloudFormation

AWS CloudFormation es un servicio que ayuda a modelar y configurar recursos de AWS. Utiliza templates escritos en JSON o YAML para describir el conjunto de recursos y propiedades requerido.

Este servicio es la base fundacional para el despliegue de recursos, en la documentation oficial vamos a encontrar las referencias y configuraciones para prácticamente cualquier servicio disponible en AWS y esta en constante actualización con las ultimas características y servicios.

Para facilitar un poco las cosas, dentro de la consola de AWS vamos a poder contar con la herramienta CloudFormation Designer, que nos permitirá de manera gráfica crear un stack con los recursos necesarios, establecer dependencias y configurar según los requisitos de nuestra aplicación. Ademas, desde esta herramienta vamos a poder exportar nuestro template en formato JSON o YAML.

Si bien CloudFormation cuenta con una extensa y detallada documentación, es esta a su vez uno de sus principales desafíos, ya que la curva de aprendizaje suele ser un tanto empinada para los principiantes

{
  "AWSTemplateFormatVersion": "2010-09-09",
  "Description": "A sample template",
  "Resources": {
    "MyEC2Instance": {
      "Type": "AWS::EC2::Instance",
      "Properties": {
        "ImageId": "ami-0ff8a91507f77f867",
        "InstanceType": "t2.micro",
        "KeyName": "testkey",
        "BlockDeviceMappings": [
          {
            "DeviceName": "/dev/sdm",
            "Ebs": {
              "VolumeType": "io1",
              "Iops": 200,
              "DeleteOnTermination": false,
              "VolumeSize": 20
            }
          }
        ]
      }
    }
  }
}
AWSTemplateFormatVersion: 2010-09-09
Description: A sample template
Resources:
  MyEC2Instance:
    Type: "AWS::EC2::Instance"
    Properties:
      ImageId: ami-0ff8a91507f77f867
      InstanceType: t2.micro
      KeyName: testkey
      BlockDeviceMappings:
        - DeviceName: /dev/sdm
          Ebs:
            VolumeType: io1
            Iops: 200
            DeleteOnTermination: false
            VolumeSize: 20

AWS SAM

SAM (Serverless Application Model), es un conjunto de herramientas desarrollado por Amazon para la construcción de aplicaciones serverless.

SAM esta conformado por 2 partes principales

  • Un framework open-source que utilizaremos para la definición de nuestro template
  • SAM CLI: Una herramienta de linea de comando que nos permitirá inicializar, testear y deployar (entre varias otras tareas) nuestra aplicación.

¿Como funcionan los templates de SAM?

Este framework esta basado en CloudFormation, con lo cual maneja la misma sintaxis y funciona como una extension del mismo. Tal como su nombre nos indica esta orientado a crear recursos serverless, como funciones Lambda, API Gateway o bases de dato DynamoDB. Dentro de los templates de SAM podemos usar indistintamente recursos del tipo serverless, que veremos dentro del template como *AWS::Serverless::** o recursos de CloudFormation como podría ser un *AWS::EC2::Instance.*

Una particularidad de los templates de SAM es la declaración del “Transform” que se puede apreciar en la segunda linea de la siguiente imagen:

AWSTemplateFormatVersion: 2010-09-09
Transform: AWS::Serverless-2016-10-31
Resources:
  getAllItemsFunction:
    Type: AWS::Serverless::Function
    Properties:
      Handler: src/get-all-items.getAllItemsHandler
      Runtime: nodejs12.x
      Events:
        Api:
          Type: HttpApi
          Properties:
            Path: /
            Method: GET
    Connectors:
      MyConn:
        Properties:
        Destination:
          Id: SampleTable
          Permissions:
            - Read
  SampleTable:
    Type: AWS::Serverless::SimpleTable

El “Transform” en un template de SAM es una instrucción clave que le indica a CloudFormation cómo procesar el archivo. Al especificar “AWS::Serverless-2016-10-31” como valor para “Transform”, estamos indicando que el archivo debe ser procesado como un modelo de AWS Serverless Application. Esto permite transformar los recursos simplificados del tipo “AWS::Serverless::”, como “AWS::Serverless::Function” para las funciones Lambda o “AWS::Serverless::Api” para API Gateway.

Además, el “Transform” en SAM también permite el uso de algunas funcionalidades adicionales como las IAM policies generadas automáticamente para las funciones Lambda.

La magia de SAM CLI

Si bien los templates SAM nos facilitan el armado de la infraestructura de nuestra aplicación, la verdadera magia ocurre con la herramienta de linea de comando, que nos va a permitir sacar el máximo potencial de este framework.

En SAM CLI vamos a contar, entre otros, con los siguientes comandos:

  • sam init: Este comando se utiliza para inicializar un nuevo proyecto SAM. Puedes crear un nuevo proyecto a partir de una plantilla de inicio rápido de AWS o de un ejemplo de la galería de aplicaciones de SAM.
  • sam local invoke: Este comando permite invocar funciones Lambda localmente, lo que es útil para probar y depurar tus funciones antes de desplegarlas en AWS.
  • sam local start-api: Este comando inicia una API local de Amazon API Gateway a partir de tu plantilla de SAM. Puedes usarlo para probar la interacción de tu función Lambda con API Gateway antes de desplegarlo a AWS.
  • sam package: Este comando empaqueta tu aplicación y la carga en un bucket de Amazon S3.
  • sam deploy: Este comando despliega tu aplicación en AWS con AWS CloudFormation. Utiliza el paquete creado por el comando sam package.
  • sam logs: Este comando te permite obtener los registros de CloudWatch Logs para las funciones Lambda desplegadas.
  • sam validate: Este comando valida que tu archivo de plantilla SAM sea válido.

Como podemos ver el potencial de AWS Serverless Application Model es inmenso y nos proporciona un abanico muy interesante de herramientas que vamos a estar analizando en futuras entradas de este blog.

Aunque AWS SAM ofrece una gran cantidad de ventajas, también tiene algunas desventajas:

  • Dependencia de AWS: AWS SAM está diseñado específicamente para AWS. Esto puede ser una limitación para las organizaciones que buscan una solución multi-cloud.
  • Curva de aprendizaje: Para los nuevos usuarios, la sintaxis de los templates de CloudFormation que se utiliza en AWS SAM puede resultar compleja y difícil de aprender.
  • Limitaciones de las políticas IAM generadas automáticamente: AWS SAM genera políticas IAM automáticamente para las funciones Lambda, lo que puede ser conveniente, pero también puede resultar en políticas más permisivas de lo que se necesita, lo que puede ser un riesgo de seguridad.
  • Depuración: Al igual que con otros frameworks basados en infraestructura como código, la depuración de los scripts de AWS SAM puede ser compleja y requerir un conocimiento más profundo de AWS.

AWS CDK

El AWS Cloud Development Kit (CDK) es un framework open-source que permite a los desarrolladores modelar y aprovisionar sus recursos de AWS utilizando lenguajes de programación populares como TypeScript, Python, Java y .NET.

A diferencia de SAM, donde usamos un template en formato JSON o YAML, con CDK declararemos nuestra infraestructura mediante nuestro lenguaje de preferencia, lo que facilita la curva de aprendizaje dentro del equipo y nos ahorra la necesidad de aprender la sintaxis requerida por los templates de CloudFormation o SAM.

export class MyEcsConstructStack extends Stack {
  constructor(scope: App, id: string, props?: StackProps) {
    super(scope, id, props);

    const vpc = new ec2.Vpc(this, "MyVpc", {
      maxAzs: 3, // Default is all AZs in region
    });

    const cluster = new ecs.Cluster(this, "MyCluster", {
      vpc: vpc,
    });

    // Create a load-balanced Fargate service and make it public
    new ecs_patterns.ApplicationLoadBalancedFargateService(
      this,
      "MyFargateService",
      {
        cluster: cluster, // Required
        cpu: 512, // Default is 256
        desiredCount: 6, // Default is 1
        taskImageOptions: {
          image: ecs.ContainerImage.fromRegistry("amazon/amazon-ecs-sample"),
        },
        memoryLimitMiB: 2048, // Default is 512
        publicLoadBalancer: true, // Default is false
      }
    );
  }
}

En CDK vamos a declarar los recursos necesarios mediante el uso de “Constructs”, los cuales son bloques de código reutilizables que encapsulan uno o más recursos de AWS, junto con la configuración requerida para usar esos recursos. Los Constructs pueden ser anidados dentro de otros Constructs para crear una jerarquía, lo cual permite crear abstracciones de alto nivel que encapsulan detalles de la implementación de la infraestructura. Existen 3 niveles de constructs:

  • Constructs de nivel 1 (L1): Representan los recursos de AWS CloudFormation. Estos son los bloques de construcción básicos que representan a cada uno de los servicios de AWS.
  • Constructs de nivel 2 (L2): Son abstracciones pre-construidas que encapsulan un patrón o una pieza de infraestructura que es usada de manera habitual como como puede ser una función lambda, un bucket S3, entre otros.
  • Constructs de nivel 3 (L3): Son los constructs creados por los desarrolladores. Estos pueden combinar varios L2 y L1 para crear abstracciones personalizadas.

A su vez, estos constructs los vamos a estar organizando en “Stacks”. Los stacks son una pieza de la infraestructura de nuestra aplicación que se puede gestionar y actualizar de manera independiente. Cada aplicación de AWS CDK puede constar de uno o varios stacks. Un stack en CDK corresponde a una ‘pila’ en AWS CloudFormation, que es la unidad de implementación en CloudFormation.

El uso de los Stacks en AWS CDK nos van a permitir:

  • Organización y modularidad: Los Stacks permiten agrupar y organizar recursos relacionados en unidades lógicas y manejables. Esto facilita la gestión de la infraestructura, especialmente en aplicaciones grandes y complejas.
  • Despliegue independiente: Cada Stack puede desplegarse de manera independiente, lo que permite actualizar partes específicas de la infraestructura sin afectar a otras.
  • Reutilización de código: Los Stacks pueden definirse una vez y luego reutilizarse en varias aplicaciones o entornos, lo que permite un desarrollo más rápido y consistente.
  • Gestión de dependencias: AWS CDK maneja automáticamente las dependencias entre los recursos dentro de un Stack, lo que simplifica la creación y actualización de infraestructuras complejas.

Si bien el poder utilizar un lenguaje de programación ya conocido por nuestro equipo facilita la curva de aprendizaje, esto puede ser un punto en contra para aquellos perfiles mas cercanos a las areas de infraestructura, ya que en lugar de utilizar un template con una sintaxis agnóstica deberán estar familiarizados con el lenguaje que estemos utilizando en nuestra aplicación de CDK.

Terraform

Terraform, desarrollado por HashiCorp, es una herramienta que permite a los usuarios definir y proporcionar infraestructura utilizando un lenguaje de configuración declarativo. Esto significa que los usuarios describen el estado deseado de la infraestructura y Terraform se encarga de crear, modificar o eliminar recursos para alcanzar ese estado.

A diferencia de CloudFormation, Terraform es agnóstico a la plataforma, lo que significa que no está atado a AWS y puede ser utilizado con otros proveedores de servicios en la nube. Esta característica puede ser especialmente útil para organizaciones que utilizan una estrategia multi-cloud.

Aunque su sintaxis es más simple que CloudFormation, Terraform no está tan profundamente integrado con AWS, lo que puede llevar a algunas complicaciones. Por ejemplo, puede que no soporte las últimas características y servicios de AWS tan rápido como CloudFormation.

Entonces, ¿Que me conviene que usar?

Puede que esta no sea la respuesta que estabas buscando pero, depende… Cada una de las herramientas tienen sus pro y contras y es importante conocerlas y probarlas para definir cual tiene mejor fit con los requisitos de nuestro proyecto o equipo de trabajo.

Para eso, en los siguientes capítulos de este blog, vamos a estar revisando en profundidad estas herramientas, creando una aplicación serverless simple y con una misma arquitectura que nos permita comparar los procesos de cada uno y poder elegir si queremos crear nuestra aplicación con CloudFormation, SAM o CDK.