- Introduzione ad AWS
- Attivare il piano gratuito di AWS
- Gestire la sicurezza nel Cloud
- La Command Line Interface
- Monitorare costi e budget
- Percorsi formativi e certificazioni
- Infrastruttura con CloudFormation
- Gestire risorse con CDK
- Gestire risorse con SDK
- Eventi nel Cloud
- Elastic Compute Cloud (EC2)
- Script di avvio delle istanze EC2
- Storage Service (S3)
- Serverless Compute
- Template CloudFormation avanzati
- Alnao.it disclaimer
In questa pagina sono raggruppati tutti gli articoli riguardo all'argomento AWS. Non si tratta di un manuale o un corso dove sono descritti i servizi e il loro funzionamento ma si tratta solo di un gruppo di esempi di codice o mini-guide per gestire le risorse nel cloud. La documentazione ufficiale è disponibile al sito docs.aws.amazon.com, è consigliato tenere sempre a portata di click la pagina per visionare le pagine ufficiali con particolare attenzione alle sezioni che descrivono i servizi e i relativi costi di uso.
Per poter leggere e seguire questi articoli è necessario aver presenti alcuni concetti base:
- all'interno di un cloud AWS tutto ha un costo calcolato in base all'utilizzo, bisogna sempre prestare attenzione ai costi nelle pagine dei vari servizi per evitare brutte sorprese e addebiti indesierati
- chi gestisce e amministra un cloud AWS deve costantemente prestare attenzione alla sicurezza e bisogna sempre usare i servizi seguendo le linee guida per evitare buchi di sicurezza e brutte sorprese
- ogni risorsa possiede un ARN (Amazon Resource Name) che identifica in maniera univoca la risorsa, concetto molto utile quando bisogna fare iteragire più servizi tra loro
- tutti gli esempi e i servizi presentati in questo sito sono stati provati per quanto possibile nella regione irlandese ma possono essere usati in tutte le region disponibili nel cloud AWS che prevedono i servizi usati, non è stata scelta la region italiana in quanto non tutti i servizi sono disponibili e i costi in Irlanda sono a volte minori
In molti di questi articoli vengono fatti riferimenti a codice sorgente scritto in Java o in Python, vengono usati spesso comandi Linux e spesso sono usati file in formato Json e Yaml, inevitabilmente questi concetti devono essere conosciuti per poter comprendere al meglio l'uso dei servizi AWS e in particolar modo CloudFormation usato in quasi tutti gli articoli e il AWS SDK specifico per Java.
Per accedere alla console amministrativa via web, viene fornita un link di accesso che tipicamente è del tipo:
https://999999999999.signin.aws.amazon.com/console
dove il numero iniziale indica il "numero" di account aws. Il primo accesso deve essere effettuato tramite la mail di registrazione che viene chiamata "root-user", questa utenza è abilitata a fare qualunque attività ed operazione nel Cloud, per ragioni di sicurezza e di buona gestione è sconsigliato usare questa utenza per le operazioni quotidiane di sviluppo e monitoraggio, nei prossimi articoli verrà spiegato come blindare l'utenza "root" e come attivare le utenze con un livello normale di operatività.
All'accesso, la console web compare in questo aspetto:
La barra in alto alla console è sempre visibile e presenta questi link rapidi:
- informazioni sull'account e possibilità di accedere ad alcune opzioni del profilo
- selettore della regione attiva (region)
- selettore di servizi
- barra di ricerca dei servizi
- link per accedere velocemente a AWS CloudShell
Nella pagina di ingresso della console sono presenti i widget personalizzabili, la videata è presa dalla guida ufficiale dove sono disponibili tutti i dettagli riguardo ai componenti della console web.
Il piano gratuito di AWS (free tier in lingua inglese) è un programma che offre ai nuovi utenti la possibilità di provare servizi di AWS senza dover sostenere alcun costo. Il piano comprende alcuni servizi entro determinati limiti temporali e dimensioni di storage, questi limiti sono dovuto alla volontà del gestore di permettere agli utenti neofiti di eseguire prove senza costi ed evitare che il piano gratuito possa essere usato a sproposito dagli utenti esperti. Bisogna ricordare che il piano gratuito ha la durata di un anno dalla data di attivazione dell'account, al termine del quale tutti i servizi saranno a pagamento secondo le tariffe standard previste quindi bisogna prestare attenzione a come gestire il proprio account.
I principali servizi previsti dal free tier e i rispettivi limiti di utilizzi sono:
- Storage S3: 5 Gb di spazio di archiviazione sommando tutti i bucket di un account
- Compute Ec2: 750 ore mensili di esecuzione di istanze di tipo "t2.micro", queste ore sono calcolate per poter eseguire 24 ore per 31 giorni al mese una istanza ma è possibile eseguire più istanze in parallelo (per esempio 12 ore con due istanze per 31 giorni)
- Database RDS: 750 ore mensili di esecuzione di istanze di tipo "db.t2.micro" con uno storage massimo di 20 Gb, anche in questo caso le ore di esecuzione bastano per avere in piccolo database attivo per tutto un mese ma può essere anche diviso in altre maniere, lo storage è calcolato sommando tutti i componenti di un database, è possibile scegliere un DBSM di tipo MySQL, PostgreSQL, MariaDB o SQL Server.
- Database Dynamo: 25 Gb di storage per il database not-SQL nativo di AWS
- Esecuzioni di funzioni Lambda: 1 milione di esecuzioni al mese
- Esecuzioni di step function: 4.000 cambi di stato al mese
- Sistema di notifiche SNS : 1 milione di notifiche inviate al mese
- Monitoraggio CloudWatch: 10 allarmi massimi impostati attivi nello stesso momento
- Chiamate API-gateway: 1 milione di chiamate mensili indipendentemente dal back-end richiamato
- LightSail: 750 ore mensili di attivazione di una istanza, anche in questo caso è calcolato in base all'esecuzione per un mese.
- Storage condiviso EFS/FSx: 5 Gb di storage totale sommando tutti i dischi di un account
l'elenco completo di tutti i servizi e limiti di utilizzo è disponibile nella pagina ufficiale che è sempre bene tenere sotto mano se si vuole usare il piano gratuito in maniera intelligente senza avere brutte sorprese e addebiti indesiderati.
Per iscriverti al piano gratuito di AWS, è necessario creare un account AWS dal sito ufficiale e seguire i passi della procedura guidata presentata, la guida alla procedura spiega dettagliatamente i passi da seguire che possono essere riassunti:
- indicazione della mail dell'utente di registrazione con successiva verifica dell'indirizzo
- scelta della password dell'utente di registrazione
- configurazione del metodo di pagamento obbligatorio, previsto anche in caso di utilizzo del piano gratuito infatti bisogna sempre ricordare che superare i limiti previsti dal piano gratuito causeranno l'addebito di tutti i costi con il metodo di pagamento indicato nell'account
- inserimento del numero di cellulare necessario per la verifica a più fattori della prima login
Una volta effettuata la registrazione il piano gratuito si attiva in pochi minuti e sarà possibile iniziare ad usare tutti i servizi. Il piano gratuito include una varietà di servizi, ma non tutti sono uguali: alcuni servizi sono più costosi di altri, quindi è importante scegliere i servizi in base ai limiti gratuiti o quelli con il massimo rapporto qualità-prezzo. In successivi articoli sarà descritto come monitorare i costi, i servizi gratuiti e l'impostazione di budget specifici con l'invio di alert per evitare il superamento di certe soglie prefissate.
Per eseguire la prima login viene fornito via mail un link di accesso del tipo:
https://999999999999.signin.aws.amazon.com/console
dove il numero iniziale indica il "numero" di account aws. Il primo accesso deve essere effettuato tramite la mail di registrazione che viene chiamata "root-user", questa utenza è abilitata a fare qualunque attività ed operazione nel Cloud, per ragioni di sicurezza e di buona gestione è sconsigliato usare questa utenza per le operazioni quotidiane di sviluppo e monitoraggio, nei prossimi articoli verrà spiegato come blindare l'utenza "root" e come attivare le utenze con un livello normale di operatività.
Il piano gratuito di AWS è un ottimo modo per iniziare a utilizzare i servizi AWS senza spendere nulla o quasi, scegliendo i servizi giusti e impostando limiti di monitoraggio.
E' possibile chiudere un account AWS con una procedura molto semplice, la chiusura è consigliata se un profilo non viene usato, visto che alcuni servizi sono a pagamento e si rischia di ricevere addebiti indesiderati. Per chiudere l'account basta aprire la console con l'account root e aprire la pagina dell'account nel link disponibile nel menù in alto a destra. Nella pagina aperta compaiono tutte le informazioni dettagliate e alla fine della pagina è presente la sezione per richiedere la chiusura. Si consiglia di leggere le condizioni prima di selezionare i checkbox perché alcune informazioni possono essere utili per evitare addebiti non previsti. Se si chiude l'account per sbaglio oppure se si cambia idea dopo la chiusura, l'account rimane sospeso per 90 giorni prima della cancellazione definitiva, in quel periodo è possibile richiedere la ri-apertura tramite una specifica funzionalità del supporto tecnico di AWS. Dopo aver chiuso un account, non è più possibile utilizzarlo per accedere ai Servizi AWS ma nel periodo post-chiusura è possibile accedere alle informazioni riguardo alla fatturazione dei periodi precedenti alla chiusura ed è possibile accedere al supporto tecnico. Se l'utente root aveva abilitato l'autenticazione a più fattori (MFA) per acceso, conviene mantenere il dispositivo MFA attivo fino alla scadenza del periodo successivo alla chiusura di 90 giorni. La chiusura viene confermata tramite una mail all'indirizzo dell'account root. La guida completa di questa procedura è disponibile nel sito ufficiale di AWS anche se ovviamente è nascosta e quasi introvabile.
Identity and Access Management (spesso abbreviato con IAM) è uno dei servizi più importanti di tutto il Cloud AWS e deve essere sempre a portata di mano nell'uso e nella gestione di un servizio cloud complesso come quello di AWS. La regola principale del cloud è che, di default, tutto è bloccato e non è possibile accedere da una risorsa ad un altro, rispecchiando il paradigma dei "privilegi minimi", cioè assegnare autorizzazioni specifiche a ciascun utente o gruppo, assicurando che abbiano accesso solo alle risorse di cui hanno veramente bisogno. Questo per ridurre al minimo il rischio di accesso non autorizzato o uso improprio accidentale di dati sensibili.
Il servizio IAM consente di creare e gestire più utenti all'interno del tuo account AWS, funzionalità indispensabile per le organizzazioni con un numero elevato di persone che devono accedere allo stesso Cloud, con questo servizio si può gestire l'autenticazione e le autorizzazioni specifiche per ogni utente per ogni servizio, tutto da una dashboard centralizzata. Un altro vantaggio significativo di IAM è la sua capacità di fornire registri di controllo dettagliati e capacità di monitoraggio. Puoi monitorare l'attività degli utenti, visualizzare le chiamate API e persino impostare avvisi per comportamenti sospetti.
IAM supporta anche l'autenticazione a più fattori (MFA), un ulteriore livello di sicurezza che rafforza i controlli di accesso, è possibile richiedere agli utenti di fornire una seconda forma di autenticazione, come un codice univoco generato da un'app mobile, riducendo in modo significativo il rischio di accesso non autorizzato. E' consigliato, quasi obbligatorio, attivare l'autenticazione MFA all'utente root. L'attivazione si esegue manualmente dalla console web di AWS, cliccando sulla voce di menù "Security credentials" e poi assegnando un dispositivo con una applicazione compatibile. Si consiglia la lettura della mini-guida completa su come attivare la strong-autentication che è disponibile nel sito ufficiale.
Tramite IAM è possibile creare account e gruppo di account, è fortemente sconsigliato usare l'utenza principale root nella normale operatività di tutti i giorni ma è vivamente consigliato la creazione e l'uso di utenze personali senza i "poteri" di super-administrator. Un'altra funzionalità molto importante di IAM è la possibilità di definire le regole di accesso (dette policies), questo strumento serve ai gestori del Cloud per definire le regole di "comunicazione" tra due o più risorse in quanto, per default, tutto è bloccato.
Le regole (dette policies) vengono rappresentate in formato Json e devono essere della struttura:
{
"Version": "2012-10-17",
"Statement": [{
"Sid": "Sid1",
"Effect": "Allow",
"Action": [
"ec2:StartInstances",
"ec2:StopInstances"
],
"Resource": "arn:aws:ec2:*:*:instance/i-123456789"
},{
"Sid": "Sid2",
"Effect": "Allow",
"Action": [
"cloudwatch:ListMetrics",
"cloudwatch:GetMetricStatistics",
"cloudwatch:Describe*"
],
"Resource": "*"
}]
}
In questo semplice esempio sono state definite due politiche "permissive" a due diversi servizi (ec2 e cloudwatch) con le corrispettive azioni per servizio, da prestare particolare attenzione che le regole possono essere limitate a specifiche risorse, come nel caso del servizio EC2 dove è indicata la istanza rappresentata con il rispettivo codice ARN, oppure è possibile indicare asterisco per non limitare la regola ad una singola risorsa, questa tecnica viene spesso usata ma è fortemente sconsigliata.
Da ricordare sempre che una regola/policy può essere agganciata ad un singolo utente, un gruppo e/o ad una risorsa, per esempio la regola di esempio può può essere assegnata ad un utente per permettergli di gestire una istanza EC2 ma può essere assegnata anche ad una funzione lambda per assegnare gli stessi poteri.
Grazie al servizio IAM e alla somma di tutte le sue funzionalità è possibile costruire una infrastruttura sicura, nei prossimi articoli sarà indicato ogni volta sarà necessario creare regole/policies specifiche, si può fare riferimento alla documentazione ufficiale per maggiori approfondimenti e dettagli. Usare questo servizio è fondamentale anche per il rispetto della "responsabilità condivisa" compreso nelle indicazioni del contratto tra il customer e AWS al momento dell'apertura di un account, secondo questo modello
- è responsabilità di AWS la "sicurezza del cloud": AWS è responsabile della protezione dell'infrastruttura in cui vengono eseguiti tutti i servizi offerti nel cloud AWS. Questa infrastruttura è composta da hardware, software, reti e strutture che eseguono i servizi Cloud AWS.
- è responsabilità del cliente (customer) la "sicurezza nel Cloud": la responsabilità del cliente è determinata dai servizi Cloud AWS selezionati dal cliente. Ciò determina la quantità di lavoro di configurazione che il cliente deve eseguire nell'ambito delle proprie responsabilità di sicurezza.
Per maggiori informazioni si rimanda alla documentazione ufficiale "AWS Well-Architected" e si rimanda alla documentazione ufficiale del servizio IAM.
La Command Line Interface (abbreviato con CLI) è un tool che consente di interagire con i servizi AWS da riga di comando in maniera veloce e diretta, senza l'uso della console e senza dover scrivere codice con un linguaggio specifico. Per poterla lanciare i comandi della CLI è possibile usare la Shell di GNU Linux, la riga di comando di windows, da remoto via ssh su istanze EC2 oppure è possibile usare la CLI tramite il servizio AWS CloudShell e il bottone presente nella barra principale della console web.
In questo sito si fa sempre riferimento alla versione 2, per chi ha usato in passato la versione 1 deve aggiornarsi perchè le due versioni non sono compatibili. L'installazione della CLI in qualsiasi sistema è molto semplice e si può fare sempre riferimento alla documentazione ufficiale dove sono descritti i passi per l'installazione e l'aggiornamento nei più comuni sistemi operativi, per ora non è previsto una versione nativa per smartphone.
Per poter usare la CLI è necessario usare uno dei sistemi di autenticazione abilitati dal sistema IAM, il modo più semplice è quello descritto nella guida ufficiale, questa tecnica preve di creare o usare un utente specifico creando le chiavi di accesso nel dettaglio di un utente e selezionado "Crea chiavi di accesso" nel menù "Credenziali di sicurezza", con questa semplice procedura viene generata una coppia di chiavi (KeyId e AccessKey) che poi deve essere salvata al momento della creazione, successivamente non sarà più possibile recuperare la coppia in nessun modo.
Per configurare la cli bisogna lanciare il comando
$ aws configure
e in questa procedura guidata nella CLI vengono chieste quattro informazioni:
AWS Access Key ID [None]: xxxx
AWS Secret Access Key [None]: xxxx
Default region name [None]: us-west-2
Default output format [None]: json
le prime due sono le credenziali ritornate dal servizio IAM, la terza rappresenta la region di default usata dal profilo, è comunque possibile usare altre region aggiungendo un parametro al comando eseguito, il quarto valore richiesto è il formato dell'output dei comandi. Come alternativa al comando di configurazione manuale, è possibile usare un file csv scaricabile dalla console e caricare le informazioni con il comando:
aws configure import --csv file://credentials.csv
Una volta creato il profilo è possibile verificare il file di configurazione presente nella cartella di sistema:
~/.aws/credentials
oppure:
%USERPROFILE%\.aws\credentials
a seconda del sistema operativo usato (rispettivamente GNU Linux o Ms Windows). Se si dispone di più account è possibile impostare diversi profili configurando un default e poi gli altri profili con un nome personalizzato:
$ aws configure --profile <nomeProfilo>
Per vedere l'elenco dei profili è possibile lanciare il comando:
$ aws configure list-profiles
Quasi tutti i comandi della CLI sono del tipo:
$ aws <servizio> <comando> <parametri> --profile <nomeProfilo>
il profilo è un parametro facoltativo, se non indicato viene usato il profilo di default configurato. Per semplice esempio per visualizzare l'elenco di tutti i bucket in un account:
$ aws s3 ls
L'elenco completo di tutti i servizi e i comandi disponibili è consultabile con il comando:
$ aws help
oppure è sempre possibile controllare la documentazione ufficiale. In tutti i futuri articoli verranno descritti i comandi se il servizio descritto prevederà operazioni di amministrazione con la CLI.
La fatturazione e la gestione degli addebiti di AWS viene gestita dalla console web tramite il servizio AWS Billing dove si possono scaricare le fatture, i dettagli dei costi e impostare i sistemi di pagamento. Quando si utilizza e amministrano sistemi Cloud bisogna sempre ricordare che ogni risorsa ha un costo, anche se molto basso, questo è calcolato spesso in base all'uso in testo e in dimensioni, per esempio le istenze EC2 sono calcolate in base al numero di ore di utilizzo e al numero di CPU mentre i costi dei servizi di storage tipicamente sono calcolati in base alla dimensione in Gb dello storage.
Il servizio di fatturazione (billing) e tutti i suoi sotto-servizi sono limitati all'account root ma è possibile abilitare l'accesso anche agli altri utenti dalla dashboard del servizio billing dell'acount root nella sezione "IAM user and rule access to billing information", da questa sezione è possibile attivare o disattivare l'accesso degli utenti non root alle informazione delle fatturazione, cost explorer e i budget. Questo è un tema molto delicato e bisogna prestare sempre molta attenzione, AWS ha dedicato una pagina specifica che tratta di questo argomento.
In questo servizio è possibile anche analizzare i pagamenti passati e impostare ordini e monitorare l'utilizzo del "free tier" e monitorare la situazione per cercare di evitare di superare i limiti del piano gratuito e avere addebiti non previsti.
Il servizio principale di monitoraggio dei costi è Cost Explorer che include report dinamici per visualizzare i costi e l'uso dei servizi con un'ananlisi dettaglia di tutti i servizi una semplice e comoda tabella. I report permettono di regolare l'intervallo di tempo fino a 12 mesi così da poter verere anche una tendenza dei costi. Inoltre è possibile creare report specifici per alcuni servizi così da monitorare i tipi di risorse usati in un servizio, per esempio per il servizio EC2 è possibile creare un report diviso per ogni tipo di istanza come si può vedere da questa immagine di esempio:
E' possibile anche aumentare i dettagli dei report aggiungendo informazioni orarie e usare i "tags" per creare report che visualizzano e analizzano di dati dei costi solo delle risorse taggate con specifici tag, ovviamente il report analizza i costi delle risorse dopo l'inserimento dei tag; fornisce anche report per analizzare gli acquisti e le opportunità di risparmio con il famoso "Savings Plans".
Il servizio AWS Cost Explorer ti consente di accedere direttamente al motore di query interattivo che alimenta AWS Cost Explorer. Ogni richiesta comporterà un costo di 0,01 dollari, anche in questo caso si deve sempre prestare attenzione a come si usa questo servizio. La documentazione ufficiale del servizio è molto ricca di informazioni ed è disponibile alla pagina ufficiale.
Di default solo l'amministratore root può accedere a questo servizio ma, come indicato dal servizio stesso, è possibile fornire a specifici utenti l'autorizzazione creando policy IAM, per maggiori informazione è disponibile una pagina dedicata alle politiche IAM per i servizi di fatturazione.
La policy generica per abilitare un utente al servizio di Cost Explorer (ce) è del tipo:
{
"Version": "2012-10-17",
"Statement": [{
"Sid": "VisualEditor0",
"Effect": "Allow",
"Action": "ce:*",
"Resource": "*"
}]
}
Un altro sotto-servizio molto utile è AWS Budget, si trova sempre all'interno della sezione billing della console web di AWS, grazie a questo è possibile impostare degli alert in base a delle soglie limite in dollari, al superamento di questo limite viene inviata una mail ad un gruppo di destinatari prefissato. Visto che la fatturazione è sempre mensile anche i Budget fanno sempre riferimento ai costi mensili ma è possibile creare report con periodi di riferimento diversi dalla frequenza mensile.
Un semplice esempio è impostare un budget di un dollaro mensile, è possibile essere avvisati quando si supera la soglia ed è possibile avere uno storico di quando questo budget è stato superato, nel mio esempio nel febbraio 2023 la soglia è stata superata ed è arrivata la mail, negli altri mesi il budget non è mai stato superato, per fortuna.
La creazione di un budget è molto semplice e richiede solo un nome simbolico, l'importo soglia in dollari e l'elenco degli indirizzi mail ai quali AWS deve inviare le notifiche. Da notare che, per default, un primo alert viene inviato al 85% della soglia di spesa, un secondo alert viene inviato al arrivo della soglia e un terzo alert viene inviato quando la soglia viene superata.
Anche in questo caso il costo del servizio è di 0.01 dollari per ogni budget impostato ma i primi due budget di un account sono gratuiti, mentre il servizio di "Budgets reports" ha una tariffa di 0.01 dollari per ogni report creato. Maggior informazioni sono disponibili nella pagina ufficiale.
AWS mette a disposizione tantissimi percorsi per imparare ad usare i servizi e rimanere aggiornati visto che il mondo cloud è in continua evoluzione. La principale risorsa è il sito pubblico ufficiale docs.aws.amazon.com che spesso viene citato in questo sito come riferimento attendibile, è consigliato usare sempre la versione in inglese in quanto la versione in Italiano a volte non è accurata e spesso tradotta in maniera automatica. I percorsi formativi ufficiali rilasciano dei badge ufficiali verificati tramite il servizio credly.com.
CloudQuest è un "gioco" on-line disponibile su sito ufficiale, permette di eseguire alcuni task via via sempre più complessi con suggerimenti e consigli passo dopo passo. Il programma formativo contiene diversi ruoli per aiutare gli utenti e le organizzazioni a sviluppare le competenze ricercate studiando casi specifici per i vari ruoti ruolo e raggiungere obiettivi di apprendimento. Con questo programma è possibile ottenere alcuni badge, il più semplice "Cloud Practitioner" è gratuito mentre per ottenere i successivi è necessario sottoscrivere un abbonamento a pagamento, questi badge non sono molto famosi ma sono comunque ufficiali e sono consigliati ad utenti poco esperti per fare esperienza pratica.
I percorsi formativi con corsi e aule studio nel senso classico del termine è Skill-Builder, questi sono raggiungibili nel sito ufficiale e nel sito specifico AWS-skillbuilder dove sono disponibili guide specifiche per vari sotto-servizi ma anche percorsi formativi a 360 gradi su tutto il cloud di AWS. L'obbiettivo di questi piani formativi è mettere a disposizione corsi per gli utenti e i customer, alcuni di questi prevedono un esame online per la verifica delle competenze e vengono rilasciati anche alcuni badge ufficiali chiamati "Knoledge bedge".
Le certificazioni ufficiali permettono ad una persona di convalidare le competenze tecniche tramite degli esami ufficiali che, se superati, rilasciano un badge prestigioso riconosciuto a livello mondiale. Gli esami si possono effettuare da alcuni centri "test center" oppure da casa tramite la piattaforma "pearsonVue" che prevede delle regole stringenti, per maggiori informazioni riguardo alla modalità di esame si può visitare il sito ufficiale. Gli esami sono dei test online a risposta multipla con 65 o più domande in lingua inglese (o in altre lingue se richiesto), le domande sono casuali scelte diverse migliaia di domande possibili con una risposta corretta e 4 o 5 risposte errate casuali. Esistono tre livelli di certificazione ufficiali AWS:
- practitioner: è la certificazione base che tutti devono avere per poter sostenere gli esami successivi, riguarda tutti i servizi di AWS ad alto livello e la maggior parte di domande riguarda la teoria e i paradigmi del Cloud System di AWS.
- associate: si tratta del livello intermedio con una verifica specifica delle conoscenze teoriche ma anche pratiche di determinati servizi di tre categorie: developer (sviluppo), architect (architettura), sysOps (operazioni sistemistiche).
- professional & specialty: si tratta del livello più specifico con le categorie: solution architect, devops, data analytics, database, machine laerning, security e il prodotto SAP.
Dopo aver sostenuto l'esame, in pochi giorni giorni, si riceve una mail di comunicazione del risultato dell'esame che può essere passato (pass) o non passato. Se passato viene rilasciato un badge digitale verificato che viene caricato in automatico nel servizio credly.com dove chiunque può verificare che l'esame è stato sostenuto e la data di scadenza visto che i certificati AWS durano 3 anni! Oltre alla soddisfazione di avere un badge di questo tipo, AWS mette a disposizione alcune benefici per chi ha sostenuto almeno un esame, l'elenco completo può essere trovato al sito ufficiale. Per maggiori dettagli tutte le informazioni si può visionare il sito ufficiale nella sezione faqs.
CloudFormation è un servizio che permette di creare e gestire risorse AWS, si tratta del principale servizio AWS di tipo Infrastructure as Code (IaC) di AWS, questo paradigma prevede che i componenti nel Cloud siano create da codice programmato, nello specifico questo servizio prevede un file che definisce una lista di risorse AWS che vengono create, gestite dal servizio CloudFormation in maniera programmatica.
Il servizio prevede due concetti chiave che devono essere ben compresi:
- template: il file che elenca un gruppo di risorse con specificate tutte le caratteristiche per ogni risorsa, sono previsti due possibili formati: Json o Yaml, per poter usare questo servizio è necessario conoscere almane uno dei due formati, esistono dei tool grafici per la creazione di questi template e il convertitore da un formato all'altro
- stack: è la realizzazione di un template con tutte le risorse create a partire da un template. CloudFormation garantisce che tutte le risorse all'interno di uno stack vengano create, modificate ed eliminate come una unica "unità". Se non è possibile creare una risorsa, AWS CloudFormation esegue il rollback dell'intero stack ed elimina automaticamente tutte le altre risorse create. Se una risorsa non può essere eliminata, tutte le risorse rimanenti vengono mantenute fino a quando lo stack non può essere eliminato correttamente
Per usare CloudFormation non bisogna distinguere i due concetti, paragonandoli ai concetti culinari di stampo e biscotto: il file template è lo stampo mentre gli stack sono i biscotti, ogni biscotto è creato da uno stampo e ci possono essere più biscotti creati dallo stesso stapo, in questo caso ogni stack ha un nome che lo identifica e le risorse create saranno cloni nati dallo stesso template. Maggiori dettagli su questi concessi si possono trovare nella pagina ufficiale. I template prevedono la presenza di queste sezioni:
- Intestazione: versione di CloudFormation e descrizione del template, questa sezione è sempre fissa ed unica per ogni template.
- Parameters: elenco dei parametri del template, per ogni parametro è necessario impostare il nome e il tipo (come String). Per ogni parametro è possibile impostare un valore di default, un elenco di possibili valori e alcune regole specifiche (come MinLen e Constraint)
- Resources: elenco delle risorse, ogni risorsa deve avere un nome univoco, il tipo e l'elenco dei parametri, alcuni obbligatori altri facoltativi a seconda delle regole di ogni tipo di risorsa
- Outputs: elenco dei valori che lo stack deve ritornare e visualizzare in Console o nella Cli al momento di creazione o aggiornamento
Uno degli esempi di template più semplici su AWS è descrivere la creazione di un storage S3 senza nessuna configurazione particolare, il template CloudFormation è:
#Intestazione con la descrizione
AWSTemplateFormatVersion: 2010-09-09
Description: CloudFormation di esempio s3
#blocco Parametri
Parameters:
NomeBucket:
Type: String
Default: esempio01buckets3
Description: Nome del bucket
MinLength: 9
#blocco Risorse
Resources:
S3Bucket:
Type: 'AWS::S3::Bucket'
Properties:
BucketName: !Ref NomeBucket
#blocco Outputs
Outputs:
S3Bucket:
Value: !GetAtt S3Bucket.Arn
Description: S3 bucket ARN
Per caricare un template e creare uno stack ci sono due possibilità: Console web o CLI-SAM. Nella console web, nella pagina principale del servizio c'è la lista di tutti gli stack con un dettaglio di tutte le risorse appartamenti al gruppo e il template originario, è presente anche il bottone "create stack", questa procedura guidata prevede quattro passi:
- selezionare se il template è già pronto (template is ready) oppure la creazione tramite designer web (sconsigliato in quanto non è molto efficiente come metodo)
- selezionare un file dal proprio pc oppure un file già depositato in un bucket S3, nel primo caso l'upload del file verso S3 viene eseguito dalla console
- inserimento dei parametri dello stack come il nome univoco e inserire i valori di tutti i parametri previsti dal template, la pagina web visualizza anche il valore di default se previsto o la lista di valori possibili
- inserimento dei parametri avanzati come tag, la regola IAM, le impostazioni di rollback ed altre impostazioni che possono essere ignorate da un utente poco esperto
All'avvio del processo di creazione, lo stack compare nello stato "CREATE_IN_PROGRESS", se la creazione genera degli errori lo stato diventa "ROLLBACK_COMPLETE" ed è possibile controllare i log nel dettaglio. Se lo stack viene creato con successo viene visualizzato con lo stato "CREATE_COMPLETE", i parametri di Output di un template possono essere visualizzati nel dettaglio dello stack stesso, tramite console è possibile anche aggiornare uno stack ricaricando un file template. La rimozione di uno Stack può essere eseguita da console con l'accorgimento che, di default, tutte le risorse descritte nel template e create in AWS vengono eliminate quando viene rimosso uno stack, è possibile modificare questo comportamento impostando che le risorse rimangano quando lo stack viene rimosso con la proprietà:
DeletionPolicy: Retain
che deve essere inserita nel blocco Resources del template.
Come si può notare dal semplice esempio, nei template è possibile usare alcuni metodi come Ref e GetAtt per far riferimento a parametri e ad risorse, questa tecnica è molto usata nei template complessi dove ci sono molte risorse legate tra loro. La AWS-CLI mette a disposizione una serie di comandi per la gestione di template e stack, l'elenco completo può essere trovato nel sito ufficiale, il più interessante è il comando per recuperare la lista di tutti gli stack con i relativi stati e le informazioni basiche, la sintassi è:
aws cloudformation list-stacks
ed è possibile recuperare il dettaglio di ogni stack con i comandi
aws cloudformation describe-stacks --stack-name CIT
aws cloudformation describe-stack-events --stack-name CIT --max-items 2
aws cloudformation describe-stack-resources --stack-name CIT
i comandi visualizzano rispettivamente la descrizione generica di uno stack, gli eventi e le risorse appartenenti a quello specifico stack. Tramite i comandi CLI è possibile creare e distruggere stack ma è consigliato l'uso della CLI-SAM specifica per questo tipo di operazioni. Per usare la CLI-SAM che è necessario installare il pacchetto specifico dopo aver configurato la CLI di AWS, la guida per l'installazione si trova nel sito ufficiale, questa è un gruppo di comandi specifici per la gestione dei servizi serverless come CloudFormation. I principali comandi messi a disposizione dalla CLI-SAM per la gestione di template e stack sono:
- sam validate: esegue la validazione del template e visualizzare messaggi di errori se presenti, non è obbligatorio ma è sempre buona prassi validare il template prima di eseguirlo
- sam build: crea una sottocartella ".aws-sam" con i file necessari per il rilascio
- sam pacakge: se si tratta di template composti da più file questo passo è necessario per creare il file unico da rilasciare. Se il template è composto da un solo file, il passo non è da eseguire
- sam deploy: esegue il rilascio e crea lo stack con tutte le sue risorse
L'elenco completo di tutti i comandi previsti è disponibile nella documentazione ufficiale. Usando il template di esempio di creazione del bucket S3, per eseguire la creazione di uno stack, i comandi da eseguire nella cartella dove è salvato il template in un file con il nome "template.yaml":
sam validate
sam build
sam deploy --stack-name esempio1buckets3 --capabilities CAPABILITY_IAM
Nel deploy è sempre indispensabile impostare il nome dello stack e la regola base IAM di tipo "CAPABILITY_IAM", senza questa regola CloudFormation non disporrà delle necessarie autorizzazioni e restituirà un errore. Quando il comando deploy viene seguito, vengono visualizzate le informazioni dei passi eseguiti e, se lo stack viene creato senza errori, vengono visualizzati gli Output indicati nel template:
Initiating deployment
=====================
Waiting for changeset to be created..
CloudFormation stack changeset
-------------------------------------------------------------------------
Operation LogicalResourceId ResourceType
-------------------------------------------------------------------------
+ Add S3Bucket AWS::S3::Bucket
-------------------------------------------------------------------------
2042-04-02 00:00:00 - Waiting for stack create/update to complete
CloudFormation events from stack operations (refresh every 0.5 seconds)
-------------------------------------------------------------------------
ResourceStatus ResourceType LogicalResourceId
-------------------------------------------------------------------------
CREATE_IN_PROGRESS AWS::CloudFormation::Stack esempio1buckets3
CREATE_IN_PROGRESS AWS::S3::Bucket S3Bucket
CREATE_IN_PROGRESS AWS::S3::Bucket S3Bucket
CREATE_COMPLETE AWS::S3::Bucket S3Bucket
CREATE_COMPLETE AWS::CloudFormation::Stack esempio1buckets3
-------------------------------------------------------------------------
CloudFormation outputs from deployed stack
-------------------------------------------------------------------------
Outputs
-------------------------------------------------------------------------
Key S3Bucket
Description S3
Value arn:aws:s3:::esempio01buckets3
-------------------------------------------------------------------------
Successfully created/updated stack - esempio1buckets3 in None
I comandi della CLI-SAM mettono a disposizione alcuni comandi specifici per le operazioni negli stack:
- per rimuovere uno stack e di tutte le sue risorse con il comando:
sam delete --stack-name esempio1buckets3
- per valorizzare i parametri obbligatori o modificare i valori di default dei parametri di un template con il comando "parameter-overrides":
sam deploy --stack-name esempio1buckets3 --capabilities CAPABILITY_IAM
--parameter-overrides NomeBucket=nome-bucket-personalizzato
- se un template è formato da più file, è necessario usare il comando pacakge prima del deploy, il comando necessita di tre parametri: il nome del file che verrà creato, un bucket e un path:
sam package --output-template-file <packagedV1.yaml> --s3-bucket <bucket-name> --s3-prefix <path>
- come per la CLI, anche la CLI-SAM usa il profilo di default impostato, se si vuole personalizzare profilo e zona di rilascio bisogna aggiungere il parametro "profile" quando deploy e delete vengono usati:
sam deploy --stack-name esempio1buckets3 --profile <nomeProfilo>
sam delete --stack-name esempio1buckets3 --profile <nomeProfilo>
Nei successivi articoli in questo sito che trattano i servizi AWS, se il servizio è compatibile con con CloudFormation, verrà introdotto un template specifico per la gestione di risorse con template, per temi avanzati come la dipendenza tra template e i template annicati si rimanda ad articoli futuri. Tutti i dettagli e le caratteristiche del servizio si possono trovare nel sito ufficiale, questa fonte è molto utile perchè ricca di esempi e sono elencati tutte le proprietà possibili per ogni tipo di risorsa supportata dal servizio CloudFormation. Bisogna ricordare anche che il servizio è gratuito ma ogni risorsa creata negli stack è a pagamento quindi bisogna sempre prestare alle risorse create nei template.
Tutti gli esempi di template di CloudFormation presentati in questo sito sono disponibili in un repository pubblico:
https://github.com/alnao/AWSCloudFormationExamples
AWS ha realizzato due specifiche librerie per la gestione delle risorse in Cloud usando linguaggi di programmazione: Cloud Development Kit, spesso abbreviato con la sigla CDK, e SDK, la prima mette a disposizione librerie per creare e gestire risorse mentre la seconda mette a disposizione librerie per usare/interagire le risorse nel Cloud. Comprenderne la differenza è fondamentale: in parole semplici la libreria CDK gestisce risorse del Cloud mentre la libreria SDK gestisce risorse nel Cloud, sottile differenza ma fondamentale.
Quando si usa la CDK bisogna sempre tenere presente che si tratta di un servizio di tipo "infrastructure as code", concetto già presentato con il servizio di CloudFormation, secondo la documentazione ufficiale:
the output of an AWS CDK program is an AWS CloudFormation template
Per entrambe le librerie AWS mette a disposizione librerie per i maggiori linguaggi di programmazione: Python, Java, .Net, JavaScript e altri, disponibili nlelle documentazioni ufficiali di CDK e SDK. Purtroppo è facile confondere i nomi delle due librerie vista l'assonanza, spesso si fa riferimento solo al SDK anche per componenti comprese nella CDK. In questo sito si presterà sempre attenzione e verrà indicato sempre quale delle due librerie è usata negli esempi. Sono messe a disposizione anche Toolkit specifici per i principali ambienti di sviluppo come Eclipse e Visual Studio Code, per maggior informazioni si può consultare la documentazione ufficiale.
python -m pip install aws-cdk-lib npm install -g aws-cdknpm uninstall aws-cdk
cdk init app --language python python -m pip install -r requirements.txt
#!/usr/bin/env python3 import os import aws_cdk as cdk from prova1.prova1_stack import Prova1Stack app = cdk.App() Prova1Stack(app, "Prova1CDKStack", ) app.synth()
from aws_cdk import ( Stack,) from constructs import Construct import aws_cdk.aws_s3 as s3 class Prova1Stack(Stack): def __init__(self, scope: Construct, construct_id: str, **kwargs) -> None: super().__init__(scope, construct_id, **kwargs) # definizione di un bucket bucket = s3.Bucket("MyBucket", bucket_name="my-bucket", versioned=True,)
- cdk deploy: esegue il deploy dell'applicazione
- cdk synth: crea un template CloudFormation per la app
- cdk diff: confronta il codice sorgnete con l'eventuale stack già presente nel cloud
- cdk list: visualizza la lista di tutti gli stack rilasciati
- cdk destroy <nome>: distrugge uno stack nel cloud
Il pacchetto standard npm è ben documentato nella pagina ufficiale, la libreria è gratuita ed open-source, il repository pubblico del progetto è disponibile su GitHub:
https://github.com/aws/aws-cdk
Una Software Development Kit, spesso abbreviato con la sigla SDK, è una libreria che permette ad un programmatore di interfacciarsi con i servizi AWS tramite codice scritto in un linguaggio utilizzando delle specifiche API messe a disposizione. A differenza della CDK di AWS, che può essere usata solo per creare e configurare risorse, la SDK permette anche di interagire con i servizi, per esempio con le librerie SDK è possibile recuperare la lista di un bucket mentre con la CDK è possibile solo creare e distruggere uno storage S3. La libreria è documentata molto bene nel sito ufficiale e sono disponibili moltissimi esempi gratuiti che è possibile studiare nel repository ufficiale gratuito, gli usi più comuni sono lo sviluppo di applicazioni che interagiscono con i servizi nel Cloud sia come codice serverless tramite il servizio AWS Lambda Function sia come di applicazioni client.
Quando si usano le librerie di AWS (CDK e SDK) bisogna sempre ricordare che queste usano i profili configurati con la AWS-CLI: esattamente come per il comando CLI-SAM anche per la SDK viene usato il parametro di default se non specificato diversamente, se non c'è nessun profilo configurato queste librerie non sono utilizzabili, tuttavia è possibile impostare il profilo direttamente nel codice senza dover usare i profili CLI del sistema.
Per il linguaggio di programmazione Python la libreria SDK messa a disposizione da AWS è boto3, installabile grazie al gestore dei pacchetti pip:
pip install boto3
oppure nei sistemi Debian 12 è installabile con il pacchetto ufficiale:
apt-get install python3-boto3
#Elenco profili disponibili import boto3 lista_profili=boto3.session.Session().available_profiles for profilo in lista_profili: print(profilo) #Elenco bucket import boto3 s3 = boto3.resource('s3') for bucket in s3.buckets.all(): print(bucket.name)
Package names begin with software.amazon.awssdk in SDK 2.x, whereas the SDK 1.x uses com.amazonaws
Per iniziare a lavorare con SDK in Java è necessario configurare la libreria nel file di configurazione, aggiungendo i riferimenti al repository maven nel pom.xml con il tag:
<dependencyManagement> <dependencies> <dependency> <groupId>software.amazon.awssdk</groupId> <artifactId>bom</artifactId> <version>2.16.1</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement>
<dependency> <groupId>software.amazon.awssdk</groupId> <artifactId>auth</artifactId> </dependency> <dependency> <groupId>software.amazon.awssdk</groupId> <artifactId>profiles</artifactId> </dependency>
import software.amazon.awssdk.auth.credentials.AwsCredentialsProvider; import software.amazon.awssdk.auth.credentials.ProfileCredentialsProvider; import software.amazon.awssdk.profiles.ProfileFile; import software.amazon.awssdk.profiles.ProfileFile.Type; ... public static ProfileFile loadCredentialsFromFile() throws FileNotFoundException { File configfile = new File(System.getProperty("user.home"), ".aws/credentials"); ProfileFile profileFile = ProfileFile.builder() .content(new FileInputStream(configfile)) .type(Type.CREDENTIALS).build(); return profileFile; } public static Set<String> loadProfilesFromFile() throws FileNotFoundException{ ProfileFile p=loadCredentialsFromFile(); return p.profiles().keySet(); } public static AwsCredentialsProvider loadCredentialFromFile() throws FileNotFoundException { return loadCredentialFromFile(DEFAULT_PROFILE); } public static AwsCredentialsProvider loadCredentialFromFile( String profileName) throws FileNotFoundException { ProfileFile p=loadCredentialsFromFile(); AwsCredentialsProvider profileProvider = ProfileCredentialsProvider.builder() .profileFile(p) .profileName(profileName) .build(); return profileProvider; } ...
Esattamente come per i servizi CloudFormation e CDK bisogna ricordare che la SDK è gratuita ma tutte le risorse gestite possono essere a pagamento e bisogna sempre prestare attenzione a quello che viene creato nel Cloud per evitare addebiti indesiderati.
CloudWatch è il principale servizio di monitoraggio degli eventi nel Cloud AWS, con il quale è possibile raccogliere log e dati in tempo reale, questi dati vengono poi resi disponibili in un pannello di controllo nella console web, studiata per la manutenzione dell'infrastruttura e delle applicazioni in esecuzione. Con CloudWatch e le sue funzionalità di Log e Alarm, è possibile ridurre al minimo la logica da programmare per il monitoraggio, avendo a disposizione un sistema molto robusto e flessibilo.
Il servizio si basa su alcuni concetti:
- Log: un registro di log proveniente da tutti gli altri servizi, i dati vengono strutturati in Namespace e metriche
- Namespace: è un contenitore di metriche che risultano separate
- Metric: rappresenta un insieme di dati in ordine temporale pubblicati su CloudWatch, vengno rappresetnate come variabili da monitorare (a volte il termine Metric viene tradotto in italiano con la parola Parametro)
- Dashboard: nella console web è disponibile un pannello di controllo personalizzabile con il quale è possibile monitorare il sistema e gli eventi passati
- Alarm: dalle metriche si possono creare allarmi che generano eventi in base ad eventi. L'allarme più semplice consiste nell'avvisare persone inviando un messaggio quando si verifica un evento registrato in una metrica
- CloudWatch agent: sistema per inserire log in Metric provenienti da sistemi esterni al sistema Cloud AWS.
Bisogna prestare attenzione quando viene usato questo servizio in quanto non è gratuito visto che alcune funzionalità sono a pagamento in base all'uso e in base a quante query vengono eseguite nel motore che gestire log ed eventi, è consigliato leggere attentamente la pagina ufficiale.
La CLI mette a disposizione una serie di comandi per la gestione di comandi, la documentazione ricca di esempi è sempre il punto di riferimento princpale. I comandi principali per gestire le metriche si basano sul comando:
aws cloudwatch list-metrics --namespace "AWS/Lambda"
Per gestire gli allarmi è possibile recupeare la lista con i comandi:
aws cloudwatch describe-alarms aws cloudwatch describe-alarms --alarm-names "nome-alarm"
Per scatenare un allarme è possibile usare lo stesso comando con dei parametri specifici:
aws cloudwatch set-alarm-state --alarm-name "nome-alarm" --state-value ALARM --state-reason "testing purposes"
La gestione dei log da riga di comando può essere scomoda a causa della numerosità dei log comunque esiste il comando per recuperare l'elenco dei gruppi di log e i singoli eventi salvati nel registro con la possibilità di filtrare per pattern e orario del log:
aws logs describe-log-groups aws logs filter-log-events --log-group-name /aws/lambda/nome-lambda aws logs filter-log-events --log-group-name /aws/lambda/nome-lambda --filter-pattern ERROR aws logs filter-log-events --log-group-name /aws/lambda/nome-lambda --start-time 1688977737000 --end-time 1688977738000 aws logs filter-log-events --log-group-name /aws/lambda/nome-lambda --output text
Con CloudFormation è possibile gestire i log e i permessi che le varie risorse devono avere per scrivere nei log, per esempio in un template per la creazione di una lambda, oltre alla creazione della Lambda, nella sua execution role creata come regola IAM è necessario aggiungere la policy per permettere alla funzione di creare il gruppo di log e a scriverci, un semplice e classico esempio è:
LambdaIamRole: Type: 'AWS::IAM::Role' Properties: AssumeRolePolicyDocument: Version: 2012-10-17 Statement: - Effect: Allow Principal: Service: - lambda.amazonaws.com Action: - 'sts:AssumeRole' Path: / Policies: - PolicyName: root PolicyDocument: Version: 2012-10-17 Statement: - Effect: Allow Action: - 'logs:CreateLogGroup' - 'logs:CreateLogStream' - 'logs:PutLogEvents' Resource: 'arn:aws:logs:*:*:*'
Tramite CloudFormation è possibile anche creare Allarmi, Dashboard e Metriche, la documentazione ufficiale è completa e ricca di esempi, per la gestione dei log è disponibile una pagina dedicata.
La libreria SDK mette a disposizione una libreria per la gestione del servizio CloudWatch, dei log, degli alert e delle metriche tramite la solita libreria boto3. Le principali funzionalità sono recuperare la lista delle metriche disponibili ed eseguire una query su una metrica per recuperare la lista dei log degli eventi:
def get_metrics(profile_name): boto3.setup_default_session(profile_name=profile_name) cloudwatch = boto3.client('cloudwatch') lista=[] paginator = cloudwatch.get_paginator('list_metrics') for response in paginator.paginate( Dimensions=[{'Name': 'LogGroupName'}], MetricName='IncomingLogEvents', Namespace='AWS/Logs'): lista=lista+response['Metrics'] return lista def get_metric_group_log(profile_name,group_name): # Create CloudWatchLogs client boto3.setup_default_session(profile_name=profile_name) cloudwatch_logs = boto3.client('logs') # List subscription filters through the pagination interface paginator = cloudwatch_logs.get_paginator('describe_log_groups') lista=[] for response in paginator.paginate(logGroupNamePrefix=group_name): lista=lista+response['logGroups'] #for i in response['logGroups']: #print(i['logGroupName']) return lista def get_metric_log(profile_name,group_name,hours): boto3.setup_default_session(profile_name=profile_name) cloudwatch_logs = boto3.client('logs') query = "fields @timestamp, @message" start_query_response = cloudwatch_logs.start_query( logGroupName=group_name, startTime=int((datetime.today() - timedelta(hours=hours)).timestamp()), endTime=int(datetime.now().timestamp()), queryString=query, ) query_id = start_query_response['queryId'] response = None while response == None or response['status'] == 'Running': #print('Waiting for query to complete ...') time.sleep(1) response = cloudwatch_logs.get_query_results( queryId=query_id ) return response["results"]
L'icona del servizio è proprio il logo del sito
Elastic Compute Cloud, abbreviato con la sigla EC2, è servizio principale di servizio di calcolo (compute in inglese) nel Cloud di Amazon Web Services (AWS). Si tratta di un servizio che permette di avviare istanze remote per virtualizzare server o desktop con la posssilità di configurare la sicurezza, networking, storage, capacity e molto altro. Il servizio permette di gestire processi molto pesanti ma anche molti piccoli grazie alla scalabilità che permette di ridimensionare le istanze in base alle necessità di calcolo e al carico di lavoro. Questo non è un articolo che tratta di questo servizio nello specifico, si rimanda alla documentazione ufficiale per tutti i dettagli a riguardo, si da per scontato che un utente abbia almeno le conoscenze basi del servizio EC2 come i SecurityGroup, la gestione delle chiavi KeyPair, gli storage EBS e il bilanciamento del traffico ELB.
Questo articolo ha lo scopo di descrivere i principali comandi per la gestione delle istanze EC2 nel cloud usando gli strumenti messi a disposizione da AWS come la CLI, il servizio CloudFormation e le librerie CDK/SDK, lo scopo finale è automatizzare la gestione del servizio di virtualizzazione EC2.
La CLI mette a disposizione un unico comando con alcuni sottocomandi, tutte le informazioni sono disponibili nel solito sito ufficiale. I principali comandi sono:
- recuperare l'elenco di tutte le istanze:
aws ec2 describe-instances
- recuperare il dettaglio di una istanza partendo dal nome dell'instanza (come tag name):
aws ec2 describe-instances --filters "Name=tag:Name,Values=testAlberto"
- recuperare il dettaglio di una istanza partendo dal id istanza:
aws ec2 describe-instances --instance-ids i-094d7505c54b0xxxx
- filtrare i dati ritornati dai precedenti comandi per ottenere solo alcuni dati delle istanze (come id, stato e indirizzi ip):
aws ec2 describe-instances --instance-ids i-094d7505c54b0xxxx --query "Reservations[*].Instances[*].[InstanceId, ImageId, State, PrivateIpAddress, PublicIpAddress]"
- impostare un tag di una istanza per assegnare un nome alla istanza:
aws ec2 create-tags --resources i-094d7505c54b0xxxx --tags Key=Name,Value=testAlbertoLinux3b
- eseguire lo stop di una istanza:
aws ec2 stop-instances --instance-ids i-094d7505c54b0xxxx
- eseguire il comando di start di una istanza:
aws ec2 start-instances --instance-ids i-094d7505c54b0xxxx
Quasi tutti i comandi ritornano i dati secondo il fomato specifico al momento della configurazione della AWS-CLI, se si è impostato il tipo Json le risposte saranno del tipo:
{"StartingInstances": [{ "CurrentState": { "Code": 0, "Name": "pending" }, "InstanceId": "i-094d7505c54b0e029", "PreviousState": { "Code": 80, "Name": "stopped" } } ] }
L'elenco completo di tutti i parametri e i possibili utilizzi è disponibile nelle pagine dedicate nella pagina ufficiale: ec2 e describe-instances. Per creare/avviare una nuova istanza è disponibile il comando run-instances, documentato nella pagina ufficiale, il comando ha alcuni parametri obbligatori che corrispono ai dati obbligatori per l'avvio di una istanze EC2 da console:
- immagine ami
- numero di istanze da avviare
- tipo (consigliato t2.micro)
- chiavi di accesso (se si tratta di istanza Linux)
- security group
- subnet-id
Un semplice esempio di avvio nella AZ Irlandese è:
aws ec2 run-instances --image-id ami-06e0ce9d3339xxxx --count 1 --instance-type t2.micro --key-name Keeeey --security-group-ids sg-0f2d1afe5832e7xxxx --subnet-id subnet-0b6f53c0291c1xxxx
La risposta di questo comando è la conferma che una nuova istanza è stata avviata con tutti i dati, compresi quelli di default, alcuni dei principali dati ritornati dal json sono:
"ImageId": "ami-06e0ce9d3339cb039", "InstanceId": "i-02849762f5cf6d1e1", "Placement": { "AvailabilityZone": "eu-west-1b", "GroupName": "", "Tenancy": "default" }, "PrivateDnsName": "ip-10-199-12-207.eu-west-1.compute.internal", "PrivateIpAddress": "10.199.12.207", "PublicDnsName": "", "State": { "Code": 0, "Name": "running" },
Per terminare l'istanza esiste un comando specifico, ben documentato nella pagina ufficiale, il comando ha bisogno in input solo dell'istanza, per esempio:
aws ec2 terminate-instances --instance-ids i-02849762f5cf6xxxx
Con CloudFormation è possibile creare e gestire istanze EC2 in template con il tipo base "AWS::EC2::Instance", ben documentato nella pagina ufficiale, i parametri minimi per avviare una istanza sono:
EC2Instance: Type: AWS::EC2::Instance Properties: InstanceType: !Ref 'InstanceType' # t2.micro free tier SecurityGroups: [!Ref 'InstanceSecurityGroup'] KeyName: !Ref 'KeyName' ImageId: !Ref 'LatestAmiId'
L'esempio più semplice con solo i quattro parametri fondamentali è disponibile nel repository pubblico ufficiale di AWS:
github.com/awslabs/aws-cloudformation-templates/blob/master/aws/services/EC2/EC2InstanceWithSecurityGroupSample.yaml
Un esempio leggermente più complesso con la creazione di un web-server esposto in internet con uno script user-data e una configurazione più avanzata della rete è disponibile nel repository:
github.com/alnao/AWSCloudFormationExamples/tree/master/Esempio02istanzeEC2
Da notare che, per creare uno stack da questo template, è necessario inserire tre parametri obbligatori: KeyName, VpcId e SubnetId mentre AMI, security group sono parametri con un valore di default.
La libreria CDK permette la creazione e l'avvio di istanze EC2 da codice con la libreria ufficiale, un semplice esempio di creazione con la libreria Java:
final Instance engineEC2Instance = Instance.Builder.create(this, id + "-ec2") .instanceName(id + "-ec2") .machineImage(armUbuntuMachineImage) .securityGroup(securityGroup) .instanceType(InstanceType.of(InstanceClass.BURSTABLE4_GRAVITON,InstanceSize.SMALL)) .vpcSubnets(SubnetSelection.builder() .subnetType(SubnetType.PUBLIC).build()) .vpc(vpc) .build();
maggiori informazioni sono disponibili nella documentazione ufficiale.
La libreria SDK mette a disposizioni tool per gestire le Istanze, la documentazione ufficiale descrive metodi e procedure disponibili per la gestione del servizio Ec2. Per creare istanze è disponibile metodo per Java specifico:
RunInstancesRequest runRequest = RunInstancesRequest.builder() .imageId(amiId) .instanceType(InstanceType.T1_MICRO) .maxCount(1) .minCount(1) .build(); RunInstancesResponse response = ec2.runInstances(runRequest); String instanceId = response.instances().get(0).instanceId(); Tag tag = Tag.builder().key("Name").value(name).build(); CreateTagsRequest tagRequest = CreateTagsRequest.builder() .resources(instanceId).tags(tag).build(); ec2.createTags(tagRequest);
Per ottenere la lista delle istanze di un account è disponibile un metodo nella libreria specifica, si riporta un esempio dove si può notare che il metodo ritorna al massimo 100 (o 1000) elementi quindi si usa deve usare il sistema a token per ottenerere l'elenco completo:
Region region = Region.EU_WEST_1; //default irland Ec2Client ec2 = Ec2Client.builder().region(region) .credentialsProvider( Profiles.loadCredentialFromFile() ).build(); do { DescribeInstancesRequest request = DescribeInstancesRequest.builder() .maxResults(6).nextToken(nextToken).build(); DescribeInstancesResponse response = ec2.describeInstances(request); for (Reservation reservation : response.reservations()) { for (Instance instance : reservation.instances()) { list.add(instance); } } nextToken = response.nextToken(); } while (nextToken != null); for (Instance instance : list) { System.out.println("Instance:" + instance.instanceId() + " " + instance.tags().get(0).value() + " " + instance.instanceType() + " " + instance.state().name()); }
Per il linguaggio Python, la libreria SDK-Boto3 mette a disposizione metodi specifici simili a quelli disponibili per la libreria in linguaggio Java, per esempio i 4 metodi principali per gestire le istanze sono: import boto3
def get_lista_istanze(profile_name): boto3.setup_default_session(profile_name=profile_name) ec2 = boto3.client('ec2') response = ec2.describe_instances() return response def set_tag(instance_id, tag_key, tag_value): if tag_key=='': return ec2 = boto3.resource('ec2')# region_name=AWS_REGION) tags=[{'Key': tag_key,'Value': tag_value}] instances = ec2.instances.filter(InstanceIds=[instance_id,],) for instance in instances: instance.create_tags(Tags=tags) print("set_tag " + instance_id) return tags def stop_instance(instance_id): ec2_client = boto3.client('ec2')#, region_name=”us-west-2" print ("stop_instance " + instance_id) response = ec2_client.stop_instances(InstanceIds=[instance_id]) return response def start_instance(instance_id): ec2_client = boto3.client('ec2') print ("start_instance " + instance_id) response = ec2_client.start_instances(InstanceIds=[instance_id]) return response
In questo gruppo di funzioni sono esposti i metodi per eseguire start e stop di una istanza, esiste anche il metodo "terminate" per terminare una istanza ma è sconsigliato prevedere questo tipo di operazioni da un programma se non strettamente necessario.
All'avvio di istanze EC2 è possibile indicare quale istruzioni eseguire, questo gruppo di istruzioni è chiamato User data, nonostante il nome possa essere forviante si tratta di un sistema di configurazione e controllo dell'avvio delle istanze, per ovvi motivi questo tipo di script può essere eseguito solo in istanze con sistema operativo GNU Linux ma non può essere usata con istanze con sistema operative MsWindows. Di default queste istruzioni vengono eseguite solo al primo avvio ma è possibile modificare la configurazione da console per eseguire lo script anche ogni riavvio come suggerito da una pagina del sito ufficiale. Ci sono due tipi di script: shell o cloud-init, il primo tipo viene usato per installare software o eseguire istruzione mentre il secondo viene usato quando c'è la necessità di gestire il collegamento tra l'istanza EC2 e altri servizi come CloudFormation, RDS. Un semplice esempio di uso di user-data è l'installazione di un web server LAMP con una piccola infrastuttura di webserver, database MySql e il motore Php. Nel caso di sistema operativo Linux con distruzione Amazon con il gestore di pacchetti yum:
#!/bin/bash yum update -y amazon-linux-extras install -y lamp-mariadb10.2-php7.2 php7.2 yum install -y httpd mariadb-server systemctl start httpd systemctl enable httpd usermod -a -G apache ec2-user chown -R ec2-user:apache /var/www chmod 2775 /var/www find /var/www -type d -exec chmod 2775 {} \; find /var/www -type f -exec chmod 0664 {} \; echo "<?php phpinfo(); ?>" > /var/www/html/phpinfo.php
Per verificare il corretto funzionamento degli script è possibile verificare i log scritti dal sistema nei due file dedicati:
/var/log/cloud-init.log /var/log/cloud-init-output.log
e alcuni sotto-servizi del Cloud scrivono i corrispettivi files di log nella cartella specifica:
/var/log/amazon/
Il tipo cloud-init configura aspetti specifici di una nuova istanza Amazon Linux al momento del lancio come la configurazione del file delle chiavi private .ssh/authorized_keys
. Le direttive utente cloud-init possono essere passate a un'istanza all'avvio nello stesso modo in cui viene passato uno script ma con una sintassi molto diversa: la prima riga deve iniziare con
#cloud-config
così da indicare il tipo di script, un esempio completo corrispondente allo script per l'installazione di un server LAMP:
#cloud-config repo_update: true repo_upgrade: all packages: - httpd - mariadb-server runcmd: - [ sh, -c, "amazon-linux-extras install -y lamp-mariadb10.2-php7.2 php7.2" ] - systemctl start httpd - sudo systemctl enable httpd - [ sh, -c, "usermod -a -G apache ec2-user" ] - [ sh, -c, "chown -R ec2-user:apache /var/www" ] - chmod 2775 /var/www - [ find, /var/www, -type, d, -exec, chmod, 2775, {}, \; ] - [ find, /var/www, -type, f, -exec, chmod, 0664, {}, \; ] - [ sh, -c, 'echo "<?php phpinfo(); ?>" > /var/www/html/phpinfo.php' ]in questo esempio è possibile notare la distinzione tra la sezione "packages" dove sono elencati tutti i pacchetti da installare e la sezione "runcmd" con l'elenco dei comandi da eseguire.
Attraverso la CLI è possibile avviare istanze con uno specifico script salvato in un file
aws ec2 run-instances --image-id ami-XXXXX --count 1 --instance-type m3.medium --key-name my-key-pair --subnet-id subnet-abcd1234 --security-group-ids sg-abcd1234 --user-data file://my_script.txtE' possibile anche recuperare l'informazione dell'user data con il comando
aws ec2 describe-instance-attribute --instance-id i-1234567890abcdef0 --attribute userData
Con la libreria boto3 di SDK è possibile indicare lo script user-data come parametro del metodo per avviare una istanza:
import boto3 ec2 = boto3.resource('ec2') user_data_script = """#!/bin/bash echo "Hello, World!" > /home/ec2-user/hello.txt """ instance = ec2.create_instances( ImageId='<your-ami-id>', MinCount=1, MaxCount=1, InstanceType='t2.micro', UserData=user_data_script )
Nei template CloudFormation è possibile indicare l'user data di una istanza EC2 come è possibile notare nell'esempio:
Resources: WebServerInstance: Type: 'AWS::EC2::Instance' Metadata: Comment1: >- Configure to install the Apache Web Server and PHP Comment2: Save website content to /var/www/html/index.php 'AWS::CloudFormation::Init': configSets: InstallAndRun: - Install - Configure Install: packages: yum: mysql: [] mysql-server: [] mysql-libs: [] httpd: [] php: [] php-mysql: [] files: /var/www/html/index.php: content: ...: null mode: '000600' owner: apache group: apache /tmp/setup.mysql: content: !Join - '' - - 'CREATE DATABASE ' - !Ref DBName - | ; - 'GRANT ALL ON ' - !Ref DBName - .* TO ' - !Ref DBUsername - '''@localhost IDENTIFIED BY ''' - !Ref DBPassword - | '; mode: '000400' owner: root group: root /etc/cfn/cfn-hup.conf: content: !Join - '' - - | [main] - stack= - !Ref 'AWS::StackId' - |+ #riga vuota - region= - !Ref 'AWS::Region' - |+ #riga vuota mode: '000400' owner: root group: root /etc/cfn/hooks.d/cfn-auto-reloader.conf: content: !Join - '' - - | [cfn-auto-reloader-hook] - | triggers=post.update - > path=Resources.WebServerInstance.Metadata.AWS::CloudFormation::Init - 'action=/opt/aws/bin/cfn-init -v ' - ' --stack ' - !Ref 'AWS::StackName' - ' --resource WebServerInstance ' - ' --configsets InstallAndRun ' - ' --region ' - !Ref 'AWS::Region' - |+ #riga vuota - | runas=root services: sysvinit: mysqld: enabled: 'true' ensureRunning: 'true' httpd: enabled: 'true' ensureRunning: 'true' cfn-hup: enabled: 'true' ensureRunning: 'true' files: - /etc/cfn/cfn-hup.conf - /etc/cfn/hooks.d/cfn-auto-reloader.conf Configure: commands: 01_set_mysql_root_password: command: !Join - '' - - mysqladmin -u root password ' - !Ref DBRootPassword - '''' test: !Join - '' - - '$(mysql ' - !Ref DBUsername - ' -u root --password=''' - !Ref DBRootPassword - ''' >/dev/null 2>&1 </dev/null); (( $? != 0 ))' 02_create_database: command: !Join - '' - - mysql -u root --password=' - !Ref DBRootPassword - ''' < /tmp/setup.mysql' test: !Join - '' - - '$(mysql ' - !Ref DBUsername - ' -u root --password=''' - !Ref DBRootPassword - ''' >/dev/null 2>&1 </dev/null); (( $? != 0 ))' Properties: ImageId: !FindInMap - AWSRegionArch2AMI - !Ref 'AWS::Region' - !FindInMap - AWSInstanceType2Arch - !Ref InstanceType - Arch InstanceType: !Ref InstanceType SecurityGroups: - !Ref WebServerSecurityGroup KeyName: !Ref KeyName UserData: !Base64 'Fn::Join': - '' - - | #!/bin/bash -xe - | yum install -y aws-cfn-bootstrap - | # Install the files and packages from the metadata - '/opt/aws/bin/cfn-init ' - ' --stack ' - !Ref 'AWS::StackName' - ' --resource WebServerInstance ' - ' --configsets InstallAndRun ' - ' --region ' - !Ref 'AWS::Region' - |+
In questo semplice esempio è possibile notare che sono presenti script di entrambi i tipi di user data separati:
- cloud-init: in una sezione Metadata vengono divisi i comandi tra package, files, service e command, si rimanda alla documentazione ufficiale per la descrizione approfondita della sintassi di queste sezioni.
- script: nello script viene installato il pacchetto "aws-cfn-bootstrap" e successivamente viene eseguito un comando "cfn-init" per avviare lo script indicato nel cloud-init.
Questa tecnica è necessaria per permettere a CloudFormation di avviare i vari script nella istanza in fase di creazione, si rimanda alla documentazione ufficiale. Molti esempi di user data sono consultabili nel sito ufficiale.
Simple Storage Service, abbreviato con la sigla S3, è il principale servizio di archiviazione del servizio Cloud di AWS, studiato per memorizzare e recuperare qualsiasi volume di dati, in qualunque momento e da qualunque luogo. Le caratteristiche principali del servizio sono: gli oggetti sono salvati in contenitori chiamati bucket (non a caso il logo di questo servizio è proprio un secchio), ogni elemento ha un nome (key), gli oggetti sono organizzati in strutture (path), l'accesso agli oggetti può essere personalizzato grazie a regole IAM, gli accessi possono essere salvati in registri specifici nel servizio CloudWatch. E' possibile cancellare o spostare oggetti e il servizio permette di attivare il sistema di versioning per avere la storia di tutti gli oggetti. Per qualsiasi informazione e approfondimenti si può fare riferimento alla pagina dedicata al servizio S3 nel sito ufficiale.
La AWS-CLI mette a disposizione tutta una serie di comandi per la gestione dei bucket e degli oggetti, in particolare "mb" può essere usato per creare bucket:
$ aws s3 mb s3://bucket-name
ricordandosi che il nome deve essere globalmente unico (globally unique unique across all of Amazon S3) e deve rispettare le regole imposte da AWS. La lista dei bucket disponibili si recupera con il comando:
$ aws s3 ls
e per cancellare un bucket (che non contiene nessun oggetto) si usa il comando rb:
$ aws s3 rb s3://bucket-name
Per ottenere la lista di tutti gli oggetti contenuti in un bucket:
$ aws s3 ls bucket-name
E per muovere oggetti tra bucket o scaricare un oggetto cancellandolo si usa la sintassi:
$ aws s3 mv s3://bucket-name/example.txt s3://bucket-name2/ $ aws s3 mv s3://bucket-name/filename.txt ./
Mentre per copiare tra bucket o dal sistema locale da/per un bucket si usa la sintassi:
$ aws s3 cp s3://bucket-name/example.txt s3://my-bucket/ $ aws s3 cp ./filename.txt s3://bucket-name $ aws s3 cp s3://bucket-name/filename.txt ./
I comandi possono essere combinati con i comandi Linux, per esempio per scrivere o leggere un oggetto:
$ echo "hello world" | aws s3 cp - s3://bucket-name/filename.txt $ aws s3 cp s3://bucket-name/filename.txt -
Il comando Sync permette di tenere sincronizzato una cartella locale con un bucket, quindi eventuali orfani vengono cancellati e nuovi file vengono copiati, la sintassi preve solo la cartella sorgente e il bucket di destinazione:
$ aws s3 sync . s3://my-bucket/path
Per svuotare un bucket da tutti gli oggetti contenuti si può usare il comando rm con il parametro ricorsivo:
$ aws s3 rm s3://my-bucket/path --recursive
è ovvio che bisogna sempre prestate attenzione a questo ultimo comandi in quanto rimuove tutti gli oggetti e, senza sistema di versionamento attivo, gli oggetti vengono cancellati in maniera permanente. Tutti i parametri e le caratteristiche di questo comando sono disponibili alla pagina della documentazione ufficiale.
I template CloudFormation spesso hanno al proprio interno definizione o riferimenti a bucket S3, il tipo specifico AWS::S3::Bucket
che ha come unico parametro obbligatorio il nome (che deve sempre rispettare le regole previste da AWS)
Resources: S3Bucket: Type: 'AWS::S3::Bucket' Properties: BucketName: !Ref NomeBucket
La documentazione ufficiale è ricca di esempi e può essere sempre consultata come fonte principale di informazioni. Il più semplice esempio è la gestione di siti web esposti dallo stesso servizio S3 senza l'uso di CloudFront o altri servizi dedicati, ispirato alla documentazione ufficiale con in aggiunta le regole ACL, nel template è indispensabile aggiungere la regola di accesso al bucket tramite un oggetto di tipo BucketPolicy:
S3BucketPolicy: Type: AWS::S3::BucketPolicy Properties: Bucket: !Ref NomeBucket PolicyDocument: Version: 2012-10-17 Statement: - Sid: AllowSSLRequestsOnly Action: 's3:GetObject' Effect: Allow Resource: !Join - '' - - 'arn:aws:s3:::' - !Ref NomeBucket - /* Principal: '*'
L'esempio completo funzionante può essere trovato al solito repository
github.com/alnao/AWSCloudFormationExamples/tree/master/Esempio03bucketS3sito
La libreria CDK mette a disposizione classi per la gestione dei bucket, la documentazione ufficiale è ricca di esempi pratici. Per il linguaggio Java la principale risorsa è proprio il builder di Bucket:
Bucket bucket = Bucket.Builder.create(this, "MyBucket") .versioned(true) .encryption(BucketEncryption.KMS_MANAGED) .build();
Per il linguaggio Python la creazione di bucket è ancora più semplice, un esempio ripreso dalla guida ufficiale:
from aws_cdk import (aws_s3 as s3,core) class MyStack(core.Stack): def __init__(self, scope: core.Construct, id: str, **kwargs) -> None: super().__init__(scope, id, **kwargs) # Create an S3 bucket bucket = s3.Bucket(self, "MyBucket", bucket_name="my-unique-bucket-name",#unique bucket name versioned=True, # enable versioning for the bucket encryption=s3.BucketEncryption.S3_MANAGED ) app = core.App() MyStack(app, "MyStack") app.synth()
La libreria SDK è ricca di classi e metodi per la gestione dei bucket e dei contenuti, per il linguaggio di programmazione Python il sito ufficiale mette a disposizione diversi esempi i principali metodi messi a disposizione del servizio S3 sono:
#Lista dei bucket s3_client.list_buckets()["Buckets"] #Lista di oggetti response = s3_client.list_objects_v2( Bucket=bucket_name, Delimiter="/", Prefix=path, ) if "Contents" in response: response["objects"]=response["Contents"] if "CommonPrefixes" in response: response["folders"]=response["CommonPrefixes"] #Lista di oggetti con metodo paginante s3_paginator = s3_client.get_paginator('list_objects_v2') for page in s3_paginator.paginate(Bucket=bucket_name, Prefix=path, Delimiter='/'): #, StartAfter=start_after): if "Contents" in page: response["objects"]=response["objects"] + page["Contents"] #sum to append if "CommonPrefixes" in page: response["folders"]=response["folders"] + page["CommonPrefixes"] #sum to append #Contenuto di un file di testo content = s3_client.get_object(Bucket=bucket_name, Key=key)["Body"].iter_lines() #Scrivere un file di testo string_encoded = body.encode("utf-8") s3_client.put_object(Bucket=bucket_name, Key=key, Body=string_encoded)
Nel la libreria per il linguaggio Java le classi disponibili sono nel package:
software.amazon.awssdk.services.s3
Per esempio per ottenere la lista completa di tutti i bucket si può usare il semplice metodo:
S3Client client = S3Client.builder().build(); ... public static List<Bucket> getBucketList(S3Client s3Client){ ArrayList<Bucket> l=new ArrayList<Bucket>(); ListBucketsRequest listBucketsRequest = ListBucketsRequest.builder().build(); ListBucketsResponse listBuckets = s3Client.listBuckets(listBucketsRequest); listBuckets.buckets().stream().forEach(x -> l.add(x)); return l; }
Un semplice esempio dei vari metodi messi a disposizione della libreria può essere trovato al solito repository oppure mella documentazione ufficiale sono disponibili molti esempi di gestione dei bucket
Per serverless si intende una architettura Cloud nella quale la gestione dei server viene delegata al gestore del Cloud e i programmatori possono concentrarsi al 100% sugli sviluppi. AWS ha investito molto sui servizi di questo tipo basando quasi interamente il Cloud su questo tipo di modello. Il più famoso servizio di questo tipo è Lambda che permette di creare applicazioni scrivendo piccole funzioni, altri servizi di tipo serverless saranno descritti in futuri articoli.
Nota: con il termine "serverless" non si intende l'assenza di server ma si intende che il server può essere configurato dall'utente ma non è possibile prenderne il controllo.
Il servizio Lambda prevede che venga indicata l'architettura (64 o 32 bit) e la quantità di memoria RAM, al resto di pensa AWS. Il servizio prevede un limite tecnologico sulle elaborazioni di ogni funzione: una esecuzione può durare al massimo 15 minuti, oltre questo limite il processo di interrompe per time-out. Per tutte le informazioni riguardo a questo servizio si rimanda alla documentazione ufficiale dove sono sono presenti anche esempi per tutti i linguaggi di programmazione supportati come Python, Java e Node.
Nella console web di AWS per ogni lambda si hanno a disposizione quattro tab per la gestione delle funzioni:
- il codice, la configurazione dell'architettura e la dichiarazione del nome tecnico della funzione (handler)
- il sistema di testing della funzione
- il monitor della funzione con grafici e link per consultare i log in CloudWatch
- le configurazioni avanzate tra cui: il trigger chiamante come EventBridge, la execution rule e la resource-based policy statements, le variabili d'ambiente (Environment variables), la configurazione della Vpc e le configurazioni dei sistemi di chiamata asincrona (come SQS)
La console web mette a disposizione una procedura guidata per la creazione di una Lambda Function, nella procedura l'utente deve inserire i dati minimi: il nome, il runtime (Node, Python, Java, ...). E' possibile modificare alcune configurazione di default come la "execution role" che viene creata di default con solo la "permission" per permettere alla funzione di scrivere i log nella CloudWatch Logs, si rimanda alla documentazione ufficiale per maggior informazioni riguardo alle "execution role" e alle altre configurazioni delle lambda function da Console. Di default la Lambda creata in Console nel linguaggio Python viene creata con il codice di default molto semplice:

nel caso di linguaggio Java invece è necessario creare un Jar come spiegato nell'esempio disponibile nel repository:
https://github.com/alnao/AwsLambdaExamples/tree/master/java-maven-example01-console
In questo esempio sono introdotti anche i comandi maven per creare il progetto Java di base, è possibile creare lo scheletro di un progetto AWS-Lambda usando un archetipo specifico:
mvn archetype:generate -DarchetypeGroupId=xxxxx -DarchetypeArtifactId=archetype-lambda -DarchetypeVersion=2.15.79
La CLI mette a disposizione una serie di comandi per creare e gestire le lambda function, la sintassi del comando base è
aws lambda create-function --function-name java-maven-example01-cli --zip-file fileb://target/java-maven-example01-console-1.0-SNAPSHOT.jar --runtime java8 --handler it.alnao.App::handleRequest --role arn:aws:iam::740456629644:role/lambda-role
Tramite questo comando è possibile invocare, aggiornare e recuperare le informazioni riguardo alla lambda, una serie di esempi per la gestione di una lambda:
aws lambda invoke --function-name java-maven-example01-cli outputfile.txt aws lambda update-function-code --function-name java-maven-example01-cli --zip-file fileb://target/java-maven-example01-console-1.0-SNAPSHOT.jar aws lambda list-functions --max-items 10 aws lambda get-function --function-name java-maven-example01-cli aws lambda delete-function --function-name java-maven-example01-cli aws lambda get-function-configuration --function-name my-function
La CLI mette a disposizione un comando specifico per la gestione dei servizi serverless e in particolare le lambda function, chiamato Serverless Application Model abbreviato con la sigla SAM. Nella documentazione ufficiale sono descritti tutti i comandi messi a disposizione, è disponibile una guida per l'installazione. Il comando più usato è il:
sam deploy --guided
usato per eseguire il rilascio di una Lambda, il comando crea un template CloudFormation, per esempio:
AWSTemplateFormatVersion: '2010-09-09' Transform: AWS::Serverless-2016-10-31 Resources: AppFunction: Type: AWS::Serverless::Function Properties: Runtime: java8 Handler: it.alnao.App::handleRequest Timeout: 60 MemorySize: 512 CodeUri: ./target/java-maven-example01-console.jar
e successivamente esegue il rilascio di uno stack salvando un file di configurazione samconfig.toml
dove sono indicati tutti i parametri per la creazione dello stack.
Con CloudFormation è possibile gestire Lambda, le "execution role" e tutti i servizi che possono iteragire con le funzioni. L'esempio più semplice è creare una Lambda che legge un file da un Bucket S3, esempio classico consultabile nel solito repository. In questo esempio si vede la dichiarazione della Lambda con il codice Python in-line nel templare, questa tecnica è ovviamente da evitare e conviene sempre fare un file py separato, in questo esempio viene usata questa tecnica solo a titolo esplicativo:
FunzioneLambda: Type: 'AWS::Lambda::Function' Properties: Code: ZipFile: | import json def lambda_handler(event,context): for record in event['Records']: print("Esecuzione" + json.dumps(event) ) bucket_name = record['s3']['bucket']['name'] key_name = record['s3']['object']['key'] print('Key found: ' + key_name + ' in Bucket: ' + bucket_name) return {'statusCode': 200 , 'body': 'OK'} Handler: index.lambda_handler Role: !GetAtt LambdaIAMRole.Arn Runtime: python3.9 Timeout: 5
Come ripetuto più volte, la tecnica di inserire il codice Python all'interno dei template CloudFormation è una cosa da evitare, usando un file separato con estensione "py" è richiamabile indicando il nome della sottoscartella nel "CodiceUri", mentre nel Handler si indica il nome del file e il nome del metodo (che tipicamente è lambda_handler):
ExternalPyLambda: Type: AWS::Serverless::Function Properties: CodeUri: lambda Handler: esempio_file.lambda_handler Runtime: python3.8 MemorySize: 512 Timeout: 900
Oltre alla definizione della Lambda, all'interno del template CloudFormation, bisogna aggiungere due elementi:
- la regola IAM detta execution role per gestire i permessi di cosa può fare la lambda. risorsa di tipo
AWS::IAM::Role
- la regola di invocazione detta resource base policy per permettere al chiamante di invocare la funzione Lambda, risorsa di tipo
AWS::Lambda::Permission
in questo esempio la execution role permette al codice di accedere alla notifica da S3 e di scrivere i log, mentre la resource policy permette al bucket S3 di invocare la funzione lambda. Bisogna sempre ricordare che senza queste regole il sistema blocca le esecuzioni in quanto su AWS tutto è negato a meno che non sia specificato in una regola IAM, si rimanda alla documentazione ufficiale per maggior in formazioni.
LambdaInvokePermission: Type: 'AWS::Lambda::Permission' Properties: FunctionName: !GetAtt S3Notification.Arn Action: 'lambda:InvokeFunction' Principal: s3.amazonaws.com SourceArn: !Join - '' - - 'arn:aws:s3:::' - !Ref BucketName LambdaIAMRole: Type: 'AWS::IAM::Role' Properties: AssumeRolePolicyDocument: Version: 2012-10-17 Statement: - Effect: Allow Principal: Service: - lambda.amazonaws.com Action: - 'sts:AssumeRole' Path: / Policies: - PolicyName: root PolicyDocument: Version: 2012-10-17 Statement: - Effect: Allow Action: - 's3:GetBucketNotification' - 's3:PutBucketNotification' Resource: !Join - '' - - 'arn:aws:s3:::' - !Ref BucketName - Effect: Allow Action: - 'logs:CreateLogGroup' - 'logs:CreateLogStream' - 'logs:PutLogEvents' Resource: 'arn:aws:logs:*:*:*'
Nelle funzioni lambda è possibile usare le librerie messe a disposizione dal SDK per interagire con altri gli altri servizi, per esempio nelle lambda function è possibile usare la libreria Boto3 per collegarsi ad altri servizi AWS, per esempio è possibile accedere ad un bucket con poche righe di codice:
import boto3 s3 = boto3.client('s3') s3_resource = boto3.resource('s3') ... def lambda_handler(event,context): print("Esecuzione" + json.dumps(event) ) ... #esempio per leggere un oggetto da un bucket s3_object = s3.get_object(Bucket=bucket_name, Key=key_name) ... #esempio per copiare un file da un bucket ad un altro copy_source = {'Bucket': source_bucket,'Key': source_key } s3_resource.Bucket(destination_bucket_name).Object(target_key) .copy(copy_source, ExtraArgs={'ACL': 'bucket-owner-full-control'})
Per il linguaggio Java è sempre possibile usare la libreria SDK all'interno delle Funzioni tuttavia c'è un enorme problema: nel linguaggio Java le lambda function sono blocchi di codice senza nomee invocati con l'operatore freccia ->
, per esempio:
numbers.forEach( (n) -> { System.out.println(n); } );
e purtroppo c'è un caso di omonimia con le Lambda Function del Cloud AWS, la cosa può creare confusione tra i non programmtori ma chi conosce il linguaggio Java comprende sempre la differenza tra i due concetti di funzione. Tipicamente in questo sito si usa sempre Python come linguaggio per le funzioni lambda e per gli esempi combinati con CloudFormation e gli altri servizi, tuttavia è possibile trovare esempi di AWS-Lambda Function scritti nel linguaggio Java nel repository:
https://github.com/alnao/AwsLambdaExamples
Con la libreria SDK è possibile gestire le lambda recuperando l'elenco delle Funzioni Lambda, invocare le funzioni da remoto e creare Lambda Application, concetti che saranno descritti in un prossimo articolo.

Nested stacks are stacks created as part of other stacks
AWS::CloudFormation::Stack
per eseguire l'innesto di un template dentro ad un altro, l'uso di questa tecnica è frequente quando si vogliono usare template già pronti dal sito ufficiale o personalizzati integrandoli in un template principale (spesso chiamato root nei vari documenti o siti di riferimento).
AWSTemplateFormatVersion: '2010-09-09' Transform: AWS::Serverless-2016-10-31 Description: Template che crea una VPC richiamando il template ufficiale Parameters: CidrBlockVPC: Description: 'The IP address range to VPC' Type: String MinLength: '9' MaxLength: '18' Default: 10.184.0.0/16 AllowedPattern: '(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})/(\d{1,2})' ConstraintDescription: must be a valid IP CIDR range of the form x.x.x.x/x CidrBlockSubnetA: Description: 'The IP address range to Subnet A' Type: String MinLength: '9' MaxLength: '18' Default: 10.184.1.0/24 AllowedPattern: '(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})/(\d{1,2})' ConstraintDescription: must be a valid IP CIDR range of the form x.x.x.x/x. CidrBlockSubnetB: Description: 'The IP address range to Subnet B' Type: String MinLength: '9' MaxLength: '18' Default: 10.184.2.0/24 AllowedPattern: '(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})/(\d{1,2})' ConstraintDescription: must be a valid IP CIDR range of the form x.x.x.x/x. CidrBlockSubnetC: Description: 'The IP address range to Subnet A' Type: String MinLength: '9' MaxLength: '18' Default: 10.184.3.0/24 AllowedPattern: '(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})/(\d{1,2})' ConstraintDescription: must be a valid IP CIDR range of the form x.x.x.x/x. CidrBlockSubnetD: Description: 'The IP address range to Subnet B' Type: String MinLength: '9' MaxLength: '18' Default: 10.184.4.0/24 AllowedPattern: '(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})/(\d{1,2})' ConstraintDescription: must be a valid IP CIDR range of the form x.x.x.x/x. Resources: VPC: Type: AWS::CloudFormation::Stack Properties: TemplateURL: https://s3.amazonaws.com/ecs-refarch-cloudformation/infrastructure/vpc.yaml Parameters: EnvironmentName: !Ref AWS::StackName #usato come tag per le risorse VpcCIDR: !Ref CidrBlockVPC # "10.84.0.0/16" PublicSubnet1CIDR: !Ref CidrBlockSubnetA # "10.84.1.0/24" PublicSubnet2CIDR: !Ref CidrBlockSubnetB # "10.84.2.0/24" PrivateSubnet1CIDR: !Ref CidrBlockSubnetC # "10.84.3.0/24" PrivateSubnet2CIDR: !Ref CidrBlockSubnetD # "10.84.4.0/24"
https://github.com/aws-samples
Conditions: CreateVolume: !Equals [!Ref EnvName, prod]
- Fn::And
- Fn::Equals
- Fn::If
- Fn::Not
- Fn::Or
Condition: CreateVolume
. Esaminando un esempio di creazione di un disco solo se si tratta di un ambiente di produzione mentre il disco non verrà creato se si tratta di altro ambiente:Esempio20conditionsVolumeAttachment: Type: AWS::EC2::VolumeAttachment Condition: CreateVolume Properties: InstanceId: !Ref Esempio20conditionsInstance VolumeId: !Ref Esempio20conditionsVolume Device: /dev/sdh Esempio20conditionsVolume: Type: AWS::EC2::Volume Condition: CreateVolume Properties: Size: 10 AvailabilityZone: !Ref RegionAZ
Outputs: StackName: Description: Deployed StackName for update Value: !Ref AWS::StackName VolumeId: Description: Volume ID if created Condition: CreateVolume Value: !Ref Esempio20conditionsVolume
Fn::FindInMap
, la documentazione ufficiale del comando è ricca di esempi. Un esempio di utilizzo di questa tenica può essere la definizione di un blocco per descrivere la dimensione di istanze a seconda di diversi ambienti:Mappings: EnvInstance: dev: EC2Type: t2.micro prod: EC2Type: t2.small
InstanceType: !FindInMap [EnvInstance, !Ref 'EnvName', EC2Type]
https://github.com/alnao/AWSCloudFormationExamples/tree/master/Esempio05conditions
È online la nuova versione del sito con contenuti aggiornati. Nessun articolo e nessun contenuto di questo sito è stato creato con IA o generatori automatici di testi ma tutto è stato scritto con molta pazienza personalmente da Alberto Nao. Tutto il codice presente nel sito Tutti gli esempi di codice nel sito sono coperti da
free software!
I contenuti di AlNao.it potrebbero avere inesattezze o refusi. Non potrà in alcun caso e per qualsiasi motivo essere ritenuta responsabile di eventuali imprecisioni ed errori né di danni causati. Il sito web e tutte le informazioni ed i contenuti in esso pubblicati potranno essere modificati in qualsiasi momento e di volta in volta e senza preavviso. Poiché ogni materiale sarà scaricato o altrimenti ottenuto attraverso l’uso del servizio a scelta e a rischio dell’utente, ogni responsabilità per eventuali danni a sistemi di computer o perdite di dati risultanti dalle operazioni di scarico effettuato dall'utente, ricade sull'utente stesso e non potrà essere imputata ad AlNao.it che declina ogni responsabilità per eventuali danni derivanti dall'inaccessibilità ai servizi presenti sul sito o da eventuali danni causati da virus, file danneggiati, errori, omissioni, interruzioni del servizio, cancellazioni dei contenuti, problemi connessi alla rete, ai provider o a collegamenti telefonici e/o telematici, ad accessi non autorizzati, ad alterazioni di dati, al mancato e/o difettoso funzionamento delle apparecchiature elettroniche dell’utente stesso.
AlNao.it ha adottato ogni possibile accorgimento al fine di evitare che siano pubblicati, nel sito web, contenuti che descrivano o rappresentino scene o situazioni inappropriate o tali che, secondo la sensibilità degli utenti, possano essere ritenuti lesivi delle convinzioni civili, dei diritti umani e della dignità delle persone, in tutte le sue forme ed espressioni. In ogni caso non garantisce che i contenuti del sito web siano appropriati o leciti in altri Paesi, al di fuori dell’Italia. Tuttavia, qualora tali contenuti siano ritenuti non leciti o illegali in alcuni di questi Paesi, ti preghiamo di evitare di accedere al nostro sito e ove scegliessi, in ogni caso, di accedervi, ti informiamo che l’uso che deciderai di fare dei servizi forniti dal sito sarà di tua esclusiva e personale responsabilità. L’utente sarà esclusivo responsabile della valutazione delle informazioni e del contenuto ottenibile mediante il sito web. Il sito web e tutte le informazioni ed i contenuti in esso pubblicati potranno essere modificati in qualsiasi momento e di volta in volta e senza preavviso.
Le pagine di questo sito sono protette dal diritto d’autore (copyright), in particolare a norma della legge sul diritto d’autore e il contenuto del sito è protetto contro duplicazioni, traduzioni, inserimento o trasformazione dello stesso in altri media, incluso l’inserimento o la trasformazione con mezzi elettronici. La riproduzione e lo sfruttamento economico di tutto o di parte del contenuto di questo sito sono consentite solo a seguito del consenso scritto dell’avente diritto. Sia il contenuto che la struttura del sito sono protetti dal diritto d’autore. In particolare, la duplicazione di informazioni o dati, l’uso dei testi o di parte di essi o delle immagini contenute nel sito (eccetto per le foto ad uso stampa) è consentita solo previo consenso scritto dell’avente diritto. Anche le illustrazioni, a norma dell’art. 1 della legge 633/1941 – e successive modifiche e integrazioni – sono protette dal diritto d’autore. Il diritto di pubblicazione e riproduzione di questi disegni è di titolarità dell’avente diritto. Il diritto d’autore sui disegni rimane in vigore anche per i disegni automaticamente o manualmente aggiunti a un archivio. Nulla di quanto contenuto in questo sito vale come concessione a terzi dei diritti di proprietà industriale ed intellettuale indicati in questa sezione. Ci riserviamo tutti i diritti di proprietà intellettuale del sito web.
Marchi ed immagini riferibili a soggetti terzi utilizzati in questo sito non appartengono a AlNao.it e sono da ritenersi di proprietà esclusiva dei rispettivi titolari. Le denominazioni dei prodotti pubblicati su questo sito web o delle società menzionate, anche qualora non siano indicate con il simbolo identificativo della registrazione del marchio sono marchi di titolarità di terzi e sono protetti dalla legge sui marchi (D.lgs. 30/2005 e successive modifiche e integrazioni) e dalle norme in tema di concorrenza sleale. Qualsiasi riproduzione degli stessi è da ritenersi vietata ai sensi di legge. In particolare è espressamente vietato qualsiasi uso di questi marchi senza il preventivo consenso scritto del relativo titolare ed, in particolare, è vietato utilizzarli in modo da creare confusione tra i consumatori in merito all'origine dei prodotti o per finalità di sponsorizzazione, nonché in qualsiasi modo tale da svilire e discreditare il titolare del marchio. Tutti i diritti che non sono espressamente concessi sono riservati al titolare del marchio.
In aggiunta a quanto indicato, AlNao.it non potrà essere ritenuto in alcun caso responsabile di alcun danno derivante dall'utilizzo o dall'impossibilità di utilizzare il sito web, i contenuti, le informazioni o connessi alla qualità degli stessi.