CloudFormation vs Terraform

Terraform è superiore a CloudFormation in ogni scenario, tranne quando è assolutamente necessario utilizzare le funzionalità all'avanguardia di AWS. Ecco perché.

Curva di apprendimento:

Penso che la maggior parte delle persone apprenda nuove tecnologie, seguendo tutorial o guardando esempi. Questo è abbastanza facile da fare con la maggior parte dei linguaggi di programmazione, almeno per un livello base.
Non con CloudFormation. È formattato JSON (o YAML). È stato progettato per essere consumato e prodotto dai computer, non dagli umani. Provalo tu stesso, di seguito è riportato un esempio di frammento di codice necessario per eseguire il rollup di un'istanza EC2 (sostanzialmente una VM):

{
  "AWSTemplateFormatVersion": "2010-09-09",
....
150 linee di bla bla bla ...
....
  },

  "Risorse": {
    "EC2Instance": {
      "Tipo": "AWS :: EC2 :: Istanza",
      "Proprietà" : {
        "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",
      "Proprietà" : {
        "GroupDescription": "Abilita accesso SSH",
        "SecurityGroupIngress":
          [{"IpProtocol": "tcp", "FromPort": "22", "ToPort": "22", "CidrIp": {"Ref": "SSHLocation"}}]
      }
    },

    "Indirizzo IP" : {
      "Tipo": "AWS :: EC2 :: EIP"
    },

    "IPAssoc": {
      "Tipo": "AWS :: EC2 :: EIPAssociation",
      "Proprietà" : {
        "InstanceId": {"Ref": "EC2Instance"},
        "EIP": {"Ref": "IndirizzoIP"}
      }
    }
  },
  "Output": {
    "InstanceId": {
      "Descrizione": "InstanceId dell'istanza EC2 appena creata",
      "Value": {"Ref": "EC2Instance"}
    },
    "InstanceIPAddress": {
      "Descrizione": "indirizzo IP dell'istanza EC2 appena creata",
      "Valore": {"Rif.": "Indirizzo IP"}
    }
  }
}

Cattiva. 210 righe di codice per ottenere una VM con IP pubblico protetto da Security Group. 210. 210! Con ogni modello c'è un'enorme quantità di codice del boilerplate, che è fondamentalmente rumore (ne parleremo più avanti).
Se questo non è abbastanza per scoraggiarti in questa fase, dai un'occhiata alla documentazione ufficiale. Ora si è spostato verso l'utilizzo di YAML, ma quando si desidera esaminare i frammenti di esempio, si scopre che sono tutti in JSON. Lo stesso vale per i risultati di Google.
BTW. quando hai diversi frammenti di campione per regione, puoi dire qualcosa di sospetto

Round # 1: CF: 0 TF: 1

Codice di scrittura

Praticamente gli stessi argomenti di cui sopra si applicano alla scrittura del codice stesso. Per un rapido esempio, dai un'occhiata esattamente alle stesse risorse di cui sopra, ma descritte in Terraform:

risorsa "aws_instance" "web" {
  ami = "12345-6789-10"
  instance_type = "t2.micro"

  tag {
    Nome = "Dolce"
  }
}
data "aws_eip" "pip" {
  public_ip = "1.1.1.1"
}

risorsa "aws_eip_association" "pip" {
  instance_id = "$ {aws_instance.web.id}"
  allocation_id = "$ {data.aws_eip.pip.id}"
}
risorsa "aws_security_group" "allow_all" {
  name = "allow_ssh"
  description = "Permetti a ssh da ogni parte"

  ingresso {
    from_port = 0
    to_port = 22
    protocollo = "tcp"
    cidr_blocks = ["0.0.0.0/0"]
  }
}
risorsa "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 differenza è scioccante, no? Nota quanto è facile fare riferimento ad altre risorse tramite i loro ID. Con una rapida occhiata puoi dire cosa sta succedendo e apportare modifiche di base all'infrastruttura. Il che ci porta benissimo ad un altro punto

Round # 2 CF: 0 TF: 1

Codice di convalida

CF consente solo il controllo della sintassi. Quindi, nella migliore delle ipotesi, ti dirà che hai perso una parentesi qua e là. Prima di provare ad applicare il modello CloudFormation non saprai se ogni variabile che hai utilizzato è risolvibile, ma qual è il più grande svantaggio è che non sai cosa accadrà.
Terraform d'altra parte, convalida i file .tf, controllando non solo la sintassi ma anche se tutte le dipendenze si risolvono correttamente e ti dà un piano! Sì, con Terraform puoi effettivamente vedere cosa verrà creato / modificato / distrutto prima di applicare il tuo codice!

