Salta al contenuto principale

Buone pratiche

Definisci tutta l'infrastruttura come codice sotto controllo di versione

Fai il provisioning di ogni risorsa tramite Infrastructure as Code dichiarativa tenuta sotto controllo di versione, mai cliccando in una console, così che gli ambienti siano riproducibili, revisionabili e auditabili. Le modifiche manuali causano un drift che nessuno può ricostruire dopo un incidente. Fai: dichiara un VPC, le subnet e le istanze in un modulo Terraform revisionato via pull request e applicato da una pipeline. Non fare: creare a mano un database di produzione in console e provare a ricordarne le impostazioni in seguito.

Tratta i server come immutabili e sostituiscili anziché applicare patch

Costruisci una nuova immagine e distribuisci istanze fresche per cambiare un sistema in esecuzione, invece di mutare i server live sul posto, così elimini il drift di configurazione e rendi il rollback un nuovo deploy dell'immagine precedente. Le patch sul posto producono server snowflake, di cui non ce ne sono due uguali. Fai: crea una nuova immagine golden o immagine di container, poi esegui una sostituzione rolling. Non fare: collegarti in SSH alla produzione per modificare file di config e installare pacchetti al volo.

Distribuisci i carichi su almeno due availability zone

Distribuisci istanze, repliche e standby di database su due o più availability zone così che la perdita di un singolo data center non abbatta il tuo servizio. Un deployment a singola AZ è un single point of failure per quante istanze abbia. Fai: fai girare il tier applicativo e uno standby di database in AZ separate dietro un load balancer. Non fare: mettere tutte le repliche in una zona perché è marginalmente più economico o semplice.

Tieni le risorse di backend in subnet private

Colloca server applicativi, database e servizi interni in subnet private senza IP pubblico né rotta in entrata da internet, esponendo pubblicamente solo un load balancer o un gateway e usando un NAT gateway per il traffico in uscita. I backend direttamente raggiungibili da internet allargano drasticamente la superficie d'attacco. Fai: metti il database in una subnet privata raggiungibile solo dal security group del tier applicativo. Non fare: assegnare un IP pubblico a un database "solo per collegarmi velocemente".

Applica IAM a privilegio minimo ovunque

Concedi a ogni identità solo i permessi di cui ha davvero bisogno, limitati a risorse specifiche, e preferisci identità di carico a vita breve rispetto a chiavi statiche a lunga vita. Permessi ampi con wildcard trasformano una singola compromissione in una violazione completa dell'account. Fai: dai a un servizio un ruolo che consente la lettura su un solo bucket specifico. Non fare: assegnare una policy di amministratore a un'applicazione "per farla funzionare per ora".

Conserva i segreti in un secrets manager, mai nel codice o nelle immagini

Tieni credenziali, token e chiavi in un secrets manager dedicato e iniettali a runtime, con rotazione e accessi auditati, anziché incorporarli nel sorgente, nelle immagini di container o nei file IaC. I segreti committati in un repository o cotti dentro un'immagine trapelano ampiamente e sono difficili da revocare. Fai: leggi la password del database da un secrets manager tramite il ruolo dell'istanza all'avvio. Non fare: scrivere a codice una chiave API in un Dockerfile o committarla in Terraform.

Ridimensiona le risorse e gestisci i costi in modo continuo

Adatta le dimensioni delle istanze all'utilizzo reale, elimina le risorse inattive, impegnati in capacità riservata per il carico di base costante, usa lo spot per il lavoro interrompibile e tagga tutto così che la spesa sia attribuibile. Il costo è una proprietà architetturale, e la spesa cloud non tracciata cresce silenziosamente. Fai: tagga le risorse per team e agisci ogni mese sulle raccomandazioni di ridimensionamento. Non fare: lasciare in esecuzione una flotta di istanze sovradimensionate e senza tag perché nessuno è responsabile della bolletta.

Progetta per il guasto con health check e failover automatico

