CloudFormation vs Terraform

Terraform es superior a CloudFormation en todos los escenarios, excepto cuando absolutamente tiene que usar funciones de vanguardia de AWS. Este es el por qué.

Curva de aprendizaje:

Creo que la mayoría de las personas aprenden nuevas tecnologías, siguiendo tutoriales o mirando ejemplos. Esto es bastante fácil de hacer con la mayoría de los lenguajes de programación, al menos para un nivel de entrada.
No con CloudFormation. Tiene formato JSON (o YAML). Ha sido diseñado para ser consumido y producido por computadoras, no por humanos. Pruébelo usted mismo, a continuación se muestra un fragmento de código de ejemplo requerido para activar una instancia EC2 (básicamente una VM):

{
  "AWSTemplateFormatVersion": "2010-09-09",
....
150 líneas de bla bla bla ...
....
  },

  "Recursos": {
    "EC2Instance": {
      "Tipo": "AWS :: EC2 :: Instancia",
      "Propiedades": {
        "UserData": {"Fn :: Base64": {"Fn :: Join": ["", ["IPAddress =", {"Ref": "IPAddress"}]]}},
        "InstanceType": {"Ref": "InstanceType"},
        "SecurityGroups": [{"Ref": "InstanceSecurityGroup"}],
        "KeyName": {"Ref": "KeyName"},
        "ImageId": {"Fn :: FindInMap": ["AWSRegionArch2AMI", {"Ref": "AWS :: Region"},
                          {"Fn :: FindInMap": ["AWSInstanceType2Arch", {"Ref": "InstanceType"}, "Arch"]}]}
      }
    },

    "InstanceSecurityGroup": {
      "Tipo": "AWS :: EC2 :: SecurityGroup",
      "Propiedades": {
        "GroupDescription": "Habilitar acceso SSH",
        "SecurityGroupIngress":
          [{"IpProtocol": "tcp", "FromPort": "22", "ToPort": "22", "CidrIp": {"Ref": "SSHLocation"}}]
      }
    },

    "Dirección IP" : {
      "Tipo": "AWS :: EC2 :: EIP"
    },

    "IPAssoc": {
      "Tipo": "AWS :: EC2 :: EIPAssociation",
      "Propiedades": {
        "InstanceId": {"Ref": "EC2Instance"},
        "EIP": {"Ref": "IPAddress"}
      }
    }
  },
  "Salidas": {
    "InstanceId": {
      "Descripción": "InstanceId de la instancia EC2 recién creada",
      "Valor": {"Ref": "EC2Instance"}
    },
    "InstanceIPAddress": {
      "Descripción": "Dirección IP de la instancia EC2 recién creada",
      "Valor": {"Ref": "Dirección IP"}
    }
  }
}

Asqueroso. 210 líneas de código para obtener una VM con IP pública protegida por Security Group. 210. 210! Con cada plantilla hay una gran cantidad de código repetitivo, que es básicamente ruido (más sobre esto más adelante).
Si eso no es suficiente para posponerlo en esta etapa, eche un vistazo a la documentación oficial. Ahora se ha desplazado hacia el uso de YAML, pero cuando desea ver fragmentos de muestra, resulta que todos están en JSON. Lo mismo es cierto para los resultados de Google.
Por cierto. cuando tienes diferentes fragmentos de muestra por región, puedes decir que algo es sospechoso

Ronda # 1: CF: 0 TF: 1

Escribir código

Casi los mismos argumentos que los anteriores se aplican a la escritura del código en sí. Para ver un ejemplo rápido, eche un vistazo a los mismos recursos que el anterior, pero que se describen en Terraform:

recurso "aws_instance" "web" {
  ami = "12345-6789-10"
  instancia_tipo = "t2.micro"

  etiquetas {
    Nombre = "Dulce"
  }
}
datos "aws_eip" "pip" {
  public_ip = "1.1.1.1"
}

recurso "aws_eip_association" "pip" {
  instance_id = "$ {aws_instance.web.id}"
  partir_id = "$ {data.aws_eip.pip.id}"
}
recurso "aws_security_group" "allow_all" {
  nombre = "allow_ssh"
  description = "Permitir ssh desde todas partes"

  ingreso {
    from_port = 0
    to_port = 22
    protocolo = "tcp"
    cidr_blocks = ["0.0.0.0/0"]
  }
}
recurso "aws_network_interface_sg_attachment" "sg_attachment" {
  security_group_id = "$ {aws_security_group.allow_all.id}"
  network_interface_id = "$ {aws_instance.web.primary_network_interface_id}"
}

La diferencia es impactante, ¿no? Tenga en cuenta lo fácil que es hacer referencia a otros recursos por sus ID. Con un vistazo rápido puede saber qué está sucediendo y realizar cambios básicos en la infraestructura. Lo que nos lleva muy bien a otro punto

Ronda # 2 CF: 0 TF: 1

Código de validación

