Introduzione all'Infrastructure as Code con Terraform e Hetzner Cloud

L'Infrastructure as Code (IaC) rappresenta una delle evoluzioni più significative nel mondo del cloud computing moderno. In questo articolo esploreremo come utilizzare Terraform insieme ad Hetzner Cloud per gestire la tua infrastruttura in modo efficiente, scalabile e riproducibile.

Che cos'è l'Infrastructure as Code

L'Infrastructure as Code è una metodologia che consente di gestire e provisioning delle risorse IT attraverso codice leggibile dalla macchina, piuttosto che attraverso processi manuali o configurazioni interattive. Questa approccio trasforma la gestione dell'infrastruttura da un'attività manuale e soggetta a errori in un processo automatizzato, versionabile e ripetibile.

I principali vantaggi dell'IaC includono:

  • Consistenza: L'infrastruttura viene creata sempre nello stesso modo, eliminando le variazioni dovute a errori umani
  • Versionabilità: Le modifiche all'infrastruttura possono essere tracciate attraverso sistemi di controllo versione come Git
  • Riproducibilità: È possibile ricreare ambienti identici per sviluppo, test e produzione
  • Scalabilità: La creazione di nuove risorse diventa un'operazione rapida e standardizzata
  • Documentazione: Il codice stesso serve da documentazione dell'infrastruttura

Terraform: Il Linguaggio dell'Infrastructure as Code

Terraform è uno strumento open-source sviluppato da HashiCorp che consente di definire l'infrastruttura cloud attraverso file di configurazione dichiarativi. Utilizza un linguaggio di configurazione chiamato HashiCorp Configuration Language (HCL), che risulta sia leggibile dall'uomo che interpretabile dalla macchina.

Caratteristiche Principali di Terraform

Terraform si distingue per diverse caratteristiche che lo rendono uno degli strumento IaC più popolari:

  • Multi-cloud: Supporta centinaia di provider cloud diversi, incluso Hetzner Cloud
  • Stato dell'infrastruttura: Mantiene un file di stato che tiene traccia delle risorse gestite
  • Pianificazione: Mostra un piano delle modifiche prima di applicarle
  • Dependency management: Gestisce automaticamente le dipendenze tra le risorse
  • Moduli: Consente la creazione di componenti riutilizzabili

Il Workflow di Terraform

Il flusso di lavoro di Terraform segue quattro fasi principali:

  1. Write: Definizione dell'infrastruttura in file .tf
  2. Plan: Creazione di un piano di esecuzione
  3. Apply: Applicazione delle modifiche
  4. Destroy: Rimozione delle risorse quando non più necessarie

Hetzner Cloud: Un Provider Cloud Efficiente

Hetzner Cloud è una piattaforma cloud europea che offre servizi di cloud computing ad alte prestazioni con un eccellente rapporto qualità-prezzo. Basata su data center ubicati in Germania e Finlandia, Hetzner Cloud fornisce server virtuali, storage, networking e servizi correlati con particolare attenzione alla sostenibilità ambientale.

Vantaggi di Hetzner Cloud

  • Prezzi competitivi: Costi significativamente inferiori rispetto ai principali cloud provider
  • Performance elevate: Server con processori AMD EPYC e storage NVMe
  • Semplicità: Interfaccia intuitiva e API ben documentate
  • Conformità GDPR: Data center europei con piena conformità alle normative
  • Sostenibilità: Alimentazione da fonti rinnovabili al 100%

Configurazione Iniziale

Installazione di Terraform

Prima di iniziare, è necessario installare Terraform sul proprio sistema. Il processo varia a seconda del sistema operativo utilizzato.

Per sistemi Linux basati su Debian/Ubuntu:

wget -O- https://apt.releases.hashicorp.com/gpg | gpg --dearmor | sudo tee /usr/share/keyrings/hashicorp-archive-keyring.gpg
echo "deb [signed-by=/usr/share/keyrings/hashicorp-archive-keyring.gpg] https://apt.releases.hashicorp.com $(lsb_release -cs) main" | sudo tee /etc/apt/sources.list.d/hashicorp.list
sudo apt update && sudo apt install terraform

Per verificare l'installazione:

terraform version

Configurazione del Provider Hetzner

Per utilizzare Terraform con Hetzner Cloud, è necessario ottenere un token API dal pannello di controllo di Hetzner. Questo token deve essere configurato come variabile d'ambiente o direttamente nel codice Terraform.

Creazione del token API:

  1. Accedere al pannello di controllo Hetzner Cloud
  2. Navigare verso "Security" → "API Tokens"
  3. Creare un nuovo token con i permessi appropriati
  4. Copiare il token generato

Configurazione della variabile d'ambiente:

export HCLOUD_TOKEN="your-api-token-here"

Primo Progetto Terraform con Hetzner Cloud

Struttura del Progetto

Iniziamo creando la struttura base del nostro primo progetto Terraform:

mkdir hetzner-terraform-demo
cd hetzner-terraform-demo
touch main.tf variables.tf outputs.tf terraform.tfvars

Configurazione del Provider

Nel file main.tf, definiamo la configurazione del provider Hetzner:

terraform {
  required_version = ">= 1.0"
  required_providers {
    hcloud = {
      source  = "hetznercloud/hcloud"
      version = "~> 1.44"
    }
  }
}