Assumi che ogni componente prima o poi fallisca e costruisci ridondanza, health check che rimuovono i target non sani e failover automatico così che il sistema degradi con grazia anziché spegnersi. Hardware, zone e dipendenze falliscono; sperare che non lo facciano non è una strategia. Fai: configura health check del load balancer e uno standby di database che si promuove automaticamente. Non fare: affidarti a una singola istanza e a un riavvio manuale quando va in crash di notte.

Testa regolarmente backup e procedure di disaster recovery

Verifica che i backup ripristinino davvero e che i runbook di failover funzionino provandoli con cadenza programmata, con recovery time e recovery point objective espliciti. Un backup non testato è una speranza, non un piano di recupero, e la maggior parte delle sorprese di failover emerge solo durante una prova reale. Fai: esegui una prova di ripristino trimestrale in un ambiente isolato e misura il tempo di recupero. Non fare: assumere che gli snapshot notturni siano utilizzabili perché il job di backup riporta successo.

Usa l'auto scaling con limiti sensati e carichi stateless

Scala la capacità automaticamente sui segnali di carico, ma imposta limiti minimi e massimi, warm-up e cooldown per evitare oscillazioni, e mantieni stateless il tier scalato così che ogni istanza possa servire ogni richiesta. Senza limiti, un picco di traffico o un loop di metriche può scalare verso una bolletta fuori controllo o un'oscillazione. Fai: scala un tier web stateless sul tasso di richieste con un massimo definito, conservando lo stato di sessione esternamente. Non fare: scalare un servizio stateful che lega gli utenti a istanze specifiche.

Rendi le modifiche idempotenti e le operazioni sicure al retry

Assicurati che le esecuzioni di provisioning e le operazioni API producano lo stesso stato finale quando ripetute, e rendi le operazioni di creazione sicure al retry con chiavi di idempotenza, perché le chiamate cloud vanno in timeout e le pipeline si rieseguono. Le operazioni non idempotenti corrompono lo stato al retry e rendono pericolosa l'automazione. Fai: affidati alla convergenza dichiarativa dell'IaC e passa una chiave di idempotenza sulle POST simili a pagamenti. Non fare: scrivere script di provisioning che falliscono o duplicano risorse se eseguiti due volte.

Distribuisci i rilasci in modo progressivo e tieni veloce il rollback

Rilascia le nuove versioni con strategie canary o blue-green che limitano il raggio d'impatto e ti permettono di tornare indietro rapidamente, condizionate a metriche di salute e latenza anziché a un singolo passaggio big-bang. Un rilascio che non può essere annullato in fretta trasforma un piccolo difetto in un disservizio prolungato. Fai: invia il 5% del traffico a un canary, osserva il tasso di errore, poi aumenta o esegui il rollback automaticamente. Non fare: sostituire il 100% della produzione in una volta senza un percorso di rollback automatico.

Strumenta tutto con log, metriche e tracce

Costruisci l'observability fin dall'inizio - log strutturati, metriche e tracce distribuite - così da poter diagnosticare guasti inediti nei sistemi distribuiti ponendo nuove domande, non solo guardando dashboard pre-costruite. I sistemi che non puoi osservare diventano sistemi che non puoi esercire. Fai: emetti ID di richiesta correlati tra i servizi e allarma su metriche basate sugli SLO. Non fare: scoprire i disservizi solo quando i clienti si lamentano perché nulla è strumentato.

Cifra i dati in transito e a riposo per default

Abilita il TLS per tutto il traffico di rete e la cifratura a riposo per storage e database come base, terminando il TLS all'edge e usando chiavi gestite, così da prevenire l'esposizione dei dati per intercettazione o supporti rubati. I dati non cifrati sono un rischio di conformità e di violazione con poco vantaggio. Fai: imponi HTTPS, abilita la cifratura dello storage e usa mutual TLS tra i servizi interni. Non fare: lasciare un servizio interno in chiaro perché "tanto è solo sulla rete privata".