CF solo permite la verificación de sintaxis. En el mejor de los casos, te dirá que te perdiste un paréntesis aquí y allá. Antes de intentar aplicar la plantilla de CloudFormation, no sabrá si todas las variables que ha utilizado se pueden resolver, pero cuál es el mayor inconveniente es que no sabe qué va a suceder.
Terraform, por otro lado, valida los archivos .tf, verifica no solo la sintaxis sino también si todas las dependencias se resuelven correctamente, ¡y le da un plan! Sí, con Terraform puedes ver lo que se creará / cambiará / destruirá antes de aplicar tu código.

Se ha generado un plan de ejecución y se muestra a continuación.
Las acciones de recursos se indican con los siguientes símbolos:
  + crear
Terraform realizará las siguientes acciones:
+ azurerm_resource_group.test_tf101
      id: 
      ubicación: "ukwest"
      nombre: "test_tf101"
      etiquetas.%: 
+ azurerm_subnet.sub1
      id: 
      dirección_prefijo: "172.16.0.8/29"
      configuraciones_IP. #: 
      nombre: "sub-1"
      network_security_group_id: 
      resource_group_name: "test_tf101"
      route_table_id: 
      virtual_network_name: "test_vnet"
Plan: 2 para agregar, 0 para cambiar, 0 para destruir.
-------------------------------------------------- ------------------

Ronda # 3 CF: 0 TF: 1

Estado remoto

Terraform le permite importar fácilmente datos de fuentes remotas, por ejemplo, otros entornos controlados en diferentes estados. Esto le permite una fácil separación de recursos y responsabilidades. Simplemente declare la fuente de información externa y use lo que sea expuesto por ella.
CloudFormation tiene la noción de referencias de pila cruzada, pero incluso pasar por la documentación es un dolor, y el ejemplo en AWS para configurar el emparejamiento de VPC es 71 líneas, en comparación con 17 en Terraform.

Ronda # 4 CF: 0 TF: 1

Las funciones

Verifique el fragmento a continuación.

recurso "aws_instance" "web" {
  # Crear una instancia para cada nombre de host
  count = "$ {length (var.hostnames)}"

  # Pase cada instancia su correspondiente template_file
  user_data = "$ {data.template.web_init. *. prestados [count.index]}"
}

Si. Terraform tiene bastantes funciones integradas que le permiten poner lógica en su código, por lo que puede construir mejor con menos código, o tener estructuras diferentes construidas usando el mismo código, pero con diferentes variables según las necesidades.

Ronda # 5 CF: 0 TF: 1

Módulos

Puede agrupar ciertos recursos que siempre usa en conjunto y crear módulos, lo que hace que sea aún más fácil declarar ciertos tipos de recursos. ¡Puede compactarlo para que declarar una VM sea solo 4 líneas de código! Además, con el "recuento" variable puede tener tantos como desee, simplemente cambiando un número.

variable "cuenta" {
  predeterminado = 2
}

recurso "aws_instance" "web" {
  # ...

  count = "$ {var.count}"

  # Etiquete la instancia con un contador que comience en 1, es decir. web-001
  etiquetas {
    Nombre = "$ {format (" web-% 03d ", count.index + 1)}"
  }
}

Ronda # 6 CF: 0 TF: 1

Trabajo en equipo

Debido a que el HCL de Terraform es como cualquier otro lenguaje de programación, es amigable con Git de una manera que atrae las solicitudes para resaltar los cambios, por lo que es cómodo hacer revisiones y colaborar en un código. Intenta hacer lo mismo con JSON, que en última instancia es una estructura de datos. La mitad de las diferencias es solo ruido repetitivo, y algo más.

Ronda # 7 CF: 0 TF: 1

Proveedores

El poder enormemente subestimado de Terraform es la capacidad de controlar cada aspecto de su infraestructura con la misma herramienta. Tiene una lista de más de 70 proveedores que puede usar, que van desde AWS, a través de Azure, hasta Gitlab, Fastly, Chef, Docker, lo que sea. Y todo está usando el mismo HCL que tienes que aprender una vez. ¡Asombroso!

Ronda # 8 CF: 0 TF: 1

Resumen

Después de 8 rondas, es

CloudFormation: 0 vs Terraform: 8.

Incluso después de agregar un punto extra, ¡incluso dos en CloudFormation por estar más cerca del resultado final de las ofertas de AWS es CF 2 TF 8, lo que significa que Terraform aplastó absolutamente a su oponente!
Estoy bastante seguro de que lo mismo se aplica a las plantillas de Azure ARM frente a Terraform, así que ahí están, dos comparaciones en una. Ahora eso es lo que yo llamo eficiencia.

Descargo de responsabilidad
Esta publicación está llena de accesos directos y probablemente también de errores y conceptos erróneos, que felizmente corregiré cuando se me indique. Me encantaría iniciar una discusión, así que tal vez hay un cebo escondido aquí o allá. Terraform FTW.