provider "hcloud" {
  token = var.hcloud_token
}

Definizione delle Variabili

Nel file variables.tf:

variable "hcloud_token" {
  description = "Hetzner Cloud API Token"
  type        = string
  sensitive   = true
}

variable "location" {
  description = "Server location"
  type        = string
  default     = "nbg1"
}

variable "server_type" {
  description = "Server type"
  type        = string
  default     = "cx11"
}

Creazione di un Server

Aggiungiamo al file main.tf la configurazione per creare un server:

# SSH Key per l'accesso al server
resource "hcloud_ssh_key" "default" {
  name       = "terraform-key"
  public_key = file("~/.ssh/id_rsa.pub")
}

# Server principale
resource "hcloud_server" "web_server" {
  name        = "web-server-01"
  image       = "ubuntu-22.04"
  server_type = var.server_type
  location    = var.location
  ssh_keys    = [hcloud_ssh_key.default.id]

  labels = {
    environment = "demo"
    project     = "terraform-intro"
  }

  user_data = file("${path.module}/cloud-init.yml")
}

Configurazione Cloud-Init

Creiamo un file cloud-init.yml per la configurazione iniziale del server:

#cloud-config
package_update: true
package_upgrade: true

packages:
  - nginx
  - htop
  - curl

runcmd:
  - systemctl enable nginx
  - systemctl start nginx
  - echo "

Server configurato con Terraform e Hetzner Cloud

" > /var/www/html/index.html

Output delle Risorse

Nel file outputs.tf definiamo gli output utili:

output "server_ip" {
  description = "IP pubblico del server"
  value       = hcloud_server.web_server.ipv4_address
}

output "server_status" {
  description = "Status del server"
  value       = hcloud_server.web_server.status
}

Deployment e Gestione

Inizializzazione del Progetto

Prima di poter utilizzare Terraform, è necessario inizializzare il progetto:

terraform init

Questo comando scaricherà il provider Hetzner e preparerà l'ambiente di lavoro.

Pianificazione delle Modifiche

Per vedere cosa verrà creato senza applicare effettivamente le modifiche:

terraform plan

Terraform mostrerà un piano dettagliato delle risorse che verranno create, modificate o eliminate.

Applicazione della Configurazione

Per creare effettivamente le risorse:

terraform apply

Terraform chiederà conferma prima di procedere. Dopo l'applicazione, mostrerà gli output definiti, incluso l'indirizzo IP del server creato.

Gestione Avanzata dell'Infrastruttura

Networking e Sicurezza

Per un'infrastruttura più robusta, aggiungiamo elementi di networking e sicurezza:

# Rete privata
resource "hcloud_network" "private_network" {
  name     = "terraform-network"
  ip_range = "10.0.0.0/16"
}

resource "hcloud_network_subnet" "private_subnet" {
  type         = "cloud"
  network_id   = hcloud_network.private_network.id
  network_zone = "eu-central"
  ip_range     = "10.0.1.0/24"
}

# Firewall
resource "hcloud_firewall" "web_firewall" {
  name = "web-server-firewall"
  
  rule {
    direction = "in"
    port      = "22"
    protocol  = "tcp"
    source_ips = ["0.0.0.0/0", "::/0"]
  }
  
  rule {
    direction = "in"
    port      = "80"
    protocol  = "tcp"
    source_ips = ["0.0.0.0/0", "::/0"]
  }
  
  rule {
    direction = "in"
    port      = "443"
    protocol  = "tcp"
    source_ips = ["0.0.0.0/0", "::/0"]
  }
}

Moduli Riutilizzabili

Per progetti più complessi, è utile organizzare il codice in moduli. Creiamo una struttura modulare:

mkdir modules/web-server
touch modules/web-server/main.tf
touch modules/web-server/variables.tf
touch modules/web-server/outputs.tf

Nel file modules/web-server/main.tf:

resource "hcloud_server" "server" {
  name        = var.server_name
  image       = var.image
  server_type = var.server_type
  location    = var.location
  ssh_keys    = var.ssh_keys
  
  network {
    network_id = var.network_id
    ip         = var.private_ip
  }
  
  firewall_ids = var.firewall_ids
  
  labels = var.labels
  
  user_data = var.user_data
}

Best Practices e Considerazioni

Gestione dello Stato

Per progetti in team, è fondamentale utilizzare un backend remoto per lo stato di Terraform:

terraform {
  backend "s3" {
    bucket = "terraform-state-bucket"
    key    = "hetzner/terraform.tfstate"
    region = "eu-central-1"
  }
}

Sicurezza

  • Non includere mai token o credenziali nel codice
  • Utilizzare variabili d'ambiente o sistemi di gestione segreti
  • Implementare il principio del minimo privilegio
  • Utilizzare firewall e gruppi di sicurezza appropriati

Organizzazione del Codice

  • Separare gli ambienti (dev, staging, production) in directory diverse
  • Utilizzare moduli per componenti riutilizzabili
  • Mantenere file di configurazione piccoli e focalizzati
  • Utilizzare nomi di risorse descriptivi e consistenti

Monitoraggio e Manutenzione

Una volta deployata l'infrastruttura, è importante mantenere il controllo delle risorse