È stato generato un piano di esecuzione che viene mostrato di seguito.
Le azioni delle risorse sono indicate con i seguenti simboli:
  + crea
Terraform eseguirà le seguenti azioni:
+ azurerm_resource_group.test_tf101
      id: 
      località: "ukwest"
      nome: "test_tf101"
      tag.%: 
+ azurerm_subnet.sub1
      id: 
      address_prefix: "172.16.0.8/29"
      ip_configurations. #: 
      nome: "sub-1"
      network_security_group_id: 
      nome_gruppo_risorse: "test_tf101"
      route_table_id: 
      virtual_network_name: "test_vnet"
Piano: 2 per aggiungere, 0 per cambiare, 0 per distruggere.
-------------------------------------------------- ------------------

Round # 3 CF: 0 TF: 1

Stato remoto

Terraform consente di importare facilmente dati da fonti remote, ad esempio altri ambienti controllati in stati diversi. Ciò consente una facile separazione delle risorse e delle responsabilità. Dichiarare semplicemente la fonte di informazioni esterne e utilizzare tutto ciò che viene esposto.
CloudFormation ha nozioni di riferimenti incrociati, ma anche superare la documentazione è una seccatura, e l'esempio su AWS per impostare il peering VPC è di 71 linee, rispetto alle 17 di Terraform.

Round # 4 CF: 0 TF: 1

funzioni

Controlla lo snippet di seguito.

risorsa "aws_instance" "web" {
  # Crea un'istanza per ciascun nome host
  count = "$ {length (var.hostnames)}"

  # Passa a ogni istanza il corrispondente file_file
  user_data = "$ {data.template.web_init. *. rendering [count.index]}"
}

Sì. Terraform ha alcune funzioni integrate che ti consentono di mettere la logica nel tuo codice, quindi puoi costruire meglio con meno codice o avere strutture diverse costruite usando lo stesso codice, ma con variabili diverse in base alle esigenze.

Round # 5 CF: 0 TF: 1

moduli

Puoi raggruppare determinate risorse che usi sempre insieme e creare moduli, rendendo ancora più semplice dichiarare determinati tipi di risorse. Potresti compattarlo in modo che dichiarare una VM sia solo 4 righe di codice! Inoltre, usando la variabile "count" puoi averne quanti ne vuoi, semplicemente cambiando un numero.

variabile "count" {
  impostazione predefinita = 2
}

risorsa "aws_instance" "web" {
  # ...

  count = "$ {var.count}"

  # Contrassegna l'istanza con un contatore che inizia da 1, ad es. web-001
  tag {
    Nome = "$ {format (" web-% 03d ", count.index + 1)}"
  }
}

Round # 6 CF: 0 TF: 1

Lavoro di squadra

Poiché l'HCL di Terraform è come qualsiasi altro linguaggio di programmazione, è Git friendly in un modo che tira le richieste in modo da evidenziare le modifiche, quindi è comodo fare recensioni e collaborare su un pezzo di codice. Prova a fare lo stesso con JSON che alla fine è una struttura di dati. La metà dei diff è solo il rumore da placca, e poi alcuni.

Round # 7 CF: 0 TF: 1

provider

Il potere ampiamente sottovalutato di Terraform è la capacità di controllare ogni aspetto della tua infrastruttura con lo stesso strumento. Hai un elenco di oltre 70 provider che puoi usare, che vanno da AWS, tramite Azure, a Gitlab, Fastly, Chef, Docker, il nome. Ed è tutto usando lo stesso HCL che devi imparare una volta. Sorprendente!

Round # 8 CF: 0 TF: 1

Sommario

Dopo 8 round, lo è

CloudFormation: 0 vs Terraform: 8.

Anche dopo aver aggiunto un punto in più, diamine anche due a CloudFormation per essere più vicino al risultato finale delle offerte AWS è CF 2 TF 8, il che significa che Terraform ha assolutamente schiacciato il suo avversario!
Sono abbastanza sicuro che lo stesso vale per i modelli ARM di Azure rispetto a Terraform, quindi eccolo qui, due confronti in uno. Questo è ciò che chiamo efficienza.

Clausola di esclusione della responsabilità
Questo post è pieno di scorciatoie e probabilmente anche errori e idee sbagliate, che correggerò felicemente quando indicato. Mi piacerebbe innescare una discussione, quindi forse c'è un'esca nascosta qui o là. Terraform FTW.