Fin qui abbiamo versionato codice, automatizzato build e test, containerizzato applicazioni, orchestrato container e descritto infrastruttura come codice. In questo modulo mettiamo tutto in un posto reale: Amazon Web Services, il cloud provider su cui gira una fetta enorme di internet.
Il cloud computing significa affittare capacità di calcolo, storage e rete da un fornitore, invece di comprare e gestire server fisici. AWS mette a disposizione centinaia di servizi, ma si possono raggruppare in tre livelli:
IaaS (Infrastructure as a Service) — affitti l'infrastruttura grezza: server virtuali, dischi, reti. Esempio: EC2. Gestisci tu il sistema operativo e tutto quello sopra.
PaaS (Platform as a Service) — il provider gestisce anche il sistema operativo e il runtime, tu porti solo il codice. Esempio: Elastic Beanstalk, App Runner.
SaaS (Software as a Service) — usi direttamente un'applicazione già pronta, senza gestire nulla sotto. Esempio: Gmail, non è AWS ma il concetto è lo stesso.
Nel corso useremo soprattutto servizi IaaS (EC2, VPC) e alcuni servizi gestiti "a metà strada" (RDS, Lambda), che tolgono lavoro operativo pur lasciandoti il controllo dell'applicazione.
Il modello di responsabilità condivisa
AWS descrive la sicurezza come una responsabilità divisa in due parti:
AWS è responsabile della sicurezza del cloud: data center fisici, hardware, rete globale, virtualizzazione.
Tu sei responsabile della sicurezza nel cloud: configurazione delle risorse, gestione degli accessi (IAM), crittografia dei dati, patch del sistema operativo sulle istanze EC2, regole del firewall.
Questo è il motivo per cui la maggior parte degli incidenti di sicurezza su AWS non nasce da un difetto di AWS, ma da configurazioni sbagliate lasciate aperte da chi usa l'account: bucket S3 pubblici per errore, chiavi IAM esposte su GitHub, security group troppo permissivi.
Regioni e Availability Zone
AWS è distribuito fisicamente in tutto il mondo, organizzato in due livelli:
Regione — un'area geografica (es. eu-west-1 è Irlanda, eu-south-1 è Milano). Ogni servizio va scelto e configurato per regione.
Availability Zone (AZ) — all'interno di una regione, un gruppo di uno o più data center fisicamente separati, con alimentazione e rete indipendenti. Ogni regione ha almeno 3 AZ.
Una regione contiene più Availability Zone isolate: distribuire le risorse su più AZ è la base della tolleranza ai guasti su AWS.
Distribuire un'applicazione su più AZ è la tecnica più semplice ed efficace per renderla resiliente: se un intero data center ha un problema, il traffico continua a essere servito dalle altre zone.
Creare l'account e proteggere il root user
Alla creazione di un account AWS ottieni un utente speciale chiamato root user, associato all'email con cui ti sei registrato. Il root user ha accesso illimitato a tutto l'account, compresa la fatturazione.
Non usare mai il root user per il lavoro quotidiano. È buona pratica: attivare subito l'MFA (autenticazione a due fattori) sul root, non creare chiavi di accesso programmatiche per il root, e creare invece un utente IAM amministrativo da usare al suo posto.
Passaggi consigliati appena creato l'account:
Attiva l'MFA sul root user (Security Credentials → Multi-Factor Authentication).
Imposta un budget e un allarme di fatturazione (ne parliamo più avanti).
Crea un utente IAM con permessi amministrativi e usa quello da qui in poi.
IAM: utenti, gruppi, ruoli e policy
IAM (Identity and Access Management) è il servizio che controlla chi può fare cosa nel tuo account. È probabilmente il servizio più importante da capire bene, perché sta alla base della sicurezza di tutto il resto.
I concetti principali
Utente (User) — un'identità singola, di solito una persona o un servizio esterno. Ha credenziali proprie (password per la console, chiavi di accesso per la CLI/API).
Gruppo (Group) — un insieme di utenti. Le policy si assegnano al gruppo e si applicano automaticamente a tutti i membri.
Ruolo (Role) — un'identità temporanea che può essere assunta da utenti, servizi AWS (come EC2 o Lambda) o account esterni. Non ha credenziali fisse: chi lo assume riceve credenziali temporanee.
Policy — un documento JSON che descrive quali azioni sono permesse o negate, su quali risorse.
Questa policy permette di leggere e scrivere oggetti solo dentro il bucket corso-devops-bucket, nient'altro. È l'esempio pratico del principio del minimo privilegio: dare solo i permessi strettamente necessari, mai "Action": "*" su "Resource": "*" a meno che non sia davvero indispensabile.
Creare un utente IAM (console)
Vai su IAM → Users → Create user.
Dai un nome, ad esempio andrea-admin.
Scegli se serve accesso alla console, accesso programmatico, o entrambi.
Assegna un gruppo con la policy AdministratorAccess (solo per l'utente amministrativo iniziale; per tutto il resto, policy più specifiche).
Attiva l'MFA anche su questo utente.
Ruoli: perché sono meglio delle chiavi
Quando un'istanza EC2 o una funzione Lambda deve accedere ad altri servizi AWS (es. leggere da S3), la pratica corretta è assegnare un ruolo IAM alla risorsa, non incollare chiavi di accesso nel codice o nelle variabili d'ambiente. Il ruolo fornisce credenziali temporanee, ruotate automaticamente, senza che nessuna chiave venga mai scritta su disco o commitata per errore su Git.
Regola pratica: se ti stai chiedendo "dove metto la Access Key ID e la Secret Access Key nel codice", la risposta quasi sempre giusta è: da nessuna parte, usa un ruolo IAM.
AWS CLI
La AWS CLI permette di gestire l'account da terminale, utile sia per lavoro manuale veloce sia per script di automazione.
Installazione (macOS)
brew install awscli
aws --version
Configurazione delle credenziali
aws configure
Il comando chiede quattro valori:
AWS Access Key ID e AWS Secret Access Key — generati per il tuo utente IAM in IAM → Security credentials.
Default region — es. eu-west-1.
Default output format — es. json.
Le credenziali vengono salvate in ~/.aws/credentials. Per verificare che tutto funzioni:
aws sts get-caller-identity
Il file ~/.aws/credentials e qualunque chiave AWS non vanno mai committati su Git. Se una chiave finisce per errore in una repository pubblica, disattivala immediatamente da IAM e generane una nuova.
VPC: la rete privata
Una VPC (Virtual Private Cloud) è una rete privata isolata, tutta tua, dentro AWS. Ogni risorsa "di rete" (EC2, RDS, load balancer) vive dentro una VPC. Ogni account ha una VPC di default già pronta, ma in un progetto reale conviene crearne una su misura.
I mattoncini di una VPC
CIDR block — l'intervallo di indirizzi IP della VPC, es. 10.0.0.0/16 (circa 65.000 indirizzi).
Subnet — una porzione della VPC, associata a una singola Availability Zone. Si dividono in pubbliche (raggiungibili da internet) e private (non raggiungibili direttamente).
Internet Gateway (IGW) — il "portone" che collega la VPC a internet. Serve alle subnet pubbliche.
NAT Gateway — permette alle risorse in subnet private di raggiungere internet in uscita (es. per scaricare aggiornamenti), senza essere raggiungibili dall'esterno.
Route table — le regole che dicono al traffico dove andare; una subnet è "pubblica" perché la sua route table punta all'Internet Gateway.
Security Group — un firewall a livello di singola risorsa (istanza, database): regole solo di tipo "consenti", con stato (se il traffico in entrata è permesso, la risposta in uscita lo è automaticamente).
Network ACL — un firewall a livello di subnet, senza stato: puoi sia consentire sia negare esplicitamente, utile come ulteriore livello di sicurezza.
Schema tipico a due livelli: subnet pubblica per ciò che deve essere raggiungibile da internet, subnet privata per applicazione e database.
In pratica, quasi nessuno crea una VPC a mano comando per comando: si usa Terraform (modulo 06) o la console per i primi esperimenti, poi si passa all'Infrastructure as Code.
EC2: server virtuali
EC2 (Elastic Compute Cloud) è il servizio che affitta server virtuali, chiamati istanze. È il servizio AWS più fondamentale: praticamente ogni altro servizio di calcolo (ECS, EKS, RDS) gira sopra istanze EC2 dietro le quinte.
Concetti chiave
AMI (Amazon Machine Image) — il "modello" di partenza dell'istanza: sistema operativo più software preinstallato. Puoi usare AMI ufficiali (Ubuntu, Amazon Linux) o crearne di personalizzate.
Instance type — la combinazione di CPU, RAM e rete, es. t3.micro (piccola, nel Free Tier), m5.large (uso generale), c5.xlarge (ottimizzata CPU).
Key pair — la coppia di chiavi usata per accedere via SSH: la chiave pubblica resta su AWS, quella privata la scarichi tu una sola volta.
Security Group — il firewall dell'istanza: es. "consenti SSH (porta 22) solo dal mio IP", "consenti HTTP (porta 80) da chiunque".
Elastic IP — un indirizzo IP pubblico statico, che resta lo stesso anche se riavvii l'istanza.
User data — uno script che gira automaticamente al primo avvio dell'istanza, utile per installare software senza intervento manuale.
Su un'istanza Ubuntu l'utente predefinito è ubuntu; su Amazon Linux è ec2-user. chmod 400 è obbligatorio: SSH rifiuta chiavi private con permessi troppo aperti.
Esempio di user data
Per installare Node.js e avviare l'app del modulo GitHub Actions in automatico all'avvio:
#!/bin/bash
sudo apt update -y
sudo apt install -y nodejs npm
cd /home/ubuntu
git clone https://github.com/utente/progetto.git
cd progetto
npm install
npm run start &
EBS: dischi per EC2
EBS (Elastic Block Store) è lo storage a blocchi collegato alle istanze EC2 — l'equivalente di un disco rigido virtuale. Ogni istanza ha almeno un volume EBS come disco principale (root volume).
I dati su EBS sopravvivono allo spegnimento dell'istanza (a differenza dello storage "instance store", effimero).
Si possono creare snapshot, backup puntuali del volume, salvati su S3 dietro le quinte.
Un volume EBS si può ridimensionare e cambiare tipo di performance senza spegnere l'istanza.
S3 (Simple Storage Service) è lo storage a oggetti di AWS: file di qualsiasi tipo e dimensione, organizzati in bucket. È probabilmente il servizio AWS più usato in assoluto, anche da chi non tocca mai EC2: backup, asset statici, log, dataset, siti web statici.
Concetti chiave
Bucket — un contenitore con nome globalmente unico su tutto AWS (non solo nel tuo account).
Oggetto — il singolo file, identificato da una chiave (il suo "percorso" dentro il bucket).
Storage class — la "categoria" di costo/velocità: Standard (accesso frequente), Standard-IA (accesso poco frequente), Glacier (archiviazione a lungo termine, recupero lento ma economico).
Versioning — se attivo, ogni sovrascrittura crea una nuova versione invece di cancellare quella vecchia.
Lifecycle rule — regole automatiche per spostare o eliminare oggetti dopo un certo periodo (es. "sposta su Glacier dopo 90 giorni").
Bucket policy — chi può leggere/scrivere nel bucket, definita come le policy IAM ma a livello di bucket.
Un bucket pubblico va bene per un sito statico pensato per essere pubblico, ma è la causa più comune di fughe di dati su AWS quando viene applicato per errore a bucket che contengono dati sensibili. Controlla sempre "Block public access" prima di renderlo pubblico consapevolmente.
RDS: database gestiti
RDS (Relational Database Service) gestisce database relazionali (PostgreSQL, MySQL, MariaDB, SQL Server, Oracle) senza che tu debba occuparti di patching, backup manuali o replica.
Multi-AZ — RDS mantiene una copia sincronizzata del database in un'altra Availability Zone; in caso di guasto, il failover verso la copia è automatico.
Read replica — copie in sola lettura del database, utili per distribuire il carico delle query di lettura senza toccare il database primario.
Backup automatici e snapshot — RDS esegue backup incrementali giornalieri automaticamente, oltre a permettere snapshot manuali prima di operazioni rischiose.
In produzione, la connessione dall'applicazione a RDS passa dalla subnet privata della VPC (vedi il diagramma sopra): il database non deve avere un indirizzo IP pubblico raggiungibile da internet.
Load Balancer e Auto Scaling
Quando un'applicazione gira su più istanze EC2, serve qualcosa che distribuisca il traffico tra loro e che sostituisca automaticamente le istanze in difficoltà.
Elastic Load Balancing (ELB)
Application Load Balancer (ALB) — lavora a livello HTTP/HTTPS, capisce percorsi e header, ideale per applicazioni web e API.
Network Load Balancer (NLB) — lavora a livello di rete (TCP), pensato per throughput altissimo e bassa latenza.
Target Group — l'insieme di istanze (o container) a cui l'ALB inoltra il traffico, con un health check che verifica periodicamente che siano ancora sane.
Auto Scaling Group (ASG)
Un Auto Scaling Group mantiene automaticamente un certo numero di istanze EC2 in esecuzione, basandosi su una launch template (che descrive come creare una nuova istanza identica alle altre) e su regole di scala:
Policy di scalabilità — es. "aggiungi un'istanza se la CPU media supera il 70% per 5 minuti".
Self-healing — se un'istanza fallisce l'health check, l'ASG la termina e ne crea automaticamente una nuova al suo posto.
Load Balancer + Auto Scaling Group è la combinazione classica per rendere un'applicazione EC2 resiliente e scalabile senza intervento manuale: esattamente lo stesso principio delle replicas e del readinessProbe visti nel modulo Kubernetes, applicato a livello di macchine virtuali invece che di Pod.
Route 53: DNS
Route 53 è il servizio DNS di AWS: traduce nomi a dominio (es. corso-devops.it) in indirizzi IP o in altre risorse AWS.
Hosted zone — il contenitore dei record DNS di un dominio.
Record A — punta un dominio a un indirizzo IP.
Record CNAME / ALIAS — punta un dominio a un altro nome a dominio; l'ALIAS è la versione "AWS-native", gratuita e utilizzabile anche sulla root del dominio, a differenza del CNAME standard.
Routing policy — non solo un semplice A record: si possono impostare policy di routing basate su geolocalizzazione, latenza, weighted (percentuale di traffico) o failover automatico.
CloudFront è la rete di distribuzione dei contenuti (CDN) di AWS: copia i tuoi contenuti (statici o dinamici) sui suoi edge location sparsi nel mondo, così ogni utente li scarica dal punto più vicino a lui invece che dal server originale.
Origin — la fonte reale dei contenuti: un bucket S3, un Load Balancer, un server qualsiasi.
Cache behavior — regole su cosa e per quanto tempo mettere in cache.
Si abbina naturalmente a S3 per servire siti statici globalmente veloci, e a Route 53 per il dominio personalizzato con HTTPS.
Lambda e API Gateway
Lambda esegue codice senza che tu debba gestire alcun server: carichi una funzione, AWS la esegue quando serve e la fattura solo per il tempo effettivo di esecuzione. È il servizio "serverless" per eccellenza.
Come si attiva una funzione Lambda
Una richiesta HTTP tramite API Gateway;
Un evento su S3 (es. "esegui questa funzione ogni volta che viene caricato un file");
Lambda è ideale per compiti brevi ed episodici (webhook, elaborazione immagini, API leggere). Per applicazioni sempre attive con traffico costante, EC2 o i container (sotto) restano spesso più economici e prevedibili.
ECS, Fargate ed EKS
Dopo aver visto Docker e Kubernetes nei moduli precedenti, su AWS ci sono tre modi principali per eseguire container in produzione:
ECS (Elastic Container Service) — l'orchestratore di container "nativo" di AWS, più semplice di Kubernetes, ottimo se non serve tutta la flessibilità di K8s.
Fargate — una modalità di esecuzione per ECS (e per EKS) in cui non gestisci nemmeno le istanze EC2 sotto: specifichi solo CPU e memoria del container, AWS pensa al resto.
EKS (Elastic Kubernetes Service) — Kubernetes gestito da AWS: stessi concetti visti nel modulo Kubernetes (Pod, Deployment, Service), ma con il control plane gestito da AWS invece che da Minikube in locale.
Il file deployment.yaml e service.yaml scritti nel modulo Kubernetes funzionano, con pochissime modifiche, anche su un cluster EKS reale: è uno dei motivi per cui vale la pena imparare Kubernetes prima di scegliere un cloud specifico.
CloudWatch: monitoraggio
CloudWatch raccoglie metriche, log e allarmi da (quasi) tutti i servizi AWS.
Metriche — dati numerici nel tempo: CPU di un'istanza EC2, connessioni a un database RDS, richieste su un Load Balancer.
Log — CloudWatch Logs raccoglie i log applicativi (es. dall'output di un container o di una funzione Lambda) in un unico posto interrogabile.
Allarmi — regole che notificano (via email, SMS, o innescando un'azione automatica) quando una metrica supera una soglia, es. "CPU sopra il 90% per 10 minuti".
Dashboard — pannelli visivi personalizzabili con più metriche insieme.
Mettendo insieme i servizi visti finora, ecco come potrebbe apparire un'applicazione web reale in produzione su AWS:
Route 53 risolve il dominio, CloudFront serve i contenuti dal punto più vicino all'utente, l'ALB smista il traffico tra i container/istanze in due AZ diverse, che leggono/scrivono su RDS ed espongono i propri log e metriche a CloudWatch.
Costi e Free Tier
AWS fattura quasi tutto "a consumo": si paga per quello che si usa, spesso al secondo o all'ora. Il Free Tier offre una quota gratuita su molti servizi per i primi 12 mesi (e alcuni servizi gratuiti sempre, entro certi limiti), utile per esercitarsi senza spendere.
Come tenere sotto controllo la spesa
In Billing → Budgets, crea un budget mensile con notifica quando superi una soglia (es. avviso al superamento di 5€).
Ricorda di spegnere o eliminare le risorse create per esercitarti: istanze EC2 fermate ma non terminate continuano comunque a costare per lo storage EBS collegato.
Un NAT Gateway, un Elastic IP non associato a un'istanza, e RDS Multi-AZ sono tra le voci di costo più spesso dimenticate accese per errore.
Prima di chiudere una sessione di pratica, controlla EC2, RDS, NAT Gateway ed Elastic IP: sono le risorse che più spesso continuano silenziosamente a generare costi anche quando "sembra" che tu abbia finito.
AWS con Terraform
Il modulo precedente ha già mostrato come dichiarare un'istanza EC2 con Terraform usando il provider aws. Con i concetti di questo modulo, quello stesso file inizia ad avere senso completo:
Ogni riga di questo file corrisponde a un servizio spiegato in questo modulo: VPC, subnet, security group, istanza EC2. È lo stesso identico risultato che otterresti cliccando manualmente nella console AWS, ma scritto, versionato, e riproducibile con terraform apply.
Cosa abbiamo imparato
Il modello di responsabilità condivisa, regioni e Availability Zone, come proteggere l'account con IAM, configurare la CLI, costruire una VPC con subnet pubbliche e private, lanciare istanze EC2, salvare dati su S3, gestire database con RDS, distribuire il carico con Load Balancer e Auto Scaling, risolvere domini con Route 53, distribuire contenuti con CloudFront, eseguire codice serverless con Lambda, orchestrare container con ECS/EKS e monitorare tutto con CloudWatch. Con questo modulo il corso è completo dal primo git init fino a un'infrastruttura cloud reale, sicura e riproducibile.