- 1 Introduzione & servizi globali
- 1.1 Attivazione del piano gratuito
- 1.2 Monitoraggio dei costi
- 1.3 CLI Command line interface
- 1.4 Servizi di gestione della rete
- 1.5 Servizi di manutenzione
- 1.6 Lo Schedulatore EventBridge
- 1.7 Servizio IAM
- 1.8 Chiusura di account
- 1.9 Le certificazioni
- 1.10 Gestione domini con Route 53
- 1.11 Certificate Manager
- 2 Servizi di archiviazione
- 2.1 Creazione bucket S3
- 2.2 Gestione S3 con AWS-CLI
- 2.3 Sito statico con S3
- 2.4 Sito pubblico con CloudFront
- 2.5 Regole di accesso a CloudFront
- 2.6 SFTP con AWS Transfer Family
- 2.6 Gestione di CloudFront
- 2.7 S3-link con signature
- 2.8 VPC e Client VPN
- 2.9 EFS
- 3 Servizio EC2-Elastic Compute Cloud
- 3.1 Istanze EC2
- 3.2 Accesso SSH ad istanze EC2
- 3.3 User data: Script di avvio EC2
- 3.4 Security group
- 3.5 Schedulazione su EC2
- 3.6 EC2 con MS Windows
- 3.7 Metadata di istanze EC2
- 3.8 EC2 Auto Scaling group
- 3.9 Elastic Load Balancing
- 4 Servizi di server/compute
- 4.1 Lambda Function
- 4.1.1 Lambda Authorizer
- 4.2 Lambda Application
- 4.3 Step Functions
- 4.4 WordPress con LightSail
- 4.6 Servizi Docker e Kubernetes
- 4.7 Microservizio con ECR e ECS
- 4.8 Elastic Container Service ECS
- 4.9 Immagine Docker con ECS
- 4.10 Elastic BeanStalk
- 4.11 Ambienti BeanStalk
- 4.12 Microservizi su BeanStalk
- 4.13 Glue
- 5 Servizi di basi di dati
- 5.1 DynamoDB
- 5.2 Creazione di database Dynamo
- 5.3 Servizio SNS
- 5.4 Gestione di SNS tramite CLI
- 5.5 Database relazionali con RDS
- 5.6 Database Aurora
- 5.7 Code con SQS
- 5.8 Lambda per gestire code SQS
- 5.9 Configurazioni avanzate di SQS
- 6 Servizi per lo sviluppo
- 6.1 AWS Toolkit per VSCode
- 6.2 Step Function con AWS Toolkit
- 6.3 AWS CDK Kit
- 6.4 AWS CloudShell
- 6.5 Plugin AWS per Eclipse
- 6.6 SSM Parameter Store
- 6.7 Amplify
- 6.10 Pipeline e Lambda Application
- 7 CloudFormation
- 7.1 Template da console
- 7.2 CLI SAM e parametri
- 7.3 Tabella Dynamo
- 7.4 Lambda in Python
- 7.5 API GET e Dynamo
- 7.6 API POST & Dynamo
- 7.7 Definizione di StepFunction
- 7.8 Eventi con EventBridge
- 7.9 Definizione di Istanze EC2
- 7.10 Lambda in Java
- 7.11 Lambda con Jwt inline
- 7.12 Unzip con Lambda
- 7.13 Parametri da SSM
- 7.14 Funzione Mappins
- 7.15 Condizioni nei template
- 7.B Template CloudFormation avanzati
- 7.17 Client VPN
- 7.17 WordPress
- 7.18 Sito su EFS
- 7.19 Lambda Authorizer
- 7.20 Application Balancer
- 8 Funzioni AWS Lambda in Java
- 8.1 Lambda in Java con Eclipse
- 8.2 Lambda in Java con VsCode
- 8.3 S3-link con signature in Java
- 8.4 Recuperare dati da SQS
- 8.5 Conversione da Excel a CSV
- 9 AWS SDK in Java
- 9.1 Creazione di bucket S3
- AlNao.it Disclaimer
Il servizio AWS è il principale servizio di Cloud di Amazon è ormai riconosciuto come il miglior servizio al mondo. Anche se spesso si usa il singolare si tratta di centinaia di sotto-servizi disponibili e attivabili singolarmente, ogni sotto-servizio infatti si occupa di uno specifico argomento con servizi più generici e altri con uno obbiettivo più specifico. Un utente alle prime armi troverà alcuni servizi totalmente inutili mentre altri potrebbero essere banali perché la gerarchia è proprio pensata per offrire vari livelli di servizi.
Una delle caratteristiche principali di AWS è la divisione territoriale che fornisce la possibilità all'utente di attivare servizi in una specifica zona territoriale chiamate "region", il controllo sulla collocazione geografica delle istanze permette una gestione ottimale della latenza e alti livelli di ridondanza; inoltre alcune normative prevedono che i dati debbano risiedere in alcune zone geografiche (per esempio alcune normative prevedono che i dati debbano risiedere in server localizzati in Europa).
Un'altra caratteristica molto importante dei servizi è che il costo per l'utente: i criteri di calcolo dei costi è in base al tempo di utilizzo effettivo e le performance desiderate, per esempio i servizi lambda si pagano in base al numero di chiamate effettive mentre i servizi server si pagano in base alle ore di esecuzione dell'istanza.
I principali servizi offerti si diviso in macro-categorie sono:
- Servizi di server/compute
- Servizi di gestione della rete
- Servizi di archiviazione e distribuzione dei contenuti
- Servizi di basi di dati
- Servizi di sviluppo e deployment
- Servizi applicativi
Un concetto da imparare e tenere sempre a mente è che ogni risorsa creata ha un proprio riferimento univoco chiamato ARN (Amazon Resource Name), questo viene spesso usato quando è necessario collegare sistemi diversi tra loro come i server e le risorse di rete.
Un altro concetto molto importante all'interno dell'infrattuttura di AWS è il servizio IAM, servizio base usato per gestire l'accesso ai servizi e alle risorse con la possibilità di creare utenti e ruoli specifico per ogni evenienza. Nella gestione di qualsiasi infrastuttura diventa fondamentale utilizzarlo per la gestione degli accessi in quanto di default tutto è bloccato e bisogna dare le giuste abilitazioni quando necessario evitando il più possibile il bruttissimo "AllowAll" che è fortemente sconsigliato.
La registrazione sulla piattaforma AWS è gratuita e non prevede costi di esistenza della utenza, infatti la filosofia del sistema è "paghi solo quello che consumi" detta pay-as-you-go in inglese.
Una utenza con nessun servizio attivo non vedrà nessun addebito di pagamento, tuttavia qualsiasi cosa su AWS ha un costo quindi bisogna sempre prestare attenzione a cosa si avvia e cosa rimane attivo nei sistemi. Inoltre prevede il pagamento di 30 dollari annui di canone dal secondo anno. AWS mette a disposizione anche un piano gratuito che prevede un elenco di servizi gratuiti ma SOLO per il primo anno dopo la registrazione di una utenza, dopo questo periodo anche i servizi nell'elenco vengono addebitati con il normale costo previsto dai servizi stessi.
Per la registrazione serve una email e, opzionalmente, uno smartphone dove attivare l'autenticazione forte con il servizio di Authenticator Google scaricabile dal PlayStore di Android o dallo store di Apple. La registrazione si effettua dal sito ufficiale https://aws.amazon.com/it/ e si devono inserire i dati personali tra cui la mail dell'utenza e ovviamente la password, d'ora in avanti chiameremo questa utenza "root" in modo da distinguerla dalle utenze che creeremo nei prossimi passi.
In fase di registrazione bisogna obbligatoriamente inserire anche i dati di una carta di credito valida, questo perché AWS vuole essere sicuro fin dalla registrazione che l'utente sia in grado di pagare eventuali costi successivi. Una volta creato l'utente principale al primo login bisogna procedere con due passi importanti per la normale operatività del servizio:
Il primo passo è attivare il secondo livello di sicurezza, infatti oltre la password di accesso conviene usare un MFA per l'accesso. Per configurare questo bisogna accedere al servizio IAM e cliccare sulla funzionalità di attivazione di una MFA. Conviene usare il servizio di google "google authenticator" su Smartphone tramite l'app scaricabile sugli store, l'attivazione avviene tramite QR-Code e poi l'app genera il token one-time da usare ad ogni login.
Il secondo passo importante è la creazione di una utenza operativa in quanto l'utenza principale (chiamata root) di solito non viene usata per la normale operatività ma solo per la gestione della fatturazione. Per crearla si usa sempre il servizio IAM alla voce "aggiungi utente" e assegnando una policy di quelle esistenti chiamata "AdministratorAccess", per gli utenti più esperti è possibile anche creare una policy dedicata con solo le autorizzazioni dedicate.
Dopo la creazione dell'utenza viene mostrato un link del tipo:
https://XXXXXXXXXXX.signin.aws.amazon.com/console
che può essere usato da questa utenza operativa per l'accesso. D'ora in avanti verrà usata solo questa utenza per fare qualsiasi altra operazione sui vari servizi, se sarà da usare l'utenza root verrà specificato chiaramente.
Per ovvi motivi, i costi è un argomento molto importante da conoscere, alla registrazione AWS obbliga l'utente ad inserire una carta di credito, perché AWS vuole essere sicuro di avere la possibilità di addebitare eventuali costi. I servizi di monitoraggio dei costi è utilizzabile solo dall'utenza root quindi in questo articolo useremo l'utenza principale e non l'utenza operativa che avrebbe delle limitazioni, questa comunque può essere usata per l'analisi e per il monitoraggio delle risorse.
L'utenza root, rispetto alle utenze operative, ha una voce di menù in più chiamata "Pannello di controllo di fatturazione" disponibile cliccando sul menù in alto a destra in ogni videtata di AWS, tale servizio è disponibile anche cercando "AWS Budget".
In questo servizio sono presenti varie voci di menù utilizzabili per visualizzare e monitorare i costi e le spese.
- Home c'è un riepilogo delle spese sia come costi in dollari sia come percentuali del piano gratuito (se è attivo)
- Fatture visualizza tutte le fatture mensili emesse dal sistema, nel dettaglio è anche possibile monitorare i costi per ogni singolo sotto-servizio
- Pagamenti e Crediti visualizza l'elenco delle transazioni monetarie da e per l'utenza attiva con i riferimenti alle fattura e anche una previsione di costi del mese corrente
- Ordini di acquisto permette di pre-ordinare dei pacchetti che poi saranno usati nella fatturazione per coprire i costi previsti, in teoria serve anche per avere una serie di sconti
- Budget permette di impostare uno o più limiti di spese, superati i quali partono avvisi e permette di vedere un report mese per mese di ogni budget e le spese effettive sostenute nel periodo.
- "Budgets Reports" visualizza e permette di creare dei report sui budget disponibili
- "Preferenze di pagamento" e "metodi di pagamento" permette di modificare le impostazioni degli avvisi e delle carte di credito da usare nel servizio.
- Cost Explorer è un link ad un secondo sotto-servizio che permette di monitorare il costo in tempo reale.
Una guida completa su come impostare i budget e i relativi gli allarmi è disponibile alla pagina web ufficiale.
Un altro servizio disponibile è "Cost Explorer" (o Cost Management a seconda della traduzione disponibile), questo servizio permette di monitorare il consumo di ogni tipo di risorsa
- Home visualizza un report completo dei consumi per ogni servizio di AWS
- Cost Explorer visualizza un grafico completo dei consumi e dei relativi costi fatturati
- "Saving plans" è un sotto-servizio di AWS che permette di creare piani di spese che poi permettono un risparmio se i costi rimangono costanti nel tempo
- "Prenotazioni" è un sotto-servizio che permette di prenotare risorse con un piano di spesa prefissata, anche in questo caso viene usato per avere sconti se i consumi rimangono costanti nel tempo
Per usare i sistemi e i servizi AWS esistono diverse modalità: la più facile è classi è l'uso della console web da Browser. L'alternativa è usare il sistema da riga di comando la CLI (Command line interface), che rende molto più veloce l'operatività anche se spesso risulta non semplice da usare. Altre alternative sono l'uso degli script con CloudFormation che verrà presentato in altri articoli di questa serie.
L'installazione di AWS Cli è veramente molto semplice, se si usa un sistema Ms Windows basta aprire una riga di comando (CMD) e inserire il comando:
> msiexec.exe /i https://awscli.amazonaws.com/AWSCLIV2.msi
Mentre nei sistemi GNU Linux, il comando da lanciare per l'installazione è:
$ curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
$ unzip awscliv2.zip
$ sudo ./aws/install
Prima di procedere con la configurazione bisogna creare delle credenziali di accesso dedicate, per fare questo bisogna entarare in AWS-IAM e creare un utente dedicato di tipo "Chiave di accesso - Accesso programmatico", bisogna assegnare la policy AdministratorAccess all'utente e bisogna ricordarsi che la chiave privata (password) viene mostrata solo in fase di creazione.
Una volta creato l'utente tecnico per l'accesso, basta lanciare il comando
$ aws configuration --profile user1
e il programma chiederà quattro informazioni: il codice utente, la chiave privata creata in IAM, la zona di default (per esempio eu-west-1) e il formato dei file (per esempio json). Il parametro profile può essere usato per impostare un nome specifico al profilo, tecnica utile qualora vengono usati più profili e diverse VPC, se non viene indicato il parametro al profilo creato viene assegnato il nome default rimpiazzando i valori eventualmente già presenti. Una volta configurato l'utente viene creato un file di configurazione all'interno della cartella .aws del profilo dell'utente sono salvate le credenziali (purtroppo in chiaro).
La lista dei profili è visibile con il comando
$ aws configure list-profiles
mentre le chiavi è dispobile con il comando
$ aws configure list
Per provare il corretto funzionamento del comando si può eseguire il collegamento con il servizio S3 per avere l'elenco di Bucket disponibili:
$ aws s3 ls --profile default
Bisogna sempre ricordarsi che chiunque possieda le chiavi di accesso create può accedere a moltissimi servizi AWS quindi è fondamentale NON inviare le credenziali ma sono solo da usare per AWS-CLI, bisogna sempre ricordarsi di cambiare le chiavi con frequenza ed è consigliato creare una chiave per ogni utente senza condividere le chiavi tra più utenti/amministratori. Le guide di riferimento sono la installazione e la quickstart.
L'uso di AWS-CLI non comporta nessun costo aggiuntivo, ovviamente i costi riguardano le risorse AWS create e gestite.
Una infrastruttura AWS si basa anche sui servizi di rete che gestiscono non solo il traffico tra i vari nodi e servizi ma anche i livelli di sicurezza e di permessi tra servizi stessi. Di default i servizi sono separati e ogni componente non è abilitato ad accedere ed eseguire altri servizi a meno che non siano censiti in IAM, come vedremo nei progetti di esempio che seguiranno in questi articoli.
Route 53 è il servizio di gestione dei domini e dei DNS ti tipo scalabile, i prezzi risultano anche abbastanza contenuti e la grande potenza di questo servizio che è pensato per l'iterazione con qualsiasi altro servizio AWS dando la possibilità di configurare domini e rotte con tutti i servizi dell'infrastruttura.
Cloudfront è il servizio per la gestione della condivisione di dati in rete, specializzato nella condivisione tra diverse aree geografiche con l'obbiettivo di diminuire i tempi di latenza per i servizi con grandi quantità di dati.
Il servizio prevede anche la gestione dei certificato ACL con la possibilità di generarli o di importarli per una maggiore sicurezza. Il piano gratuito prevede 50 GB di trasferimento dati in uscita per 12 mesi, oltre tale limite c'è una tabella riguardo ai costi in base al traffico generato.
Virtual Private Cloud è il servizio per la creazione e gestione di sotto-reti tra altri sistemi AWS, questo servizio permette di gestire sotto-reti in sicurezza aumentando il controllo della visibilità tra componenti definendo le regole di rete tra VPC. L'esempio più classico è isolare diverse istanze di EC2 e DB regolando in maniera stringente i permessi di accesso tra le due e gli accessi dall'esterno verso i servizi interni alle VPC stesse. Il traffico tra VPC risulta sempre sicuro e monitorato. E' possibile anche gestire accessi diretti da Pc ad una VPC direttamente con il programma dedicato AWS VPN Client scaricabile e facilmente configurabile. Il costo è in base all'utilizzo circa di 0.05 dollari ogni ora e ogni GB tramesso in rete, in questo calcolo di spesa sono compresi anche i collegamenti dai PC.
Il servizio di API Gateway permette di esporre tramite API un sottoservizio non esposto in rete, per esempio una funziona lambda o un servizio su EC2, il monitoraggio e il sistema di versioning è gestito internamente dal servizio che risulta anche sicuro grazie ai servizi citati sopra che gestiscono lo strato di autenticazione. Il piano gratuito prevede 1 milione di chiamate API in ingresso e 1 milione di chiamate API ricevute, oltre tale limite si paga in base all'utilizzo secondo una tabella che dipende dalla zona geografica.
Il servizio Direct Connect permette di collegare una rete locale ad una rete VPC direttamente bypassando la rete Internet, questo servizio è indispensabile per chi ha bisogno di bassa latenza e collegamenti costanti. Il servizio ha un costo calcolato in base alla capacità della linea e alle ore di utilizzo della rete, potrebbe risultare molto costosa per un utente singolo ma è uno strumento indispensabile per le aziende.
L'architettura dei servizi di AWS è studiata per un monitoraggio continuo e sono presenti diversi strumenti lo sviluppo dei servizi interni, l'obbiettivo chiaro è di creare strumenti proprietari per diminuire l'uso di tool e programmi esterni di terze parti.
CloudWatch è il servizio più importante che permette di salvare e gestire i log dei vari sottoservizi, con il salvataggio dei dati in bucket S3 specifici. E' possibile anche impostare allarmi e soglie di utilizzo con anche la possiblità di inviare notifiche a soglia o ad evento. La maggior parte del monitoraggio è gratuito ma bisogna sempre controllare nelle varie tabelle per evitare spiacevoli sorprese.
CloudTrail è il servizio di governance e audit del Cloud con la possibilità della gestione dello store e si intergaccia con CloudWatch per la gestione degli eventi e dei log. Alcuni di questi servizi sono a pagamento.
AWS Config è di fatto l'inventario dei sistemi attivi, con la possibilità di eseguire step di controllo e verificare le configurazioni delle risorse. I prezzi sono calcolati esclusivamente in base all'uso effettivo e costa 0,003 dollari per elemento di configurazione registrato.
EventBridge gestisce i bus degli eventi dei sottoservizi serverless utilizzando eventi generati dai sottosistemi stessi e da applicazioni. Non preve nessun costo aggiuntivo.
EventBridge è il servizio di gestione eventi serverless generati dalle applicazioni o dai vari servizi AWS. È possibile impostare le regole di routing per stabilire dove inviare i dati per creare architetture applicative infatti la grande potenza di EventBridge è collegare le applicazioni e i servizi di AWS tramite eventi. E' possibile integrare le proprie applicazioni AWS con micro-servizi, applicazioni personalizzate come origini di eventi che pubblicano gli eventi in un bus di eventi, grazie ai filtri sul bus è possibile filtrare gli eventi e instradarli a destinazioni dei servizi AWS e a destinazioni API.
La procedura guidata da console prevede oltre al nome e al bus, il tipo: regola con un modello o pianificato, nel primo caso si deve selezionare il servizio AWS e la risorsa scatenante l'evento mentre nel caso di un evento pianificato si deve inserire la regola CRON in formato minuti, ore, giorno, mese, anno (con la particolarità che c'è anche la possibilità di selezionare il giorno della settimana oppure il valore ? per indicare tutti), alternativamente si può indicare la frequenza di esecuzione dell'evento. Successivamente bisogna indicare la destinazione dell'evento, per esempio un servizio AWS come Lambda. Da notare che in caso di aggancio con Lambda o altri servizi AWS ci sarà bisogno della regola IAM per permettere ad EventBridge di eseguire la funzione o il servizio. E' possibile eseguire un comando shell di una EC2 tramite il servizio "AWS-RunShellScript" e la definizione del comandi tramite una costante.
Ogni regola è descritta nella console dove è possibile monitorare tutte le esecuzioni ed è possibile visualizzare eventuali log grazie all'integrazione con CloudWatch e gli altri servizi. In caso di esecuzione di una lambda function è possibile notare che nella console della funzione compare un trigger che esegue quella lambda e nella configurazione della lambda compare "l'autorizzazione" alla chiamata alla procedura stessa.
Sempre tramite la console di AWS è possibile disabilitare un evento in modo che rimanga nella console ma eventuali eventi scatenanti o schedulazioni non scatenino eventi, questo può essere molto utile per bloccare temporaneamente un trigger o una schedulazione senza doverla eliminare o modificare nella forma.
Il costo di EventBridge va in base al consumo, cioè a quanti eventi sono pubblicati nel bus e/o acquisiti, nel piano gratuito tutti gli eventi di modifica dello stato pubblicato nel bus di default sono gratuiti, gli eventi personalizzati costano 1 dollaro per ogni milione di eventi. Lo schema principale del servizio è disponibile nella pagina di AWS ufficiale.
Il servizio IAM è uno dei principali servizi di tutta l'architettura AWS, in quanto con questo servizio si configurazioni le regole di accesso alle risorse e ai servizi di tutta l'infrastruttura con la filosofia delle tre regole: "Chi", "Come" e "A Cosa", per esempio l'utente Alberto via console accede al bucket S3. Il servizio IAM è globale quindi le regole sono le medesime in tutte le region e non è possibile impostare regole diverse per regioni o AZ diverse. Il servio è totalmente gratuito a meno di regole speciali molto avanzate ed è diviso in quattro tipi di voci principali: users, groups, roles e policies.
La vista users elenca tutti gli utenti di uno specifico account, nel dettaglio è possibile configurare le singole permission legate al singolo utente (quindi cosa quell'utente è abilitato a fare) e l'elenco dei gruppi a cui appartiene (quindi quali regole quell'utente eredita dal gruppo). Nella vista "security credentials" è possibile gestire le chiavi di accesso, queste sono utili per chi usa la AWS CLI o per quei programmi che hanno bisogno di credenziali programmatiche, inoltre è possibile una chiave SSH pubblica e una chiave GIT per CodeCommit. La vista groups (o gruppi) permette di definire un gruppo di utenti selezionando una lista di utenti e una lista di permission associata al gruppo in modo da avere regole molto più semplici e snelle per la definizione di questo tipo di impostazioni, questo sistema permette inoltre di gestire gerarchie e ereditarietà, tenendo conto che è un sistema "permissivo": di default è tutto disattivato e con queste regole si "accendono" le abilitazioni.
La vista roles (o ruoli) permette di creare e gestire i ruoli che poi possono essere associati a utenti o gruppi, di default qui si trovano tutti i ruoli di tutti i servizi di AWS, con le caratteristiche di ogni servizio con la propria regola specifico, in questa sezioni si possono vedere anche tutte le regole create con CloudFormation per permettere ai vari servizi di AWS di comunicare tra loro, per esempio un trigger per invocare una lambda ha bisogno di una specifica regola IAM nella quale si affida al trigger il ruolo di chiamare la funzione lambda. La vista "policies" permette di creare e gestire le varie regole di policy.
Il servizio IAM mette a disposizione anche tutta una serie di report per l'analisi degli accessi e dell'uso, in particolare il servizio di "Access Analyzer" può risultare molto utile per analizzare chi e come accede ai vari servizi per isolare possibili accessi indesiderati.
Quando si usa CloudFormation per creare e gestire risorse cloud su AWS bisogna sempre ricordarsi di gestire i permessi delle risorse visto che di default ogni risorsa non ha nessun permesso, per esempio una funzione lambda ha bisogno dei permessi per poter scrivere nei log di CloudWatch, un semplice esempio di uso del tipo "AWS::IAM::Role" è:
Esempio16lambdaAPIconJWTIAMRole:
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:*:*:*'
E' possibile chiudere l'account AWS con pochi click seguendo la guida ufficiale, la chiusura è consigliata se non si usa il servizio oppure se termina il periodo di prova e non si usa il servizio 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, link disponibile nel menù in alto a destra e poi selezionando la voce account.
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.
Le certificazioni permettono ad una persona di convalidare le competenze tecniche e affinare le conoscenze tramite degli esami ufficiali che, se superati, rilasciano un badge mondiale 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.
Si tratta di test 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 quattro 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 e specialty: si tratta del livello più specifico con le categorie: solution architect, devops, data analytics, database, machine laerning, security, SAP.
Per poter iscriversi e sostenere un esame si deve usare il sito ufficiale, l'esame dura almeno 100 minuti (il practitioner) o più, il costo e la disponibilità dipende dal livello di esame scelto.
Dopo aver sostenuto l'esame, entro cinque 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 sosttenuto 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ò accedere al sito ufficiale delle faqs.
Il servizio Route 53 mette a disposizione al customer la possibilità di acquistare e registrare domini internet e di gestire tutte le regole DNS dei domini registrate e altre piccole regole di rete come gli endpoint VPC. La registrazione di un dominio è una procedura guidata molto semplice dove sono richiesti i dati base:
- il nome del dominio, selezionabile se è libero e non è già acquistato
- i contatti della persona di riferimento
- il flag della Privacy Protection che, per quasi tutti i tipi di dominio, nasconde il proprietario reale dai registri pubblici internet
Una volta fatto il passo di registrazione l'acquisto può essere fatto, in questo caso AWS utilizza anche graficamente una gestione a carrello visto che questo è un servizio a pagamento e ogni dominio ha un costo. Quindi bisogna sempre prestare attenzione a cosa si a perché il costo di un dominio può variare dai 10 Dollari in su, il costo viene addebitato immediatamente sulla carta o sul metodo di pagamento impostato nell'account root.
La registrazione di nuovo dominio avviene in poco tempo, a volte ci può voler anche 10 minuti. Una volta acquistato il dominio comare tra le "Registered domains" con la poche proprietà disponibili: auto-rinnovo e il blocco di trasferimento, proprietà che sono modificabili proprio da console.
Una volta acquistato il dominio, compare anche nel "hosted zone" dove è possibile vedere tutte le regole del dominio (i record DNS), in questo caso è possibile aggiungere regole di tipo A e CNAME oppure degli altri tipi previsti dal protocollo DNS. In fase di creazione o modifica di una regola è possibile selezionare il flag alias che permette di creare record che non puntano ad un IP specifico ma ad un servizio AWS del customer: è possibile impostare una regola che punta direttamente ad un CloudFront, ad una API Manager, Load Balancer, Elastic Beanstalk e molti altri, queste regole sono molto utili perché non serve sapere l'indirizzo IP della risorsa ma basta saperne il nome ARN-AWS.
Il servizio Route 53 è un servizio globale (non legato ad una Region) e la propagazione dei record DNS è molto veloce. Il costo del servizio è in base ai domini registrati (pagati al momento dell'acquisto o del rinnovo), inoltre è previsto un costo aggiuntivo in base al numero di domini ospitati nel servizio (hosted zone in inglese), il prezzo parte da 0.5 $ al mese per i primi 25 domini registrati, ma il prezzo può variare in base all'uso, è sempre consigliato controllare il costo nella pagina ufficiale.
L'acquisto di certificati TLS è una procedura indispensabile se si vuole esporre un sito in sicurezza con HTTPS, in quanto il protocollo prevede che l'accesso al dominio venga reso sicuro tramite un certificato specifico. La creazione di un certificato TLS (Transport Layer Security) è una fase molto semplice e c'è una procedura guidata all'interno della console AWS proprio nel servizio AWS Certificate Manager (ACM). La richiesta di un certificato parte da una procedura guidata dove si indica se il certificato deve essere pubblico o privato, poi bisogna indicare il dominio, il tipi di verifica e l'algorimto, i valori di default: verifica con DNS e algoritmo RSA sono i più semplici.
Una volta creato il certificato rimare in stato "pending" finché non si completa la validazione con il metodo indicato in fase di creazione, se si è scelto di usare il DNS, nella dettaglio del certificato si possono vedere due regole CNAME che devono essere create per la validazione, se il dominio è registrato con Route 53 comparirà anche un bottone "Create record in Route 53" che permette la creazione con un semplice click. Una volta validato il certificato può essere usato in qualsiasi servizio, come CloudFront dove è possibile indicare un dominio alternativo di riferimento ma, in questo caso, è indispensabile selezionare anche il certificato corrispondente.
Tramite il servizio ACM è possibile anche caricare in AWS dei certificato rilasciati da altri enti pubblici e verificati, questa procedura serve per poter usare dei domini AWS ma che sono registrati esternamente al Cloud. Secondo la documentazione ufficiale il servizio AWS Certificate Manager è gratuito e i prezzi sono calcolati in base alle risorse AWS create, tuttavia il servizio AWS Pricate CA che gestisce i certificati privati è a pagamento come indicato nella documentazione ufficiale.
Uno dei servizi più importanti ed usati di tutta l'infrastruttura è il servizio base di storage di AWS che poi si è evoluto nel corso degli anni, dal 2006 ad oggi infatti si è evoluto molto.
S3 (Simple Storage Service) è il servizio web di storage principale di tutto AWS ed è il servizio più usato, permette di creare dei bucket contenitori di file ma non è da confondere con il concetto di cartella classica delle memorie tradizionali: secondo le linee guida di AWS non è necessario creare sottocartelle ma dovrebbero essere create più bucket (non a caso è usato il termine cestino rispetto al termine directory). Ad ogni singolo bucket è possibile assegnare diverse policy di sicurezza e di accesso, inoltre è possibile pubblicare il contenuto di un bucket come un sito web tramite l'opzione "Hosting di siti Web statici". Ad oggi il piano gratuito prevede un limite di spazio di 5Gb, oltre il limite il costo diventa di 0,023 dollari per Gb. E' considerato il sistema più sicuro e stabile al mondo con rarissimi casi di perdita di dati.
EFS (Elastic file system) è di fatto il servizio di condivisione dati su una memoria tradizionale, si tratta infatti di un servizio di FileSystem a tutti gli effetti, infatti può essere usato come disco di rete per una azienda. Per accedere ai dischi di questo tipo è necessario usare il servizio di rete AWS Direct Connect per la gestione degli accessi dalla rete internet. I costi sono piuttosto elevati e variano in base alle zone geografiche, alla dimensioni delle memorie e al traffico di lettura e scrittura.
Glacier è il servizio di storage a lungo termine di AWS, studiato per grandi memorizzazioni di dati a lungo termine, infatti viene spesso usato per i backup e lo store di grandi quantità di dati. La caratteristica principale è che la scrittura e la lettura risultano lente ma lo store viene garantito a vita senza perdita di dati. Il costo è bassissimo, infatti risulta 0.004 dollari per ogni Gb memorizzato. Nel piano gratuito non viene usare questo servizio ma conviene usare i bucket S3.
StorageGateway è il servizio di integrazione dei Bucket AWS con altri sistemi locali usato per grandi far transitare e gestire grandi quantità di file in maniera asincrona tra servizi AWS. Con questo servizio è possibile eseguire dei backup periodi di Bucket S3 su Glacier. Il costo è in base ai Gb transitati, circa 0.01 dollari per ogni Gb.
Il servizio S3 di AWS è il servizio principale di memorizzazione dati, ogni contenitore all'interno del servizio viene chiamato Bucket, dall'inglese cestino, il grande successo di AWS dipende anche dalla stabilità e dalla velocità di questo servizio. Il concetto di Bucket S3 può essere confrontato con il concetto di directory classica usata nel FileSystem, nonostante le somiglianze ci sono alcune differenze. Il nome dei file viene chiamato key mentre l'indirizzo corrispondenti alle cartelle viene chiamato path, quindi ogni elemento salvato ha un path e una key utili per identificare un file.
Il servizio viene usato per qualsiasi necessità di accesso ai dati come applicazioni internet, punto di salvataggio dei backup, archiviazione dati, analitiche su dataLake e storicizzazione di dati in cloud. Una delle caratteristiche principale è che il servizio è globale, quindi non si può selezionare uno specifica region o zona nel menù a tendina della console e ogni contenuto è disponibile in ogni region, tuttavia in fase di creazione bisogna sempre indicare la region dove gli oggetti vengno salvati.
Per creare il bucket basta cliccare nel bottone "Crea bucket" nella console di AWS, all'interno del servizio S3. I dati indispensabili per la creazione del bucket sono il nome e la region, facoltative sono le configurazioni dei permessi ACL e del accesso pubblico. Due configurazioni importanti degli S3 sono: la configurazione delle versioni "versioni multiple" e la crittografia. La prima configurazione permette di avere lo storico di tutti i file salvati nella console, la seconda permette di impostare la crittografica degli elementi salvati dentro S3 per un aumento del livello di sicurezza. Una volta creato il bucket è possibile eseguire tutte le operazioni da console: caricare e scaricare file e/o cartelle.
Nella console è possibile modificare anche la configurazione del "Blocco dell'accesso pubblico", queste configurazioni permette di rendere gli elementi dentro al bucket disponibili anche al di fuori della console, un classico esempio sono le applicazioni per la scrittura e lettura di elementi oppure condivisione degli elementi tra account. Il tab della lista di controllo accessi, chiamata ACL, permette di definire le regole di accesso sempre dal tab "Autorizzazioni" della console di AWS.
Il piano gratuito prevede 5Gb di archiviazione per il primo anno e un limite di accesso (20.000 richieste GET, 2.000 richieste PUT, COPY, POST o LIST). Oltre questi limiti i costi sono calcolati in base all'effettivo uso del servizio, i costi sono descritti alla pagina ufficiale.
Il servizio S3 può essere velocemente e facilmente gestito dalla AWS-CLI, purtroppo i comandi sono basici e non è possibile cambiare le configurazioni dei bucket in quanto le configurazioni avanzate sono specifiche solo del servizio CloudFormation. Tuttavia AWS-CLI è molto usato per inviare e scaricare file visto che risulta molto veloce e agile. La creazione di un bucket può essere eseguita con il comando
$ aws s3 mb s3://bucket-da-cli
e l'unico parametro che si può aggiungere è la region di riferimento se questa diversa dalla region impostata nel profilo di AWS-CLI, per esempio
$ aws s3 mb s3://bucket-da-cli --region us-west-1
Per eseguire upload e download di elementi si usa il comando cp
con la sintassi:
$ aws s3 cp FileSorgenteInLocale.txt s3://bucket-da-cli/FileDestinazioneNelBucket.txt
$ aws s3 cp s3://bucket-da-cli/FileSorgenteNelBucket.txt ./FileDestinazioneInLocale.txt
Mentre è possibile creare file manualmente con l'istruzione
$ echo "hello world" | aws s3 cp - s3://bucket-da-cli/filename.txt
La lista dei file è recuperabile con il comando
$ aws s3 ls s3://bucket-da-cli/
Mentre la cancellazione di un file è possibile eseguirla con
$ aws s3 rm s3://bucket-da-cli/FileDestinazioneNelBucket.txt
Un altro parametro molto usato e interessante è il sync che permette di sincronizzare una cartella locale e un bucket, andando a caricare solo i file mancanti
$ aws s3 sync ./ s3://bucket-da-cli/
La rimozione di un bucket, se non contiene nessun dati, è eseguibile con il comando
$ aws s3 rb s3://bucket-da-cli/
L'elenco completo dei comandi per la gestione di S3 con AWS-CLI è disponibile nel sito ufficiale.
Il servizio S3 permette nativamente di esporre in internet il contenuto di un bucket, questo sistema può essere usato per esporre un sito statico di soli file HTML. La configurazione del sito prevede due step: rendere pubblico il bucket e impostare l'hosting del sito pubblico.
Per rendere pubblico un bucket bisogna entrare nelle configurazione del bucket nel tab "Autorizzazioni" e premere il bottone modifica nel "Blocco dell'accesso pubblico", con questa funzionalità è possibile abilitare o disabilitare l'accesso al contenuto del bucket in quanto di default è attiva l'opzione per bloccare qualunque accesso pubblico. Una volta abilitato l'acceso pubblico, sarà possibile accedere al bucket con tool o applicazioni interne ad AWS grazie all'indirizzo ARN visibile nel tab Proprietà.
La funzionalità di attivazione dell'hosting è dispobile nel tab "Proprietà" come ultima opzione nella pagina. La configurazione è molto semplice e prevede solo la scelta del tipo (statico o redirect), pagina di indicizzazione (index) ed eventualmente delle regole di forword facoltative. Una volta attivata la funzionalità sempre sulla vista Proprietà del bucket comparirà l'url del sito statico, nella forma
http://<nomeBucket>.s3-website-<ZoneAWS>.amazonaws.com/
Se provando ad accedere, si ottiene un errore 403 per mancate autorizzazioni, bisogna controllare le configurazioni del "Blocco dell'accesso pubblico", perché attivando questa opzione, l'accesso sarà bloccato a tutti. Questo metodo è poco usato per un motivo molto importante: non è possibile, velocemente e dettagliatamente, configurare regole di accesso e/o regole di autorizzazione, per questo tipo di configurazioni bisogna usare il servizio AWS CloudFront introdotto nel prossimo articolo.
La modalità più usata per l'esposizione di siti web statici o contenuti di Bucket S3 è l'uso del servizio CloudFront, questo appunto permette l'esposizione in internet in sicurezza grazie alla definizione di regole di rete chiamate "Security group". Se si possiede un bucket bisogna rendere il contenuti di tipo pubblico, infatti bisogna disattivare l'opzione "Blocco dell'accesso pubblico" disponibile nel tab Autorizzazioni del bucket.
All'interno della console del servizio di CloudFront bisogna creare una nuova distribuzione, nella procedure guidata bisogna indicare il bucket S3, nella sezione di S3 Bucket Access bisogna ricordarsi di usare il OIA (origin access identity) e bisogna ricordarsi di premere il bottone "Create new OAI" e bisogna cliccare sulla opzione "Yes, update the bucket policy". Inoltre, per gli utenti meno esperti, non conviene attivare l'opzione di "Enable Origin Shield".
Successivamente si possono definire alcune proprietà importantissime come il protocollo (HTTP o HTTPS), i metodi abilitati (GET e POST per esempio), le regole del WAF( web application firewall) e si può caricare la struttura del certificato SSL per HTTPS. Alla fine la voce "Default root object" risulta opzionale ma in realtà è obbligatoria se si vuole esporre un sito web statico. Alla fine si può procedere con la creazione e nella lista è possibile monitorare lo stato del rilascio ce necessita qualche minuto per andare in rete.
Una volta creata la distribuzione si può accedere al dettaglio della distribuzione stessa per vedere l'url pubblico che dovrebbe essere del tipo
XXXXXXXXXXXX.cloudfront.net
Se accedendo a questo sito si ottiene un errore di tipo "Access denied", ci sono due possibilità: bisogna impostare il "default root object" oppure non funziona la regola di OIA sul bucket, cioè significa che CloudFront non può accedere al bucket S3 e bisogna controllare le autorizzazioni di accesso: all'interno delle proprietà del bucket dovrebbe comparire la regola del tipo
{
"Sid": "2",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::cloudfront:user/CloudFront Origin Access Identity XXXXXXXXX"
},
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::nome-bucket/*"
}
Le regole di CloudFront di default rendono il sito esposto compleamente aperto visto che il servizio non è studiato per impostare regole di rete specifiche: all'interno del dettaglio di una distribuzione di CloudFront, è disponibile un tab per configurare una restrizione di tipo geografico, cioè limitare l'accesso da un determinato paese o area geografica. Un'altra configurazione è il blocchi di alcuni url-path prefissati e nel tab "Create invalidation" è possibile invalidare alcuni punti di accesso di tipo url fisso.
Se risulta necessario creare regole di rete più particolari come limitare l'accesso solo ad un IP fisso, è possibile creare una regola di rete tramite il servizio AWS-WAF nella pagina specifica del "Web ACLs", inserendo un blocco a tutti tranne ad IP specifici o regole ancora più particolari. Un volta creata la regola ACL nel WAF è possibile modificare le impostazioni del CloudFront impostando la regola del firewall appena creata nella tendina del "AWS WAF web ACL". Dopo pochi istanti la regola risulterà già attiva e il traffico bloccato dal firewall riceverà un errore di tipo HTTP-403.
Il server per trasferire file è sempre un punto delicato in qualunque infrastruttura, perché si crea un punto potenzialmente pericoloso da esporre in internet e perché c'è il serio rischio che qualcuno si intrometta con qualcosa di malevolo nei sistemi. All'interno dell'infrastruttura AWS è presente il servizio AWS Transfer Family per la definizione e la configurazione di server SFTP per lo scambio di file, in questo articolo non viene preso in considerazione il server FTP senza sistema di cifratura perché è da considerarsi poco sicuro e deprecato.
Prima di procedere con la creazione di un servizio bisogna avere a disposizione una policy nel servizio IAM con la regola di accesso al/ai bucket S3 e una corrispettiva Rule agganciata al servizio "Transefer" per così avere a disposizione tutti i permessi per gli utenti che poi useranno il servizio, visto che di default su AWS tutti i permemssi sono su "Deny" senza questa regola un utente non potrebbe vedere e scrivere all'interno dei bucket.
Nella console AWS Transfer è possibile creare un nuovo server usando la procedura guidata che prevede i sequenti passi di configurazione dove bisogna selezionare i vari parametri:
- il tipo SFTP o gli altri tipi meno sicuri che sono sconsigliati
- il provider di identità: per semplicità si usa "Servizio gestito" per definire gli utenti all'interno della stessa console
- tipo di enpoint: pubblico oppure limitato ad una VPC interna
- eventuale nome dell'host personalizzato se si dispone di un DNS con una regola
- il tipo di sorgente: si può selezionare bucket S3 oppure il servizio EFS
- il ruolo con cui il server scrive i log su cloudwatch (conviene sempre selezionare "crea nuovo ruolo" per evitare problemi)
- l'algoritmo crittografico del protocollo: conviene selezionare la versione 2018-11 se si vogliono usare le chiavi di tipo "ssh-rsa"
- la chiave host del server: se non valorizzato la console crea una chiave proprietaria
Se in fase di creazione si è selezionata la voce "Servizio gestito", una volta creato si possono creare gli utenti, per ogni utente bisogna indicare:
- nome
- chiave pubblica di accesso, per esempio "ssh-rsa <valoreChiave>"
- bucket S3 ed eventuale sottocartella di accesso
Nella console, nella sezione del monitoraggio del server sono disponibili le statistiche di accesso e di uso con il traffico di ingresso e uscita del server, è possibile accedere anche al servizio CloudWatch che di default conserva i log di accesso e gli errori di collegamento. Attraverso la console è possibile anche fermare il server senza distruggerlo in modo da renderlo invisibile (Offline) e avviarlo solo quando strettamente necessario, questa pratica è consigliata per quei server esposti in internet.
CloudFront è un servizio per esporre risorse interne ad AWS, come bucket S3 oppure ALB (Application Load Balancer), il vantaggio di usare questo servizio è la cache che viene distribuita in tutte le "edge location", cioè i server sparsi in tutto il mondo in modo da ridurre la latenza e diminuire il traffico da e per i server base. La cache distribuita di CloudFront può generare un disallineamento tra quello che effettivamente è nel server e quello che viene esposto in quanto la cache è un tempo di vita (TTL) che di default è impostato ad un giorno ma può essere anche impostato ad un anno o un secondo.
Dalla console è possibile invalidare la cache in modo da ricaricarla grazie al tab "invalidate cache" dove è possibile anche impostare una singola risorsa o un url pecifico, con /*
si va a invalidare la cache di tutti i gli oggetti. Il prezzo del servizio è proporzionale al traffico generato e può variare da zona a zona, per un risparmio è possibile impostare la cache in tre diverse modalità:
- all region: la cache viene distribuita in tutte le Edge di tutte le regioni, ottimizzando il problema di latenza ma ogni region ha un prezzo specifico, più alto in Asia e sud america
- class 200: la cache viene distribuita in 4 regioni, così da parzializzare la latenza ma con costi minori perché la tariffa asiatica è minore
- class 100: la cache viene distribuita solo in Europa e negli USA, la latenza fuori da questi contenti è più alta ma il costo è minimizzato
Con la configurazione "multiple origins" è possibile impostare origini diversi per path diversi, per esempio:
- /api potrebbe essere indirizzato ad un Load-Balancer o ad una istanza EC2 pubblica
- /resources potrebbe essere indirizzata ad un bucket S3
- /* potrebbe essere indirizzata ad un altro bucket S3
Con la configurazione "origin gruops" è possibile impostare più origini (S3 o LoadBalancer), nel caso di errore del primario, il traffico viene automaticamente girato nei secondari.
Nella configurazione generale oltre al link creato automaticamente del tipo
<nomeDistribuzione>.cloudfront.net
è possible definire una regola DNS per permettere ad un dominio esterno (anche di terzo livello) di accedere alla distribuzione, senza tale regola non è possibile definire regola DNS specifica per accedere ai contenuti esposti da CloudFront.
Il servizio S3 prevede la possibilità di esporre pubblicamente in internet un link per scaricare un oggetto contenuto in un bucket. Un link di questo tipo viene creato dal servizio S3 stesso e contiene una "signature", cioè delle credenziali "Amz-Security-Token
" e "X-Amz-Signature
", queste credenziali sono temporanee con scadenza massima 7 giorni se creati da console o da CLI. Le credenziali della signature non sono gestite tramite IAM ma sono create e gestite dal servizio AWS STS (Security token service), sia in caso di creazione da console, sia in caso di creazione da codice non è possibile modificare queste credenziali che sono trasparenti per l'utente.
Da console è possibile creare un link entrando nel servizio S3, selezionando un oggetto e cliccando la voce "Share with signature URL" dalla tendina "Action". Nella finestra è possibile inseire la durata di validità del link poi con il bottone "Create" viene creato il link, l'utente deve premere nel bottone "Copy presigned URL" per poter copiare e incollare il link. Il link può essere usato da browser, da curl, da wget o da qualsiasi programma che preveda il protocollo HTTP con il metodo GET, altri protocolli e metodi non sono supportati dal servizio.
Può essere creato da AWS-CLI con il comando:
aws s3 presign s3://arn:aws:s3-outposts:<us-east-1>:<id-account>:outpost/path/file.txt --expires-in 604800
Un caso d'uso oltre alla sola condivisione di files è la possiblità di salvare in un bucket S3 file come immagini e visualizzare le immagini in un sito con dei link signature generati da una lambda esposta tramite Api Gateway e richiamata con REST. Un semplice esempio di metodo python per generare un link di questo tipo:
import boto3
s3_client = boto3.client('s3',region_name="eu-west-1",config=boto3.session.Config(signature_version='s3v4',))
url = s3_client.generate_presigned_url(
ClientMethod='get_object',
Params={'Bucket': 'ACCESS_POINT_ARN', 'Key': 'OBJECT_KEY'},
ExpiresIn=3600)
Se si usa il servizio Lambda per generare i signature bisogna ricordarsi di aggiungere la regola IAM per permettere alla lambda di accedere al bucket S3, senza questa regola usando il link si otterebbe un bruttissimo "Access denied". Un altro semplice esempio di Lambda che genera un link con signature in linguaggio Java può essere trovato a questo articolo.
La documentazione può essere trovata nel sito ufficiale.
L'intero cloud AWS si basa sul concetto di VPC: virtual private cloud, cioè un ambiente (cloud) logicamente (virtual) isolato (private) e non visibile da altri VPC o dall'esterno se non tramite specifiche configurazioni di rete. Il Client VPN messo a disposizione da AWS permette di configurare un collegamento sicuro e puntuale tra AWS e un computer in qualunque punto del mondo che così viene abilitato a collegarsi a quelle rete virtuale specifica in maniera sicura e cifrata.
Per configurare l'accesso c'è bisogno di un "Client VPN Endpoint" cioè un punto di collegamento che permetta di accedere alla rete cloud dalla rete internet con specifiche regole di rete. La specifica voce di menù è disponibile nel servizio dedicato alla VPC nella sezione "Virtual private network (VPN)" e mette a disposizione una procedura guidata web dove è possibile creare una rete configurando:
- Nome e descrizione
- Range di IP Cidr della rete client (tra 12 e 22) che NON deve essere compresa nel range IP Cidr della VPC altrimenti gli indirizzi andrebbero in contrasto
- Il servizio ACM (Certificate manager) per il recupero del certificato
- Il sistema di autenticazione (Used-based) con il quale è possibile eseguire una gederazione con un servizio SAML (come lo IAM)
- La configurazione di CloudWatch del logging
- Il DNS da usare (che di solito è nel IP X.Y.0.2 della stessa VPC)
- Il tipo di protocollo tra TCP o UDP
- La VPC specifica
Inoltre è necessario configurare nel dettaglio del Endpoint appena creato le regole di rete che permettono al client di accedere alle risorse nella VPC, nello specifico bisogna creare
- target network association per collegare le subnet ad un security group
- security group: serve un SG dedicato per regolare il traffico in ingresso e in uscita
- authorization rules: è possibile specificare quale range IP Cidr può accedere alla rete
route table: è necessario creare una route table per ogni subnet (privata) associata al range IP Cidr della VPC (non del EndPoint)
E' possibile creare tutte queste risorse anche con CloudFormation ed è uno degli script più complessi che io abbia mai fatto. Una volta creato l'endpoint è possibile da console scaricare il file di configurazione importabile nel client, la guida del programma client è disponibile nella documentazione ufficiale.
Il servizio è a pagamento e bisogna sempre prestare attenzione ai costi in quanto può risultare molto costoso se usato da molti utenti, è possibile scegliere anche altre opzioni come la VPN Site-to-Site che risulta più economica in caso di molti utenti collegati, maggiori dettagli sono disponibili nella pagina ufficiale del servizio.
Il servizio EFS (Amazon Elastic File System) mette a disposizione degli utenti la possibilità condividere file senza occuparsi o configurare la grandezza e le performance dello storage in quanto si tratta di un servizio serverless, infatti il "disco" si auto-dimensiona a seconda delle esigenze di dimensioni e traffico. L'interfaccia di collegamento di rete con supporto ai protocolli NFSv4.1 e NFSv4.0, con in più un protocollo proprietario (chiamato efs) usato all'interno alle risorse AWS, proprio grazie a questo il servizio è usabile dalle istanze EC2, da ECS e da AWS Lambda che possono eseguire il mount del volume EFS in pochi istanti.
La creazione da console richiede pochissime informazioni: un nome simbolico, la VPC e il tipo (multi AZ oppure singola AZ). Nella console, dettaglio del volume, si possono vedere il nome DNS del tipo
fs-<volumeID>.efs.<region>.amazonaws.com
e con il bottone Attach si possono vedere i comandi di mount del tipo:
sudo mount -t efs -o tls fs-<volumeID>:/ /mnt/efs
In fase di creazione del EFS viene creato un Security Group dedicato per gestire la connessione in ingresso, come sempre in AWS, di default tutto è bloccato tranne quanto è configurato nel security group, bisogna sempre ricordarsi di autorizzare le istanze EC2 o le Lambda per accedere al volume aggiungendo nel Security Gruop del EFS la regola Inbound dal Security Group della EC2. Per montare i volumi in istanze EC2 è possibile usare il tipo EFS, grazie al protocollo proprietario installabile con il pacchetto "efs-utils" con i comandi yum se si è usata una AMI con sistema AWS-Linux :
sudo yum install -y amazon-efs-utils
oppure con un sistema Debian/Ubundu si può installare con i comandi:
sudo apt-get update
sudo apt-get -y install git binutils
git clone https://github.com/aws/efs-utils
cd /path/efs-utils
./build-deb.sh
sudo apt-get -y install ./build/amazon-efs-utils*deb
maggiori informazioni sono disponibili nella guida ufficiale.
Il comando di mount potrebbe avere problemi di risoluzione DNS perchè il disco viene sempre creato nella subnet privata della VPC mentre l'istanza potrebbe non accedervi o il volume potrebbe non avere un IP nella subnet della istanza EC2, per risolvere questo problema è possibile creare un interfaccia di rete del volume e poi aggiungere nel file "/etc/hosts" della istanza la riga
<indirizzoIPvoume> fs-<volumeID>.efs.<region>.amazonaws.com
Per quanto riguarda i sistemi operativi Ms Windows, nella documentazione c'è un chiaro messaggio
Amazon EFS is not supported on Windows instances, per maggior informazioni si può leggere la documentazione ufficiale. Un caso d'uso molto semplice è la creazione di un sito web in alta affidabilità con queste componenti:
- un unico volume EFS dove viene memorizzato il codice del sito web
- più istanze EC2 che montano lo stesso EFS, all'interno di ogni istanza un server web per l'esposizione dei contenuti del volume
- un autoscaling group per la gestione delle istanze
- un application load balancer per la gestione del traffico per il bilanciamento del traffico
Per servizi di server/compute si raggruppano tutti i servizi di creazione e gestione di server o servizi di elaborazione, in inglese viene usato il termine "compute" e non server perché alcuni servizi non prevedono un server fisso e statico ma solo servizi di calcolo puro.
EC2: I più importanti servizi sono i classici server di elaborazione, il nome EC2 deriva dal nome "Elastic Compute Cloud", dove il termine Elastic rappresenta la principale caratteristica del servizio: i server possono essere velocemente ridimensionato. Ogni server EC2 infatti ha una dimensione che descrive le caratteristiche, per esempio la t2.micro identifica il tipo "t", con due core e dimensione micro. La prima lettera infatti corrisponde al tipo di server:
- t2 m5 m4 m3 = server di tipo generico
- c5 c4 c3 = server con il calcolo ottimizzato, studiati per le applicazioni web e il calcolo computazionale
- x1 r4 r3 = server con la memoria ottimizzato, studiati per la gestione di grandi dimensioni di dati (big-data)
- p3 p2 g3 g2 f1 = server con il calcolo accelerato, studiati per grafica 3D e simili
- i3 i3 h1 d2 = server con lo storage ottimizzato
Nel nome delle istanze, il numero di ogni istanza rappresenta la generazione di server. Assieme al tipo c'è sempre anche la grandezza del server, tipicamente sono da nano a 2xlarge.
Un elenco completo del tipo di istanze e le caratteristiche è disponibile nella guida ufficiale. Ad oggi risulta il servizio più usato e più semplice perché fornisce server GNU Linux o MsWindows con la possibilità di personalizzarlo completamente. La caratteristica principale di questo servizio è la possibilità di poter cambiare la dimensione in pochi minuti, questo permette la scalabilità dei server in momenti/periodi mi maggior/minor carico.
Il costo di questi server è in base alla quantità di ore di esecuzione del server, nel piano gratuito è previsto un solo server t2.micro attivo per mese, al di fuori possono costare da pochi euro al mese a migliaia.
La connessione a questi server è regolata da sicurezza tramite certificati PEM ed è possibile creare un url pubblico per l'accesso via TCP e HTTP/HTTPS ma è possibile anche gestire connessioni private con VPC o sotto-reti.
Il servizio EC2 è il più famoso e usato di tutti quelli offerti da AWS. La console dedicata ad EC2 racchiude centinaia di funzionalità che permettono di gestire le istanze e tutti i livelli di sicurezza. Nell'elenco delle istanze è possibile visualizzare tutte le istanze, comprese quelle spente ma non ancora distrutte. Con il bottone "avvia istanza" è possibile creare una nuova istanza, basta infatti inserire il nome, la AMI e il tipo di istanza.
Se si vuole rimanere all'interno del piano gratuito e non si vuole avere nessun tipo di addebito, bisogna selezionare il tipo t2.micro
e assicurarsi che sia l'unica attiva in quel momento visto che il piano gratuito mette a disposizione una istanza di questo attivo attiva. Per maggior informazioni sui diversi tipi di istanza rimando alla documentazione ufficiale.
In fase di creazione bisogna anche creare o configurare le chiavi di connessione, se non si dispone di chiavi su può creare la coppia di chiavi privata-pubblica dal link "Crea nuova coppia di chiavi". Le impostazioni di rete permettono di selezionare quale connettività sarò impostata nella istanza, tipicamente si può impostare di default il collegamento SSH e HTTP, il primo per la connessione di amministrazione da riga di comando mentre il secondo si attiva solo se l'istanza deve esporre una webapplication.
Come configurazione consigliata del protocollo SSH è consigliato l'attivazione dell'indirizzo IP "del richiedente" e non di tutti. Da notare che nella console è presente il messaggio "Creeremo un nuovo gruppo di sicurezza", i security group saranno introdotti in un articolo specifico. Nelle impostazioni avanzate è possibile configurare un parametro "Dati utente" (in inglese "User data"), anche questo argomento sarà descritto in un successivo articolo.
Una volta premuto il bottone "avvia istanza", questa verrà avviata e sarà possibile monitorare lo stato dall'elenco dove sono presenti anche le opzione per fermarla ed eliminarla.
Per collegarsi ad una istanza EC2 bisogna usare una chiave di accesso, è possibile configuare la chiave in fase di creazione oppure è possibile caricare una chiave personalizzata. Come best-practices è consigliato generare una chiave privata per ogni istanza EC2 (oppure per ogni AMI) e poi aggiungere eventuali chiavi pubbliche dedicate per le singole persone abilitate all'accesso, così da avere una chiave di manutenzione per ogni istanza.
La creazione della chiave privata per l'istanza è un passo che avviene proprio in fase di definizione dell'istanza dove c'è un bottone specifico per la creazione della chiave, in questo modo è possibile scaricare il file pem della chiave, in questo caso si scarica la chiave privata quindi bisogna prestare attenzione a dove finisce il file visto che è l'unico momento in cui si può scaricare il file. Una volta avuta la chiave è possibile collegarsi all'istanza via ssh con il comando:
ssh ec2-user@<indirizzo-ip> -i /cartella/chiave-privata-ec2.pem
da notare che di default il protocollo SSH è aperto a tutti ma è possibile limitare l'accesso ad ip specifici tramite l'impostazione del Security Group direttamente nella console nel dettaglio dell'istanza. Inoltre bisogna tenere presente che di default le istanze NON hanno IP pubblico e per collegarsi bisogna usare la VPN-Client, a meno che non venga richiesto di creare un IP pubblico nei passi di creazione dell'istanza stessa. Grazie a questa chiave è possibile eseguire l'upload o il download di file all'interno dell'istanza grazie al comando SCP, per esempio:
scp -i /cartella/chiave-privata-ec2.pem /cartellaSorgente/file.txt ec2-user@10.199.1.164:/home/ec2-user/cartellaDestinazione
in questo comando si usa la chiave privata inviando un file da una sorgente locale ad una cartella destinazione remota. L'utente da usare per il collegamento può variare a seconda del tipo di AMI usata quando si avvia la EC2, di default è "ec2-user" per le AMI semplici mentre per quelle "proprietarie" è possibile che sia diverso, per esempio bitnami viene usato nelle istanze create proprio da bitnami. Per permettere il collegamento all'istanza con una chiave diversa da quella creata in fase di definizione dell'istanza, è possibile modificare il file
~/.ssh/authorized_keys
in questo file sono salvate le chiavi (rsa per esempio) abilitate all'utente. In questo file bisogna aggiungere una riga per ogni chiave con il tipo, il valore della chiave e il nome separti da uno spazio. Per precisione nel file authorized_keys si censiscono le chiavi pubbliche e NON le private che devono essere usate dal chiamante. E' possibile consultare la documentazione ufficiale e la documentazione che descrive la gestione delle chiavi private.
Bisogna ricordare che i comandi ssh e scp sono disponibili per tutti i sistemi GNU Linux da qualsiasi Shell e per MS Windows solo usando la Power Console mentre non funziona nella console classica cmd.
L'user data è una configurazione delle istanze EC2 che permette all'utente di definire una serie di comandi da eseguire quando una istanza viene avviata per la prima volta e quando viene riavviata. La configurazione può essere inserita comodamente da console in fase di creazione dell'istanza stessa e bisogna ricordare che viene eseguita solo in fase di avvio per la prima volta e viene seguita ogni volta che l'istanza viene riavviata. Lo script viene spesso usato per installare demoni o programmi specifici oppure per definire configurazioni particolari al server, quasi mai viene usato per comandi che andrebbero persi. Un classico esempio di User data è:
#!/bin/bash
yum update -y
yum install -y httpd
systemctrl start httpd
systemctrl enable httpd
echo "<h1>start $(hostname -f)</h1>" > /var/www/html/index.html
in questo semplice script viene aggiornato il sistema operativo con il comando yum, installato il server apache httpd e successivamente configurato un file html come risposta unica al server web appena installato. Ovviamente è possibile eseguire qualunque comando o script visto che questi comandi vengono eseguiti come root user del sistema operativo selezionato. Purtroppo in alcune versioni in italiano della console e della documentazione è stato tradotto con "Dati utente" quindi bisogna prestare attenzione quando si legge questo nome riferito alle EC2 in realtà si fa riferimento al concetto di script "user data" e non ai dati dell'utente che esegue la EC2.
Uno degli aspetti più potenti di tutta l'infrastruttura cloud AWS è la configurazione dei Security Group che permette di definire regole di rete specifiche, di default infatti tutte le istanze EC2 sono chiuse di default, senza nessuna regole di security group le istanze sarebbero isolate in qualsiasi rete esse si trovino. Le regole del security group definiscono le regole di permessi per protocollo e per porta fondendo una interfaccia semplice e intuitiva facile da mantenere, si possono creare in fase di definizione di una istanza EC2 oppure possono essere gestite dalla voce di menù specifica all'interno della console delle istanze EC2. Oltre al nome la configurazione prevede due semplici tipi di regole: in ingresso e in uscita. Di default tutto il traffico è chiuso quindi in ingresso si dovrebbero definire solo le regole di protocollo e porta che sono effettivament usate mentre in uscita tipicamente si definisce la regola che apre tutte le porte per tutti i protocolli ma anche in questo caso sarebbe possibile definire regole specifica limitando i flussi di uscita.
Ogni regola prevede alcuni parametri:
- la versione del protocollo IP: v4 oppure v6
- il tipo: per esempio HTTP, HTTPS, SSH
- il protocollo di terzo livello: TCP o UDP
- la porta: per esempio 80 per HTTP, 22 per SSH
- gli ip sorgenti: qui è possibile definire il range di IP di questa regola, per esempio 0.0.0.0/0 indica l'apertura a tutti gli IP
Da non confondere queste regole come regole firewall, il WAF permette di regolare il traffico da internet ad un nodo in cloud mentre il security group definisce le regole di rete di una singola istanza anche all'interno dello stesso ecosistema in una infrastruttura aws, per esempio se ci sono due istanze è possibile definire le regole di comunicazione di queste due istanze, senza alcuna regola specifica il traffico è bloccato di default anche quando si trovano nella stessa subnet. Con CloudFormation il security group viene definito nel template con l'elenco delle regole, per esempio:
ES14ServerSecurityGroup:
Type: AWS::EC2::SecurityGroup
Properties:
GroupDescription: 'Server security group'
GroupName: 'ServerSecurityGroup'
SecurityGroupIngress:
- CidrIp: '0.0.0.0/0'
IpProtocol: TCP
FromPort: 22
ToPort: 22
E' possibile configurare un trigger o una schedulazione di EventBridge per eseguire comandi shell in una o più istanze EC2, stiamo parlando di istanze EC2 dove in esecuzione con una riga di comando attiva, come la power shell di MsWindows o una shell di GNU Linux. Prima di tutto bisogna avere ben in mente il comando, per esempio uno script sh in un file eseguibile
#!/bin/bash
date +"%Y %m %d %H %M %S" >> /home/ec2-user/file.txt
Poi su EventBridge bisogna creare da console una nuova regola impostando le configurazioni base come il nome e la regola di esecuzione, poi nella selezione del target bisogna inserire "System Manager Run Command" e il Document "AWS-RunShellScript", per eseguirlo in una o più specifiche istanze nel target key bisogna inserire inserire il valore costante "InstanceIds" e poi nel target value bisogna inserire tutti gli id-istanza che si possono recuperare dall'elenco istanze EC2. L'impostazione del comando da eseguire è nella proprietà avanzata Commands (o "command line") all'interno della sezione "Configure automation parameter(s)", ricordandosi di premere il bottone "Add" dopo aver inserito qualunque dei valori sopra indicati. Dopo il salvataggio e la creazione della regola, nella console web di AWS si possono visualizzare tutte le esecuzioni nel tab monitoring visto che tutte le esecuzioni vengono monitorate e salvate in dei log specifici. Da notare che è presente l'opzione attiva di default per creare una regola IAM per permettere alla regola EventBridge a richiamare un servizio EC2.
La procedura per creare una macchine virtuali EC2 con all'interno un sistema operativo Microsoft Windows è la stessa già descritta per le istanze con Linux con due dettagli aggiuntivi. La prima particolarità è che all'interno della procedura guidata da console è possibile selezionare, non solo il sistema MsWindows ma anche la versione dalla più recente "Windows 2022 server" ad alcune più datate come la 2012. Trattandosi di sistemi operativi a pagamento, le licenze sono a carico del "customer" e quindi devono essere acquistate, in questo caso non si usa il servizio "AWS licence manager" ma AWS acquista in automatico la licenza e poi la distribuisce nell'istanza.
La seconda particolarità è la modalità di recupero della password dell'utente administrator, per procedere al recupero in fase di creazione bisogna indicare una Key (chiave pem/pkk), dopo la creazione in console nella sezione sicurezza (security) c'è una opzione dedicata proprio al recupero della password di amministratore, questa procedra richiede la chiave privata inserita in fase di creazione, senza la chiave non è possibile recuprare la password e non è possibile farlo in nessun altro modo.
Quando si usano sistemi MsWindows bisogna sempre ricordarsi di abilitare la porta 3306 nei secutity group in ingresso se la modalità di connessione è attraverso RDP (desktop remoto) visto che con windows (di default) non è possibile usare la porta 22 per il protocollo SSH. Inoltre bisogna sempre tenere ben presente che il costo delle EC2 è maggiore rispetto alle istanze avviate con Linux all'interno.
E' sempre consigliato non usare l'utente amministratore ma è consigliato l'uso di un utente creato specificatamente nella istanza EC2, in particolare se la istanza è esposta in internet tramite un IP pubblico, bisogna prestate attenzione alle regole di rete in ingresso, è best-practice impostare nel security group le regole di ingresso solo da l'indirizzo IP sorgente e non usare la scorciatoia di aprire a tutte le sorgenti con la regola CIDR "0.0.0.0/0" che è sempre sconsigliata.
Esiste un piccolo ma utilissimo servizio messo a disposizione da AWS per le istanze EC2 con sistema operativo Linux, questo servizio permette di avere informazioni del sistema all'interno delle istanze stesse.
Il servizio è di tipo API rest e risponde all'indirizzo
http://169.254.169.254/
ma usandolo da fuori le istanze EC2 questo servizio non risulta disponibile. Questo servizio permette di "imparare" in una istanza EC2 le proprie caratteristiche, senza compromettere la sicurezza del cloud visto: per le regole IAM non è possibile visualizzare le policy ma si possono vedere solo i nomi delle regole.
Per richiamare il servizio è possibile usare il comando curl dalle istanze EC2
$ curl http://169.254.169.254/
l'elenco tornato da questo comando sono le varie versioni delle API, usando il comando
$ curl http://169.254.169.254/latest/
si usa l'ultima versione delle API e il risutato di questo comando è una lista di risorse messe a disposizione delle API. Le due risorse principali messe a disposizione sono user-data e meta-data, concetti da non confondere: il primo è lo script eseguito all'avvio della EC2, il secondo è l'elenco delle infomrazioni disponibili come meta-dati di una EC2.
Per ottenere l'elenco dei matadati basta lanciare il comando
$ curl http://169.254.169.254/latest/meta-data
E poi si può ottenere il singolo valore del meta, per esempio
$ curl http://169.254.169.254/latest/meta-data/hostname
Inoltre è possibile otterenere all'interno di una EC2 la credenziali di collegamento attive con
$ curl http://169.254.169.254/latest/meta-data/iam/security-credentials/
Che ritorna la tupla:
{acessid, secretid, token}
Ovviamente questi comandi fuori da una EC2 non sono disponibili per motivi di sicurezza e non vengono molto consigliati ma è sempre buono sapere che esistono.
Il servizio di Autoscaling delle EC2 di AWS permette di monitorare il numero di istanze applicative regolando automaticamente l'aumento o la diminuzione in base a dei criteri prefissati. Il caso d'uso più diffuso e usato è la creazione di una immagine AMI e poi l'avvio di più istanze EC2, il numero di istanze viene regolato da una regola di scalabilità in base alla CPU o altre metriche.
In fase di creazione da console si deve selezionare:
- il nome che permetterà di identificare il gruppo anche nella vista EC2: le istanze appartanenti ad un gruppo ottengono il tag di quel gruppo
- la regola di "launch configuration" con la quale si gestire la regola di creazione delle istanze
- la VPC e le AZ associate se sono disponibili subnet
- il load balancer associato a questo gruppo per permettere l'accesso e il bilanciamento, è possibile non selezionare nulla
- la verifica di "health check", cioè la regola che verifica il corretto funzionamento delle istanze, in quanto eventuali istanze con problemi vengono distrutte e vengono sostituite
- le dimensioni del gruppo con l'impostazione del numero minimo, massimo e il desiderato
- eventuali notifiche in caso di modifica del gruppo tramite il servizio SNS
Da notare che in fase di creazione non vengono richieste alcune proprietà importanti che devono essere impostate nel "launch configuration", per esempio
- la immagine AMI ufficiale o una AMI gestita e creata dall'utente nello store
- il tipo di istanze in quanto all'interno di gruppo tutte le istanze devono avere la stessa dimensione
- la chiave "key pair" gestita da KMS per permette la connessione remota
- il security group che verrà assegnato ad ogni istanza (da notare che senza regole specifiche le istanze non potranno comunicare tra di loro)
Nel dettaglio di un gruppo è possibile gestire
- gli eventi passati del gruppo con uno storico dettagliato
- le regole di scalabilità automatica
- gestione delle singole istanze con i dettagli
- la procedura di refresh di tutte le istanze
La documentazione ufficiale è molto dettagliata visto che questo è uno dei servizi più usati. Il servizio è gratuito ma bisogna sempre ricordare che tutte le istanze EC2 sottostanti sono ovviamente a pagamento quindi bisogna sempre prestare attenzione.
Il servizio di bilanciamento e distribuzione del traffico tra applicazioni è gestito dal servizio Ellastic Load Balancing e mette a disposizione quattro tipi di bilanciamento:
- Application Load Balancer: il tipo più usato perchè è il bilancamento viene eseguito a livelli 7 cioè a livello di protocollo HTTP o di altro tipo applicativo
- Network Load Balancer: il tipo di bilanciamento a livello 4 cioè usando il protocollo TPC o UDP
- Gateway Load Balancer: il tipo di bilanciamento a livello 3 cioè usando il solo protocollo IP
- Classic Load Balancer: il tipo originale di AWS, considerato deprecato in quanto sostituito con i precedenti
In fase di creazione di un bilanciatore si devono selezionare i parametri
- il tipo (application, network oppure gateway)
- esposizione internet, nel caso venga abilitata sarà creata un nome con il quale è possibile accedervi da internet
- VPN, subnet e AZ, infatti è possibile posizionare il bilanciatore nelle subnet private ma con la precedente regola avere un entry-point pubblico
- security group per regolare il traffico in ingresso ed in uscita
- l'eventuale AutoScaling group e il "target group" se presenti
Il servizio è molto usato sia per creare degli entry-point pubblici a risorse private ed è studiato proprio per integratsi con il servizio di AutoScaling e creare un unico enpoint per tutte le istanze appartenenti ad un gruppo creato con il servizio di AutoScaling e poi gestite come "target group" dal servizio.
Il bilanciatore crea una "specie" di Firewall e proxy con i quale è possibile regolare alcune regole di rete tra cui il protocollo SSL/TLS, regole di redirect anche se è sempre consigliato usare un WAF come strumento per le regole di traffico di rete. I costi del servizio variano dal tipo e dalla region di appartenenza, per esempio l'Application in Irlanda costa 0,0252 USD per ora, bisogna comunque sempre monitorare i costi, le varie tariffe sono disponibili nella pagina ufficiale.
In questo articolo sono elencati altri servizi di compute, il servizio EC2 è il più usato ma AWS mette a disposizione altri tipi di server più specifici e dedicati. Elastic Load Balancer: è il servizio che imposta e gestisce il bilanciatore in caso di architettura tra server EC2.
Lightsail: è un servizio che crea dei server virtuali privati con già impostata una applicazione specifica. Questo servizio permette infatti di creare velocemente server con già configurato un WordPress, Redmine, GitLab, Joombla e molti altri. E' possibile anche creare istanze senza applicazioni ma con demoni preinstallati come i LAMP, Node, Nginx o Django, questo tipo di istanze sono poi personalizzabili a piacimento. L'abbonamento gratuito prevede una istanza (limitata) per tre mesi mentre poi le istanze sono da 5 dollari al mese. E' possibile anche eseguire snaposhot di una istanza per poi creare backup o rindondanze per l'alta affidabilità.
ECS (Elastic container service): è il servizio di esecuzione e gestione di istanze container di tipo Docker, il servizio permette di avviare su istanze EC2 istanze caricate dall'utente permettendo in questo modo la scalabilità pura. Il servizio permette anche la gestione di batch e istanze OnDemand, per esempio l'avvio di una istanza ad un certo orario e poi lo spegnimento al termine dell'esecuzione. Il metodo classico con istanze EC2 non prevede costi aggiuntivi oltre al costo stesso dell'istanza mentre il sistema Fargate Launch prevede costi in base all'utilizzo di CPU e memoria.
Lambda: è il servizio di nuova generazione che prevede la definizione di codice sorgente da eseguire "senza server" (dall'inglese servless). Il concetto di questo tipo di servizio è definire il codice da eseguire e poi, ad ogni chiamata, viene avviata una mini-istanza di un server virtuale che esegue il codice della funzione lambda e poi l'istanza viene spenta. Vista la natura del servizio, ogni chiamata ha un tempo di latenza superiore perchè si deve sommare anche il tempo di avvio dell'ambiente virtuale, per questo motivo viene usato per quelle funzionalità eseguite molto raramente oppure trigger su eventi che non necessitano la simultanea. Il servizio permette anche di configurare un tempo di spegnimento, in modo tale che una virtuale con una lamda rimanga attiva per un tempo prestabilito in modo tale che il tempo di avvio venga "pagato" solo dalla prima chiamata mentre le successive trovino già l'istanza attiva. Uno dei grandi vantaggi di questo servizio è la scalabilità automatica: in caso di carico eccessivo su una virtuale, viene avviata una seconda istanza (o una istanza più potente) con una divisione del carico con il conseguente abbassamento dei tempi di esecuzione e risposta. I costi sono in base alle esecuzione e in particolare il costo base è di 0,20 dollari per ogni milione di richieste ma il prezzo può variare in base al tipo di server su cui si esegue la lambda (che poi servless non è visto che si paga in base alla dimensione di server). Da notare che il prezzo è in base alle chiamate e non in base al numero di istanze avviate. Una funzione lambda può essere richiamata da un trigger su bucket S3 oppure tramite una API Rest tramite il servizio Api gateway entrambi questi esempi saranno descritti in successivi articoli in questa categoria.
Step Functions: è un servizio con il quale è possibile definire flusso di lavoro visivo nei quali i passi sono altri servizi AWS. Questo tipo di servizio è utilizzato per automatizzare i processi all'interno di una infrastruttura AWS e creare applicazioni serverless. Con questo strumento è possibile gestire gli errori, i tentativi falliti e lo storico delle esecuzioni tramite il servizio di log di CloudWatch. Il piano gratuito prevede 4.000 transizioni di stato al mese e poi un costo di 0,025 dollari per 1.000 transizioni di stato.
Elastic beanstalk: è il servizio di esecuzione di applicazioni Web, caricando direttamente il codice dei una applicazione frontend, il servizio va a gestire il bilanciamento del carico, il provisioning delle risorse e il monitoraggio. Il servizio prevede un lungo elenco di linguaggi come Java, Python, Ruby, Node.js e Php. Questo servizio si basa sugli altri servizi come le istanze EC2 e i bucket S3. Anche questo servizio non presenta costi aggiuntivi ma i costi sono quelli calcolati in base alle risorse utilizzate per l'esecuzione (bucket S3 e le istanze Amazon EC2).
La funzioni lambda sono un nuovo paradigma della programmazione dove il codice viene eseguito da un server non definito, anche si chiamano ServerLess in realtà il server esiste ma il programmatore e l'architetto non deve studiare e definire quale server esegue la funzione in maniera autonoma come fosse un oggetto asincrono. I vantaggi di usare questa tecnologia sono innumerevoli: per esempio velocità, stabilità, basso costo di sviluppo e zero di manutenzione; sono spesso usate per creare API Resti visto che il le funzioni lambda sono studiate per interfacciarsi con il servizio AWS ApiGatewey; tuttavia tali funzioni hanno alcune limitazioni: la esecuzione non deve durare più di 10 minuti e il controllo sulle esecuzioni.
Lo sviluppo può essere fatto da console AWS, AWS CloudFormation, AWS SAM oppure da AWS SDK, per i vari tool di sviluppo si rimanda ai corrispettivi articoli mentre i passi per creare una lambda sono molto semplici e facilmente mantenibili da chiunque abbia conoscenze di AWS e di un linguaggio di programmazione. Per la creazione di una funzione basta entrare nella console e selezionare il servizio specifico di Lambda, da notare che nel menù sono presenti diverse voci tra cui funzioni e applicazioni, le seconde sono gruppi di lambda che verranno introdotti in un articolo dedicato.
Al momento di creazione si possono selezionare diversi template pronti:
- "Da zero" che prevede una lambda iniziale vuota
- "Usa un piano" che permette di partire da un template, la lista dei template è tutta da scoprire
- "Immagine container" che permette di selezionare una immagine Docket container
- "Repository dell'app serverless" permette di scaricare da un repository pubblico alcuni template pronti
La cosa più semplice è selezionare la prima possibilità che andrà a creare solo un metodo vuoto per la creazione. In fase di creazione bisogna inoltre assegnare un nome, l'architettura (x86_64 oppure arm64) e il tipo di linguaggio (runtime); nella vista autorizzazioni è possibile selezionare se creare un nuovo ruolo IAM oppure usarne uno esistente, di default è selezionata la prima che è la scelta consigliata visto che si crea in automatico un nuovo ruolo con le autorizzazioni Lambda di base.
In questo esempio verrà usato Python3.9 ma è possibile trovare molti altri esempi nel git
https://github.com/alnao/AwsLambdaExamples
Di default nel template "da zero" viene generato un metodo di default lambda_handler
che ritorna il status code 200 (HTTP OK). Nella console è possibile modificare il codice dall'editor ed è possibile modificare le impostazioni di RunTime come il nome del metodo che di default è sempre lambda_function.lambda_handler
nel caso di Python. Nella console è disponibile un tab e un bottone per testare una funzione direttamente da console, per ogni test bisogna assegnare un nome se non già presente e un json di evento che simula l'input arrivante da un chiamante (per esempio un trigger); una volta eseguita la lambda viene visualizzata una scheda "Exection result" dove si vede la risposta e log.
Per ogni tipo di lambda è possibile visualizzare il tab Monitoraggio dove si vedono tutti i log con il dettaglio delle chiamate, è presente anche un bottone per visualizzare i log in CloudWatch. Nel tab configurazione è possibile vedere i dettagli della lambda: se c'è un trigger su EventBridge, le autorizzazioni IAM e le variabili di ambiente se sono definite. E' possibile permettere ad una lambda di accedere ad un file system dalla vista dedicata dentro al tab configurazione. Sempre attraverso la console web è possibile creare una macchina a stati tramite il servizio Step Function con il bottone nel tab dedicato.
Il "Lambda Authorizer" ( a volte conosciuto anche come ApiAuthorizer) è una caratteristica del servizio Api Gateway che permette di controllare l’accesso alle risorse API esposte usando una Lambda, questa tecnica è pensata e molto usata per implementare il livello di autorizzazione e autenticazione delle API esposti tramite un “bearer token” come OAuth o SAML come previsto dalle tecniche più comuni dei servizi REST e HTTP. L’autenticazione può avvenire in tre modi:
- REQUEST: un sistema basato su un parametro della chiamata che deve essere validato dalla lambda, il parametro può arrivare dal header http, come parametro nella query string o nel context della chiamata. Il sottoservizio WebSocket APIs prevede solo questo metodo.
- TOKEN: un sistema basato su Token ricevuto dal chiamante in un bearer token, come un JWT o un OAuth token, il processo di validazione avviene nel codice della lambda
- COGNITO_USER_POOLS: la validazione avviene grazie ad al servizio Cognito che deve essere usato per gestire gli utenti e le credenziali.
Nella console, se si dispone già di una API, nel dettaglio della API c’è una sezione dedicata “Authorizer” dove è possibile attivare l’autenticazione indicando un nome, il tipo, la funzione lambda (o il servizio cognito) e la regola di invocazione (facoltativa, nel caso sia vuoto la console crea una regola in automatico per avere i giusti permessi di invocazione). L’esempio più semplice che si può sviluppare è la validazione del token JWT tramite Request (e non il metodo TOKEN esposto in altro articolo). Nella request è possibile impostare “$request.header.Authorization” e poi la lambda riceve il valore del parametro:
def entrypoint(event, context):
token = event['headers']['Authorization']
Un esempio con il codice completo può essere trovato nella documentazione ufficiale.
Tipicamente la Lambda Function sono funzione studiate per dialogare con altri servizi AWS come le basi dati RDS, Dynamo o S3 oppure sono studiate per esporre API con il servizio di API Manager. Visto che di default i servizi AWS non hanno i permessi di dialogare tra loro, bisogna prevedere delle regole IAM per permettere le comunicazioni che possono essere create manualmente oppure usando il servizio di Lambda Application che lega le funzioni lambda con i servizi collegati. La creazione manuale è impossibile, di default la console presenta cinque opzioni
- API Rest esposte con API manager sviluppate con NodeJS
- Trigger su S3 per l'elaborazione di file
- Job Schedulato su CloudWatch Events
- Processo di notifiche basato sul servizio SNS
- Elaborazioni di Code bastato sul servizio SQS
questi sono esempi di default ma è presente anche "AWS Serverless Application Repository" oppure è possibile creare una funzione da zero indicando i parametri. In ogni creazione oltre al nme e al runtime, si deve indicare un repository CloudCommit oppure un repository CodeStarCommit collegando il servizio GitHub. In un box quasi nascosto inoltre è necessario aggiungere la voce di "Crea ruoli e limiti delle autorizzazioni" per la configurazione delle solite regole IAM. Una volta creata una app, nel dettaglio si possono vedere tutte le componenti che vengono create, nell'esempio di API Rest i componenti creati sono:
- un repository GIT nel servizio CodeCommit
- un modello SAM visibile nella vista distribuzione
- una tabella Dynamo visibile nel servizio dedicato
- API Rest esposte con il servizio API Gateway con i metodi GET e POST
Da notare che nel servizio API Gateway sono create due fasi per produzione e staging, in questo caso si può usare l'endpoint esposto
https://<id-api>.execute-api.<region>.amazonaws.com/Prod
per caricare dati nella tabella Dynamo con il metodo POST e poi recuperare l'elenco con il metodo GET.
Da notare che nel servizio CloudCommit è stato creato un repository dove sono presenti il modello SAM in formato yaml e tutto il codice e tutto il codice NodeJS per la gestione delle API ed è stato creato un servizio di CloudPipeline per i rilasci automatici. Per maggiori informazioni riguardo a come CloudPipeline lavora con le Lambda Application si rimanda all'articolo dedicato in cui viene descritto come eseguire i deploy automatici di una Application tramite il repository GIT di CloudCommit.
Il servizio Step Function è uno dei più innovativi servizi disponibili su AWS: permette di costruire flussi e state machine senza la scrittura di molto codice e senza la definizione dell'infrastruttura di esecuzione in quanto è classificato come server-less. E' un servizio low-code per definisce processi business grazie ad un workflow visuale con l'interfacciamento di altri servizi in maniera veloce e sicura. Spesso una step function viene anche State Machine tanto che i due concetti vengono spessi confusi, usando le traduzioni migliori disponibili possiamo dire che:
- step function è il nome del servizio AWS usato per definire state machine
- state machine è la singola definizione di una sequenza di operazioni
- task è il nome di ogni singola operazione/passo eseguito all'interno di una state machine
All'interno della console sono elencate tutte le state machine disponibili, all'interno del dettaglio di ogni singola state è possibile vedere tutte le esecuzioni , i relativi log e lo schema di definizione. La definizione di una state machine è un elenco di task che possono essere rappresentati come file json, file yaml oppure in forma grafica come schema grazie ad un servizio chiamato "Graph inspector". I task base chiamati "flow" possono essere del tipo:
- pass: inserire dati in output
- choise: definizione di una istruzione logica a seconda dell'input
- wait: aggiungere un delay alla state machine
- success: termina l'esecuzione con un successo
- fail: termina l'esecuzione con un errore
- parralel: implementa esecuzioni parallele
- task: talvolta vengono chiamati task quei passi che eseguono altri servizi come funzioni lambda o altri servizi
Usando la console di AWS è possibile creare manualmente una StateMachine scrivendo il codice manualmente oppure l'opzione per disegnare il flow selezionando l'opzione "Design your workflow visually". Nel diagramma si possono inserire i tipi descritti poco fa nella vista "flow" oppure inserire oggetti AWS nella vista "actions", in questo secondo caso si possono inserire
- esecuzioni di funzioni Lambda
- push su code SNS
- esecuzioni di task ECS
- esecuzioni ad altre state machin
- esecuzione di job AWS Glue
Una delle funzionalità principali di AWS Toolit su MS Visual Studio Code è la creazione di state machine si rimanda all'articolo dedicato per una mini guida.
LightSail è un servizio che gestisce delle istanze EC2 con delle immagini AMI preparate e già disponibili per l'uso, alcuni di questi tipi sono molto sofisticati con applicativi o demoni molto evoluti mentre altri tipi sono semplici. La scopo di questo servizio è creare dei server pronti all'uso con pochi click in sicurezza e in velocità con la certezza che l'immagine installata è funzionante e ottimale per il servizio richiesto.
Il classico esempio di servizio LightSail è la creazione di una istanza con un sito WordPress funzionante e stabile, ma sono disponibili diversi AMI per varie configurazioni come un servizio LAMP in Php, Joombla, Nginx in Typescript, Django in Python. Sono disponibili immagini anche con MS Windows Server ma queste non saranno esaminate in questo articolo.
Per creare una LightSail da console basta entrare nella console e premere nel bottone "Create instance", al primo passi si deve selezionare la regione (location), la piattaforma: Linux o Windows e la AMI (con la possibilità di installare solo il sistema operativo). Si deve selezionare che tipo di chiave usare, con la possibilità di modificare la chiave di connessione e si può selezionare l'opzione "Enable Automatic Snapshots" per eseguire immagini automatiche dell'istanza.
Successivamente si deve selezionare il tipo di istanza, anche se non sembra le scelte corrispondono sempre la tipo di EC2 e si possono vedere le caratteristiche delle istanze direttamente nella console, bisogna sempre tenere conto anche del costo delle istanze in quanto le AMI sono libere ma sono a pagamento i server ed eventualmente le licenze del software installato, per esempio nel caso di istanze con MS Windows Server. Dopo aver inserito il nome ed eventuali TAG per identificare velocemente la istanza sarà possibile avviare il servizio, l'avvio necessita qualche minuto e nella console si vedrà l'istanza in "starting" e poi in "running" quando correttamente avviata. Sempre nella console sarà visibile l'indirizzo ip pubblico e nel dettaglio saranno disponibili i dati dello storage, le regole di rete e altri informazioni utili dell'istanza. In particolare è sempre conveniente e sicuro modificare la regola di rete di accesso del protocollo SSH per limitare l'accesso ai soli indirizzi IP dell'amministratore visto che di default il servizio è aperto a tutto internet.
Per collegarsi via http basta andare via browser all'indirizzo io PUBBLICO, per collegarsi via SSH si può usare la console come mette a disposizione un simulatore di SSH tramite un bottone "Connect using SSH" oppure ci si può collegare via SSH usando la chiave inserita in fase di configurazione con il comando
ssh bitnami@54.73.52.219 -i chiave_privata.pem
Ovviamente nel server deve essere caricata SOLO la chiave pubblica mentre la pubblica NON deve essere caricata in nessuna console ma usata solo dal computer dove parte la connessione, attenzione a non inserire la chiave privata in nessun punto.
L'infrastruttura AWS mette a disposizione alcuni servizi per gestire e lavorare con applicazioni e sistemi basati su Docker:
- ECS (Elastic Container Services) la piattaforma principale con cui vengon gestiti le immagini e i container docker, con questo servizio è possibile creare "servizi" e "tasks" cioè immagini e container all'interno dell'infrastruttura AWS, tutti gli altri servizi sono sompresi e gestiti dalla ECS.
- EKS (Elastic Kubernetes Services) è il servizio per la gestione dei container realizzati con la tecnologia open-source Kubernetes
- Fargate è la piattaforma dove i containers vengono eseguiti si tratta di una alternativa al servizio EC2 infatti si può definire serverless in quanto non si sceglie il tipo di stanza ma solo il numero di CPU e la quantità di memoria RAM da usare.
- ECR (Elastic Container Repository) è il repository privato di AWS, in questo si possono trovare una lunga lista di immagini pronte all'uso ed è possibile creare la propria immagine, passaggio inevitabile se si vuole eseguire una immagine docker all'interno dell'ecosistema AWS-ECS.
Avviare un container su AWS significa eseguire un task con il servizio ECS all'interno di un cluser, la scelta è di eseguire l'immagine all'interno di una istanza EC2 oppure di usare Faregate, nel primo caso l'istanza sarà gestita dal servizio EC2 con la possibilità di collegamento e gestione interna, nel secondo caso il servizio Serverless quindi senza un server specifico da configurare e gestire.
Usando e gestendo questo servizio bisogna inoltre tenere presente alcune regole fondamentali che non possono essere trascurate:
- è necessario creare regole IAM specifiche per la gestione delle immagini, il servizio avvia le istanze ma le autorizzazioni delle immagini deve essere sempre esplicita, per esempio se una immagine deve leggere su un bucket S3 allora bisogna creare una regola IAM specifica proprio per questo permesso, così come per ogni servizio AWS e per ogni componente del Cloud, spesso questo tipo di regole viene chiamato "EC2 tasks role".
- è consigliato l'uso del Application Load Balancer integrato per la gestione del traffico di rete soprattutto quando si tratta di servizio http (web e/o rest per esempio), sono supportati ma sconsigliati il Network Load Balancer e il Elastic Load Balancer.
- è possibile usare il servizio EFS per creare volumi "montabili" dai tasks anche in maniera condivisa tra più tasks in esecuzione nello stesso momento, proprio in una filosofia serverless (EFS + Fargate).
- è necessario ricordare sempre che i docker hanno bisogno di regole di rete specifiche, per questo bisogna usare i Security Group, conviene infatti creare un SG per ogni immagine docker.
Ovviamente i servizi non sono gratuiti, l'unico servizio gratuiti è ECS mentre tutti gli altri servizi, come Fargate e EKS sono a pagamento e il prezzo dipende dalla zona e dalla quantità di risorse usate, risultano comunque convenienti rispetto alle classiche istanze messe a disposizione dal servizio EC2.
Per il carico della immagine docker su AWS bisogna usare il servizio di Elastic Container Repository (ECR), per farlo bisogna aver installato la CLI di AWS e poi bisona eseguire il caricamento su ECR:
$ aws ecr create-repository --repository-name examplemicro1 --region eu-west-1
Il risultato sarà un json di risposta con il codice repositoryUri che sarà indispensabile nei passi successivi
{
"repository": {
"repositoryArn": "arn:aws:ecr:eu-west-1:XXXXXXX:repository/examplemicro1",
"registryId": "XXXXXXX",
"repositoryName": "examplemicro1",
"repositoryUri": "XXXXXXX.dkr.ecr.eu-west-1.amazonaws.com/examplemicro1",
"createdAt": "2022-03-22T14:12:53+01:00",
"imageTagMutability": "MUTABLE",
"imageScanningConfiguration": {
"scanOnPush": false
},
"encryptionConfiguration": {
"encryptionType": "AES256"
}
}
}
Successivamente bisogna creare il tag per l'immagine con il comando usando il valore del repositoryUri
$ docker images --filter reference=examplemicro1
$ docker tag <immagineID> <repositoryUri>
E poi si carica l'immagine su AWS grazie al tag appena creato
$ aws ecr get-login-password | docker login --username AWS --password-stdin XXXXXXX.dkr.ecr.eu-west-1.amazonaws.com/examplemicro1
$ docker push XXXXXXX.dkr.ecr.eu-west-1.amazonaws.com/examplemicro1
dopo un po' di tempo l'immagine viene caricata e basta controllare nella console web di AWS per verificare il corretto caricamento dell'immagine su AWS ECR. Successivamente bisogna creare una regola nel servizio IAM attivando con "Allow" l'accesso alla immagine appena creata usando il path ARN creato in precedenza.
Per avviare l'immagine caricata basta accedere al servizio di Elastic Container System (ECS) e avviare una istanza di tipo custom selezionando l'immagine caricata in precedenza.
In fase di configurazione bisogna ricordarsi di configurare il port mapping aprendo la porta 5001 o qualunque porta esposta dall'immagine, in assenza della regola di rete la porta non sarà esposta.
L'esposizione viene eseguita dal servizio di Load Balancer quindi l'url di accesso sarà del tipo
http://<id-id>.eu-west-1.elb.amazonaws.com:5001/api/demos/response
Per eliminare l'istanza bisogna procedere direttamente dal ECS mentre l'immagine depositata su ECR può essere cancellata con il comando:
$ aws ecr delete-repository --repository-name examplemicro1 --region eu-west-1 --force
dove si ottiene un json di risposta di conferma.
Il servizio ECS è il principale attore in AWS e viene usato per gestire anche gli altri servizi come EKS e Fargate. Per usare il servizio bisogna conoscere a fondo tre componenti: il task definition, il concetto di cluster e service.
Il task definition è la configurazione dell'immagine con le caratteristiche:
- il tipo di isanza: EC2 o Fargate
- la regola IAM dei task
- il tipo di networking: per esempio BRIDGE o NAT
- la quantità di risorse necessarie: CPU e Memoria
- l'immagine docker con nome, uri e port mapping
- alcune opzione avanzate come la definizione di volumi esterni, gestione log, proxy
Il cluser è la configurazion dell'infrastruttura conle caratteristiche:
- il tipo: ondemand
- il tipo di istanze EC2 se si usa questo tipo oppure la quantità di risorse se si usa Fargate
- le regole di rete come VPC e Subnet
- la regola IAM del cluster
Infine si definisce il servizio e all'avvio delle istanze nei task dove bisogna definire le caratteristiche:
- il task associato al servizio
- il cluster associato dove verrà avviato il task
- il numero di task avviati nel servizio
- il tipo di deployment, per esempio Rolling update
- il "placement tamplate", per esempio AZ spread
- il ALB (load balancer) associato
- la regola di autoscaling con un ASG assiociato
Per ogni caratteristica e per ogni possibile opzione di questo servizio si rimanda alla documentazione disponibile nel sito ufficiale. Nell'usare questo servizio bisogna anche sempre tenere presente i costi delle istanze EC2 o delle risorse Fargate usate in quanto il servizio è tanto potente ma può risultare costoso se usato e configurato male.
L'avvio di una immagine docker può apparire molto complicata ma in realtà è molto più semplice di quanto possa sembrare: prima di partire bisogna avere l'uri del docker e un'idea del tipo di risorse necessarie. Per questo semplice esempio useremo l'immagine di apache chiamata httpd disponibile nel repository ufficiale all'indirizzo
https://hub.docker.com/_/httpd
Da notare che dal sito ufficiale hub.docker.com ha il nome "httpd" che sarà il nome che andremo a configurare nel nostro ECS in quanto il servizio oltre ad usare il repository interno AWS chiamato ECR usa anche il repository ufficiale di hub.docker.com. I passi da eseguire per creare un piccolo esistema docker è:
- in ECS creare un task definition indicando l'uri selezionata ("httpd" nel nostro caso) e quantità di risorse RAM e CPU adeguate (nel nostro caso 500Mb di ram e una vCPU sono più che sufficienti)
- in ECS creare un cluster di tipo On-Demand indicando una istanze EC2 di dimensioni t2.micro (nel nostro caso basta ed è gratuita), in automatico si crea una istanze EC2 che sarà il nostro punto di riferimento, se si è creato un ip pubblico sarà possibile usarlo per vedere se funziona, inoltre è anche possibile usare le chiavi per collegersi via SSH
- creare un target group con destinazione la EC2
- creare un application load balancer indicando il target group come destinazione
- creare un security group per il load balancer e ricorarsi di configurare la regole di rete per permettere al load balancer di comunicare con la istanza EC2 (nel nostro caso basta definire la porta 80 per il protocollo http, in caso di più task avviati sulla stessa macchina bisogna studiare bene le regole di rete per evitare blocchi tra il ALB e la EC2)
- in ECS creare un service all'interno del cluser indicando il tutti componenti creati in precedenza (task, cluser e load balancer), indicando un numero di istanza maggiore di 2 verranno avviate più immagini all'interno del nostro cluster ma il load balancer effettuerà il lavoro sporco dell'instradamento di rete.
Questo è un semplice esempio di come è possibile avviare una istanza apache2-httpd in docker tramite il servizio ECS di AWS ma come è facile vedere per usare questo servizio bisogna bene conoscere tutti gli altri servizi tra cui le configurazioni di rete security group e gli application load balancer.
Il servizio di Elastic Beanstalk è uno dei servizi più potenti ma complessi di tutta l'architettura cloud di AWS perché viene usato per gestire e creare altri servizi mettendo al centro dell'architettura una applicazione. In particolare questo servizio viene usato moltissimo nel caso di applicazioni web o infrastruttura a micro-servizi dove è necessario gestire l'applicazione ma anche il ciclo di vita del software e la scalabilità in alta affidabilità. Per questo motivo Beanstalk è il servizio preferito da noi programmatori nonostante la sua complessità, è totalmente gratuito anche se bisogna sempre ricordare che si pagano le risorse che vengono create e gestite dal servizio.
Il servizio si basa su tre concetti qui elencati con il nome in inglese per semplicità:
- application: è l'insieme delle configurazioni per eseguire una applicazione in ambiente (application on environment)
- version: una fotografia (detta anche snapshot) del codice ad un certo istante, si presume compilato e funzionante
- environments: una esecuzione delle applicazione definita da tutte le risorse necessarie
Esistono due versioni chiamati tier: la "web server" e "worker enviroment", in questo semplice esempio verrà mostrato solo la web mentre la worker riguarda una iterazione tra SQS ed EC2. Un "web server tier" è una infrastuttura automatica con un Applicazion Load Balancer, un Autoscaling Group, le istanze ed e i corrispettivi security group. Il tipo di server/demone installato viene selezionato in fase di definizione della application.
Per creare la prima applicazione la procedura guidata della console richiede il nome, la piattaforma e il codice, come primo esperimento si può selezionare la piattaforma NodeJs e il codice di esempio che AWS mette a disposizione. Dopo aver definito l'application nessuna risorsa viene eseguita e questo si può fare grazie alla voce di menù "environmens", alcune versioni più recenti della console creano in automatico un ambiente subito dopo la creazione dell'application.
In fase di creazione del environment, la procedura guidata della console richiede il tipo (tier Web o tier Work), l'ambiente e l'application da eseguire Inoltre è possibile configurare i dettagli dell'ambiente cliccando nel bottone "Advanced configuration", questi dettagli saranno descritti in un futuro articolo.
Da notare che in fase di creazione dell'enviroments è necessario inserire un url, questo sarà l'url pubblico del bilanciatore ALB che verrà creato in automatico, il link pubblico di accesso è sempre nel formato
http://<nomeaambiente>.<region>.elasticbeanstalk.com/
In fase di creazione vengono creati in automatico
- Application Load Balancer e un security group per regolare il traffico nella porta 80-HTTP
- Autoscaling group
- Instanza EC2 con il server selezionato (nel caso di Node c'è il webserver)
- Security group per regolare il traffico nella porta 80-HTTP dal ALB alla istanza EC2
E' sempre possibile navigare nel servizio EC2 per notare tutte le risorse create, bisogna sempre ricordarsi che tutte le risorse vengono eliminate se viene eliminato l'environments dal servizio Beanstalk, il servizio infatti è ben progettato per evitare di abbandonare risorse orfane e inutili. Nella console di BeanStalk è possibile vedere alcuni dettagli dell'ambiente tra cui le configurazioni, i log, il monitoraggio e l'elenco di tutti gli eventi riguardanti l'ambiente.
Nella console di BeanStalk è possibile configurare nel dettaglio un ambiente di esecuzione di una applicazione (environments per chi usa la console in lingua inglese). La configurazione principale più evoluta è la modalità di deploy e la scelta è tra i tipi deploy degli aggiornamenti del software:
- "all at once": tutte le istanze vengono aggiornate assieme
- "rolling": le istanze vengono divise in due gruppi e aggiornate uno dopo l'altra
- "rolling with batches": le istanze vengono divise in due gruppi, viene creato un terzo gruppo e poi man mano vengono aggiornate tutti i gruppi
- "immutable" vengono create nuove istanze e successivamente vengno distrutte le vecchie istanze
- "blue/green" e "swap enviromns URLS" prevedono l'uso del Route53 e delle regole DNS per gestire più ALB con più istanze avviate
Queste tecniche hanno ovviamente costi diversi e quindi bisogna sempre prestare attenzione al numero di istanze avviate nello stesso momento. Altra configurazione molto importante è il numero di istanze appartenenete al autoscaling-group, anche in questo caso è possibile selezionare per ambiente, infatti si pressuppone che un ambiente di test necessiti di un solo server ma in un ambiente di produzione l'alta affidalità necessiti un numero di server maggiore.
Le configurazioni avanzate inoltre permettono di configurare velocemente
- log con Xray e cloudWatch, con la possibilità di salvare in un bucket S3 tutti i log degli ambienti
- un volume-root specifico delle istanze e condiviso
- le regole di rete della VPC e dei security groups
- il tipo di istanze EC2 avviate e la AZ corrispondente
- monitoraggio con trigger e alert con metriche specifiche, come il consumo della CPU e il traffico in ingresso
- database RDS usato dall'applicazione, in questo caso bisogna sempre ricordarsi che l'eliminazione dell'environments causa immediatamente la cancellazione di tutti i dati nel RDS se creato
La documentazione ufficiale descrive tutte le proprietà e le configurazioni di questo fantastico servizio.
Il servizio Elastic BeanStalk presente su AWS permette di avviare micro-servizi su istanze con pochi click e nessuna configurazione sistemistica. Si rimanda alla guida di AWS per la creazione della utenza con il piano gratuito e dell'uso dei servizi base di AWS. In questo articolo sarà usata una istanza t2micro
che rientra nel piano gratuito di AWS quindi non prevede nessun costo ma bisogna prestare attenzione ai passi eseguiti.
Prima di tutto, entrati nel servizio di Elastic BeanStalk, bisogna creare una applicazione impostando il nome e il tipo di piattaforma ovviamente selezionare Java alla versione 11. E' possibile selezionare anche Java alla versione 8 se si è usato quella versione della JRE. Alla fine della pagina si deve selezionare "Carica il tuo codice" e si può selezionare dal proprio pc il file jar del micro-servizio. L'alternativa è creare un S3 pubblico con il file caricato ma la scelta è sconsigliata. Una volta creata l'applicazione si vedrà una console dove nella console AWS compaiono i passi eseguiti, come la creazione del security group e lo storage su S3.
Una volta avviata l'applicazione bisogna si può notare sulla console di EC2 che è presente una nuova istanza e che questa è avviata correttamente con un suo IP. Prima di provare la API su quel indirizzo bisogna modificare il security group di quella istanza perchè di default AWS crea una regola solo sulla porta 80 mentre il micro-servizio è esposto su un'altra porta, quindi bisogna eliminare la regola sulla porta 80 e si deve creare una regola di incoming sulla porta specifica del micro-servizio, nel esempio è la 5051.
Terminata questa configurazione la API risponderà al EndPoint:
http://<IndirizzoIP>:5051/api/demoms/response
Per evitare costi inutili conviene sempre cancellare la istanza EC2 e la applicazione Elastic BeanStalk, altrimenti si rischiano addebiti indesiderati se dovesse rimanere attiva dopo la prova per diverso tempo.
Il servizio Glue è studiato come integrator-data di tipo serverless per semplificare l'analisi dei dati con differenti sorgenti anche disomogenee tra loro infatti è studiato per il machine learning, lo sviluppo di flussi applicativi, strumenti per la produttività, integrazione con base dati e molti altri casi d'uso. E' uno dei servizi più complessi ma anche più potenti di tutta l'infrastruttura Coud di AWS. Si può dividere in due grandi sottoprodotti: il data catalog e i JOB: il primo è la definizione della struttura dati generale mentre il secondo è il codice che elabora i dati statti. Glue Studio è l'interfaccia da console che pemette di gestire facilmente i JOB, crendo e monitorando l'esecuzione con la possibilità di eseguire codice Apache Spark–based di tipo serverless. Il linguaggio di programmazione principale usato il Python con Spark e Pandas come possibili librerie per la rappresentazione e la manipolazione dei dati.
Per creare un semplice JOB, la via più semplice è usare la procedura guidata disponibile da console selezionando il tipo "Spark script editor" in "Create job" e in automatico viene creata un'infrastuttura dove è possibile scrivere e/o incollare il codice con le informazioni addizionali da inserire nel tab "Job detail" dove bisogna indicare il nome, la regola IAM e la location (bucket e il file di destinazione), tutti campi obbligatori per poter salvare il JOB. La regola IAM deve essere creata manualmente oppure si può selezionare un già esistente, deve contenere le regole che permettano al JOB di accedere ai dati e agli oggetti usati come i bucket S3 o base dati RDS inoltre è consigliato aggiungere la regola di accesso a CloudWatch per permettere al JOB di scrivere i log nel servizio centrale di AWS.
Un semplice codice di esempio può essere trovato nel sito ufficiale
https://docs.aws.amazon.com/glue/latest/dg/aws-glue-programming-intro-tutorial.html
oppure anche un mio semplice caso d'uso di manipolazione di csv nel repository:
https://github.com/alnao/PythonExamples/tree/master/AWSGlue
Per avviare manualmente il JOB è presente il bottone "Run" da console e per monitorare le esecuzioni è presente il tab dedicato che elenca le esecuzioni con tutte le informazioni con anche i riferimenti ai log dell'esecuzione se presenti, in caso di errori infatti sarà possibile accedere ai Log dal servizio CloudWatch grazie al link disponibile nel dettaglio dell'esecuzione del JOB. Da notare che ogni definizione di JOB ha i suoi limiti di risorse (CPU, memoria, timeout) che possono essere viste nella scheda del monitoraggio e modificate a seconda delle esigenze operative prima dell'esecuzione, i limiti massimi di esecuzioni sono molto maggiori del servizio lambda e ipoteticamente sono quasi illimitate.
Il costo del servizio viene calcolato in base al reale utilizzo, di base si paga 0.44 $ per ogni ora di utilizzo di D-CPU di progessi JOB-Spark, prima di avviare qualunque processo è consigliato l'analisi dei costi in base alle risorse usate e al tempo di esecuzione.
I servizi di base di dati sono ormai indispensabili per le aziende e per qualsiasi applicazione. Su AWS sono disponibili diversi tipi di base di dati.
RDS è il servizio di sistemi tradizionali con DBMS relazionali come Aurora (proprietario di Amazon), Mysql, PostgreSQL, Oracle BYOL e molti altri. Non è necessario preoccuparsi della installazione del server e del DBMS visto che AWS mette già a disposizione la base di dati pronta all'uso, con un collegamento diretto. E' possibile facilmente creare backup e snaphot che poi possono essere usati per ripristino o copie per l'alta affidabilità. Anche per questo servizio esistono diversi tipi di server pronti per l'uso sempre identificati dai nomi da db.t4g.micro
a al più grande db.r5.24xlarge
. Il prezzo dipende dalle dimensioni, il piano gratuito permette 750 ore di un server db.t2.micro
con qualunque DBMBS (MySQL, MariaDB, PostgreSQL, Oracle BYOL o SQL Server). Mentre i prezzi possono andare da 0,016 dollari a 15 dollari all'ora. Inoltre il costo dipende anche dalla dimensione dei dati, il piano gratuito preve 20 Gb di dati, oltre questo limite il costo è di 0,115 dollari per GB al mese e i Backup hanno un costo di 0,010 dollari ogni Gb sempre con 20 Gb previsti dal piano gratuito.
DynamoDB è la base dati NoSql proprietaria di Amazon creata proprio per un servizio ad alta affidabilità e ad alte prestazioni, progettato per lavorare con qualunque tipo di applicazione. Offre anche un sistema di sicurezza integrata e backup continui con distribuzione su aree geografiche diverse, infatti è studiato per creare anche sistemi multi-zona con un master e più repliche in sola lettura. Il piano gratuito di AWS prevede 25Gb di spazio di archiviazione, il costo base invece è 0,25 dollari per GB al mese.
Il sotto-servizio di DynamoDB Streams permette di elaborare e inviare grandi quantità di dati tra servizi DynamoDb, il piano gratuito prevede 2,5 milioni di richieste al mese. Il sotto-servizio di Elastricache è un servizio di Cache dei DataStore, pensato per velocizzare i sistemi, risolta essere molto costoso.
Redshift è il servizio di data-warehouse su cloud che utilizza SQL per analizzare i dati che vengono strutturati e poi semi-strutturati su un data-lake operativo. I dati risultano disponibili per l'analisi con QuickSight e applicazioni di terze parti. Il piano gratuito prevede 750 ore di un server dc.2large per soli 2 mesi. Successivamente il costo dipende dalla quantità di dati e dalla necesittà di calcolo, può risultare molto costoso.
Cognito è il servizio di identity-server per le applicazioni, con la possibilità di creare piccoli servizi di autenticazione e autorizzazione con Lambda. Il piano gratuito prevede 50.000 utenti, oltre i quali il servizio è a pagamento.
Il servizio Dynamo è la base dati NoSQL nativa di AWS in quanto è un DBMS sviluppato e mantenuto solo da AWS, il servizio è studiato proprio per l'infrastuttura cloud ed è ottimamente collegato a tutti gli altri servizi, la conoscenza e le basi sono indispensabili per un uso del pacchetto completo. La caratteristica principale è che, non solo è NoSQL come tanti altri DBMS simili, ma è anche SchemaLess quindi non necessita di nessuna definizione di schema ma al momento della creazione di una tabella (o document) c'è la necessità di indicare solo la chiave primaria ed eventuale una chiave secondaria come chiave di ricerca o indice secondario (se si vuole fare una similitudine con i linguaggi SQL).
La creazione da console è veloce, dopo aver selezionato la zona di appartenenza, la procedura guidata di creazione richiede solo il nome, la chiave primaria (chiamata di partizione) e la chiave di ordinamento facoltativa. Esistono anche delle impostazioni personalizzate necessarie in caso di scrittura/lettura non frequente o necessità di capacità di dati molto elevate. Una volta creata la cartella compare nell'elenco delle tabelle con i dati inseriti (nome, stato, chiave, indice), nel dettaglio si possono vedere delle proprietà ulteriori come la procedura di backup, le impostazioni di crittografica e l'esportazione tramite flussi.
Nelle informazioni generali è disponibile anche il codice ARN nella informazioni aggiuntive, per esempio che di solito è nel formato
arn:aws:dynamodb:eu-west-1:<AccountNumber>:table/<TableName>
Per vedere gli elementi all'interno della tabella è disponibile una nuova funzionalità richiamabile tramite il bottone "Esplorare gli elementi della tabella", in questa pagina è possibile eseguire scansioni (non parliamo di query visto che si tratta di una base dati NoSQL). Sempre all'interno di questa pagina è possibile creare voci (record) della tabella con il bottone crea voce che permette di creare manualmente una voce in maniera veloce grazie ad una interfaccia grafica oppure tramite l'inserimento di un json, in questo ultimo caso i valori devono essere "tipizzati", per esempio:
{
"id": { "S": "1" },
"cognome": { "S": "Nao" },
"nome": { "S": "Alberto" }
}
dove il valore S indica a Dynamo che si tratta di un valore di tipo stringa, gli altri valori sono disponibili nella documentazione ufficiale. Per l'acceso ai dati da applicazioni o altri servizi AWS si rimanda agli articoli specifici di ogni sottoservizio.
Il piano gratuito prevede 25 GB di archiviazione e fino a 200 milioni di richieste di lettura/scrittura al mese
, oltre questo libero si applica una tariffa in base alla dimensioni della base dati e al numero di richieste di scrittura e lettura eseguire in base ad una tabella disponibile nella documentazione ufficiale.
DynamoDB è il servizio di database nosql e schemaless di AWS, disponibile solo in questo cloud e non è possibile usarlo in locale o in altri fornitori di Cloud-system. Nella console è possibile creare tabelle e configurare tutta la base dati, in fase di progettazione bisogna sempre ricordare che questo tipo di servizio è senza schema (schema-less) e senza necessità di configurare i server (server-less). Nella vista Table è possibile vedere le tabelle e crearne di nuove, in fase di definizione di una nuova tabella bisogna inserire:
- nome della tabella
- partition key: il nome e il tipo del capo della chiave primaria della tabella, unico campo obbligatorio
- sort key: il nome e il tipo del campo usato per l'ordinamento
- il tipo: default o IA (infrequent access)
Nel dettaglio di una tabella si vedono le impostazioni di creazione, gli indici, gli strumenti per il monitoraggio, gli strumenti di backup e esportazione. Lo strumento "Get item count" permette di avere il numero di item (record) all'interno della tabella. Il bottone "Explore items" permette di eseguire scan e "query" nella tabella per vedere i dati contenuti, trattandosi di base dati noSQL non è possibile usare il linguaggio SQL ma bisogna eseguire ricerche puntuali usando filtri specifici (al posto delle where condition di SQL). Con il servizio CloudFormation è possibiile creare e gestire base dati Dynamo, per esempio:
ES12Dynamo:
Type: AWS::DynamoDB::Table
Properties:
TableName: DynamoTableName
AttributeDefinitions:
-
AttributeName: "id"
AttributeType: "S"
KeySchema:
-
AttributeName: "id"
KeyType: "HASH"
ProvisionedThroughput:
ReadCapacityUnits: "5"
WriteCapacityUnits: "5"
Da notare che nell'esempio sono stati definiti i campi disponibile nella console: il nome, la chiave e il keyschema dove è necessario indicare la chiave primaria e la chiave di ordinamento ma non tutti gli altri "campi" della base dati.
Un esempio completo e funzionante di una tabella Dynamo con API Rest create con Lambda e API-Gateway è disponibile nel GIT:
https://github.com/alnao/AWSCloudFormationExamples/tree/master/Esempio12dynamoApiCrud
Il servizio SNS è studiato per creare delle semplici notifiche di messaggi per gestire comunicazioni tra applicazioni ed eventualmente persone fisiche attraverso un protocollo specifico interno ad AWS. E' usato per fornire un servizio di invio messaggi veloce, asincrono e integrato con tutti gli altri servizi AWS in modo tale da avere uno o più scrittori e uno o più destinatari. I destinatari infatti possono essere servizi AWS (come Lambda, SQS, endpoint http) oppure anche messaggi mail, messaggi SMS o notifiche push verso dispositivi mobili tramite un sottoservizio specifico dedicato al mobile disponibile nella console AWS.
Da console è possibile definire dei topic che possono essere di tipo FIFO (che mantiene l'ordine dei messaggi) oppure Standard (con maggiori performance a discapito dell'ordine), in fase di creazione è possibile anche definire regole di entryption, regole di accesso avanzate e log specifici. All'interno di ogni topic è possibile creare dei subscription cioè dei destinatari delle notifiche, che possono essere mail nel caso più semplice o servizi AWS specifici. Una volta creato il topic è possibile inserire un messaggio da console tramite il bottone "Publish message to topic" con la possibilità di inserire un titolo e un corpo del messaggio con anche un TTL (Time To Live) per impostare un timeout se eventualmente il sistema non riesca ad evadere il messaggio. Il messaggio risultante inviato da console sarà del tipo
{
"Type" : "Notification",
"MessageId" : "518a0bab-439e-5678-bcee-XXXXXXX",
"TopicArn" : "arn:aws:sns:eu-west-1:XXXXXXXXXXXX:nometopic",
"Subject" : "prova alberto",
"Message" : "Prova di Alberto di mandare un SNS tramite console",
...
}
E' possibile inviare notifiche al servizio SNS tramite AWS-CLI con il comando
$ aws sns publish
si rimanda all'articolo dedicato per maggiori dettagli riguardo a questo caso d'uso. Il servizio SNS è stato studiato per permettere ai servizi AWS di scrivere messaggi scatenati da eventi e gestiti tramite Lambda o servizi simili, si rimanda all'articolo dedicato alle Lambda su SNS. Questo servizio NON deve essere scambiato e confuso con il SQS, la differenza è sottile ma importante: SNS è un servizio di messaggistica (notifiche) mentre SQS è un servizio di coda (queue) per la gestione di oggetti.
Attraverso la console AWS-CLI è possibile gestire velocemente il servizio SNS, questo articolo vuole essere un esempio semplice ma completo di come è possibile usare la AWS-CLI per gestire un servizio AWS in maniera completa, il requisito ovvio è che sia configurato un profilo in AWC-CLI come descritto in questo articolo. Il comando base per creare un top SNS è
$ aws sns create-topic --name my-topic
e il comando ritorna il codice arn del topic appena creato. L'elenco di tutti i topic è disponibile con il comando
$ aws sns list-topics
Per sottoscrivere una mail ad un topic è possibile lanciare il comando
$ aws sns subscribe --topic-arn <arn:aws:sns:...> --protocol email --notification-endpoint alnao@alnao.it
Per pubblicare un messaggio in un topic si può usare il comando
$ aws sns publish --topic-arn <arn:aws:sns:...> --subject "Prova Alberto 2" --message "Hello World!"
Per cancellare la sottoscrizione si deve usare l'arn della sottoscrizione
$ aws sns unsubscribe --subscription-arn <arn:aws:sns:...>
Mentre per cancellare una topic si usa il comando
$ aws sns delete-topic --topic-arn <arn:aws:sns:...>
Una guida completa dei comandi e delle API di SNS è disponibile nel sito ufficiale e la guida completa della CLI è sempre disponibile nella documentazione di cli-services-sns.
La sigla RDS significa Relational Database Service ed è uno dei servizi più famosi di AWS, permette infatti di creare base di dati relazionali senza dover gestire il server ma solamente il servizio DBMS, questa configurazione permette di isolare e scalare il servizio senza doversi preoccupare del server fisico dove è in esecuzione il servizio.
I DBMS supportati sono MySql/MariaDB, PostgresSql, Orable e Ms Sql Server, inoltre è disponibile anche un DBMS proprietario di AWS chiamato Aurora che è compatibile con MySql o PostgresSQL. Oltre al DBMS, per usare il servizio, è necessario scegliere la grandezza dell'istanza, le sigle sono simili alle sigle usate per definire il tipo di istante EC2 ed ogni sigla identifica le caratteristiche specifiche
Un esempio pratico di configurazione è la classica istanza db.t3.micro che mette a disposizione 2 vCPUs con 1 Gb di RAM e una velocità di rete media mentre una istanza db.t3.2xlarge ha 8 vCPUs con 32 Gb di ram con prestazioni di rete molto elevate.
Il costo del servizio di ogni istanza dipende dalla sua grandezza, dallo storage (prezzi che partono da 0.133 dollari per ogni GB al mese) e di backup/snapshot eseguiti. Il servizio inoltre permette le repliche real-time per l'alta affidabilità e la scalabilità orizzontale.
Aurora è il tipo di DBMS proprietario di Amazon AWS e in particolare è pensato per essere il servizio di database migliore al mondo sia per i piccoli progetti sia per i progetti di dimensioni grandi. Come il servizio RDS è pensato per essere serverless e ottimizzato per il cloud AWS e tutti i suoi servizi, è compatibile con MySql e Postegres ma non è possibile avviare in modalità compatibilità con entrambi. Da console, si può usare la procedura guidata per la creazione di un database dal servizio RDS, selezionando il tipo Aurora e poi inserendo i parametri:
- la modalità di compabilità con MySql o PostgreSql quindi può essere usato come base dati su applicazioni che già usano questi due tipi di DBMS.
- il nome della base dati che poi sarà visualizzato in console e nelle proprietà della base dati
- le credenziali dell'amministratore principale che poi potrà gestire la base dati, è fondamentale non perderle e non diffonderle
- il tipo di istanza scegliendo tra i dipi di server RDS, come per le istanze EC2 e tutti i database RDS, anche in questo caso c'è la possibilità di scegliere tra una lista di diverse configurazioni
- il tipo di replica se si vuole creare una architettura con backup istantaneo per aumentare la sicurezza e la resilienza del servizio in caso di disastro
- la configurazione della connettività: come ogni altra risorsa AWS questa necessita di posizionarsi all'interno di una VPC e di avere le regole di rete configurate tramite un security group specifico
- è possibile scegliere il tipo di autenticazione tra utente semplice del database oppure una specifica regola IAM
- la attivazione facoltatica del monitoring del database per tenere sotto controllo lo stato del serivzio
La connettività è come un normale RDS quindi prevede una stringa di connessione e credenziali. Per collegarsi bisogna sempre ricordarsi di tenere presenti le regole di rete impostate in fase di creazione ma è sempre possibile modificare le regole del security group per gestire le regole di ingresso al database.
Il servizio servless di coda gestita in AWS si chiama SQS e non è da confondere con il servizio SNS: nel primo caso si tratta di coda (Queue) di oggetti mentre il secondo è un servizio di notifiche (Notification) che può essere anche usato come coda di testi ma non di oggetti, inoltre il servizio di coda permette di avere un tempo di ritenzione/conservazione degli oggetti finché un consumatore non vi accede. Dalla console, nella procedura guidata di creazione bisogna inserire le proprietà base
- nome della coda: visibile in console web e negli altri servizi (come le Lambda Function)
- i tempi di timeout e retention period: è possibile impostare un tempo di ritenzione degli oggetti, cioè il tempo massimo di conservazione nella coda, al termine del quale gli oggetti non consumati vengono eliminati
- la grandezza massima di un oggetto: di default è 256Kb ma può essere variata
- la chiave di criptazione degli oggetti: se necessario un sistema di cifratura per gli oggetti quando scritti nella cosa
- la politica di accesso IAM: si può selezionare tra quella basic o evoluta con un json, in ogni caso gestisce chi può scrivere e chi può consumare gli oggetti
Per la manutenzione da console web è possibile usare le funzionalità di "purge" e "send and retrive" per gestire manualmente gli oggetti nella cosa e nella console è disponibile anche la possibilità di consultare quanti e quali oggetti sono in coda consumandoli. E' possibile anche gestire la sottoscrizione da SQS ad SNS in modo da generare una notifica quando un elemento viene inserito in una coda.
Ad occhi poco esperti, questo servizio potrebbe sembrare inutile ma, per chi sviluppa, risulta essere quasi indispensabile e necessario in caso di servizi asincroni, caso d'uso principale per questo servizio.
Un esempio completo di template CloudFormation con la definizione di una coda SQS e due semplici lambda per scrivere e consumare gli oggetti, può essere trovato al solito repository:
https://github.com/alnao/AWSCloudFormationExamples/tree/master/Esempio21sqs
Il servizio SQS prevede la possibilità di scrivere o leggere da una coda MQ. Per poter lavorare tra lambda e qualsiasi altro servizio bisogna sempre ricordare di configurare i permessi, in questo caso ogni lambda ha bisogno della regola IAM per accedere, scrivere e/o leggere nella coda SQS. All'interno di una funzione lambda scritta in linguaggio Python è possibile usare il solito client boto3
:
sqs = boto3.client('sqs')
E recuperare url della coda con il comando
response = sqs.get_queue_url(
QueueName='nome-queue',
QueueOwnerAWSAccountId='XXXXXXXXXXX'
)
QueueUrl=response['QueueUrl']
Per inviare il messaggio si usa il metodo send_message:
response = sqs.send_message(
QueueUrl=QueueUrl,
DelaySeconds=10,
MessageBody=(
json.dumps( oggetto )
)
)
Per ricevere un messaggio si usa il metodo receive_message:
response = sqs.receive_message(
QueueUrl=QueueUrl,
AttributeNames=['SentTimestamp'],
MaxNumberOfMessages=1,
MessageAttributeNames=['All'],
VisibilityTimeout=0,
WaitTimeSeconds=0
)
message = response['Messages'][0]
receipt_handle = message['ReceiptHandle']
body = message['Body']
è possibile recuperare anche più messaggi dalla coda "MaxNumberOfMessages".
Da notare che dopo averlo ricevuto è possibile cancellarlo dalla coda o lasciarlo, se si vuole pulire l'oggetto si deve usare il delete_message:
sqs.delete_message(
QueueUrl=QueueUrl,
ReceiptHandle=receipt_handle
)
Il codice di esempio di queste lambda può essere trovato sul solito repository:
https://github.com/alnao/AwsLambdaExamples/tree/master/py-example6-sqs-get
https://github.com/alnao/AwsLambdaExamples/tree/master/py-example6-sqs-post
Il servizio SQS mette a disposizione alcune configurazioni molto utili che possono essere usate per gestire al meglio una coda e le regole di lettura dei messaggi da parte dei consumer.
Le regole di "access policy" permettono di definire in un documento json le regole di lettura e scrittura della coda da parte di altri servizi, i due casi d'uso più frequenti sono l'uso di una struttura multi-account dove il producer è in un account diverso da quello dalla coda e deve essere autorizzato con una specifica regola "Sqs:ReceiveMessage"; il secondo caso è la generazione dei messaggi da un bucket S3 (per esempio al carico di un file), in questo caso deve essere indicata la regola "sqs:SendMessage" nella regola.
La configurazione di "visibility timeout" permette di evitare che due consumer non leggano lo stesso messaggio, infatti una volta letto un messaggio da un consumer, questo non sarà più disponibile per gli altri per un arco di tempo prefissato, di default è impostato a 30 secondi ma può essere modificato, questo valore può essere variato a livello di coda ma anche a livello di singolo messaggio, caso d'uso possibile nel caso di un elemento che richieda molto tempo per l'esecuzione, allora il consumer può chiedere alla coda di aumentare quel valore, tale configurazione può essere provata anche da browser in console usando due tab dello stesso browser.
La "dead letter queue" (DLQ) è una coda di parcheggio dove vengono posizionati i messaggi che sono stati letti un numero prefissato di volte ma mai cancellati, questa coda è di fatto una SQS normale con la particolarità che può essere configurata diversamente e con un bottone "redrive" che permette di riportare dal parcheggio alla coda originale i messaggi, il caso d'uso di più frequente di questo sistema è il debug di messaggi che non vengono elaborati per errori o anomalie del codice.
Il "delay queue" è il tempo che passa dalla scrittura del messaggio a quando questo viene inviato ad un consumer, di default è 0 secondi ma può essere impostato un valore di default diverso a livello di coda ma anche a livello di singolo messaggio quando viene inviato nella coda SQS.
Con la configurazione del "long polling", se la coda è vuota, la API usata dai consumer aspetterà un numero di secondi prefissato prima di rispondere in attesa che arrivino messaggi, questo viene usato per diminuire il numero di API chiamate ed aumentare l'efficienza dell'architettura; il parametro usato è il "ReceiceMessageWaitTimeSeconds" e può essere impostato a livello di coda ma anche a livello di chiamata API, il valore massimo è 20 secondi di attesa e anche questo parametro può essere provato in console.
Di default SQS non garantisce il FIFO nativamente, se impostato SQS limita la coda a 300 messaggi al secondo in ingresso (3000 nel caso di Batch) ma con la proprietà di eliminazione dei duplicati in un limite di tempo prefissato (di default 5 secondi).
Cloud Formation è il servizio di distribuzione della modellazione e del provisioning delle componenti di una infrastruttura. Permette l'automazione dei rilasci e delle risorse di una organizzazione con il controllo della governance. La vera potenza del servizio è la creazione di pipeline per l'esecuzione di test e la produzione di stack di risorse. Non prevede costi aggiuntivi fino a 1000 operazioni al mese di gestione.
Code Commit è il gestore di repository di AWS, compatibile con GIT presenta la possibilità di creare deploy e compilazioni interne al sistema AWS riducendo di molto la necessità di tool esterni. Il servizio prevede 5 utenti gratuiti con un numero di commit e get limitata, oltre questo limite il servizio è a pagamento (e anche molto costoso).
Code Pipeline e Code Deploy sono due servizi per la gestione di rilasci di codice presente su CodeCommit o su bucket S3 verso istanze EC2 o server locali. Il servizio permette la configurazione di una linea di distribuzione continua che chi scrive questo articolo crede sia sacro graal. Il servizio prevede un numero limitato di rilasci, con una pipeline attiva nel piano gratuito, oltre la prima il costo è di 1 dollaro per ogni pipeline attiva al mese.
Esiste un Tool gratuito per accedere e gestire i servizi AWS installabile nel programma Visual Studio Code. Tale tool è ufficiale e si può considerare sicuro visto che da un po' è supportato ufficialmente da AWS. Per usare il tool bisogna aver installata e configurata la AWS CLI con un profilo attivo e funzionante. La sua installazione è molto semplice: basta infatti andare sulle estensioni di VSCode e cercare "AWS Toolkit", così si potrà installare velocemente e facilmente il tool in pochi secondi.
Se il plugin viene installato correttamente comparirà nella barra laterale di sinistra il bottone per accedere ad AWS con la classica icona del marchio. Per configurare il profilo di accesso basta visualizzare la barra dei comandi (con CTRL+SHIFT+P) e bisogna selezionare "AWS Choose profiles", in questo modo il programma propone la lista dei profili configurati e di quale è attivo in quel istante su VSCode.
Una volta configurato il profilo dalla vista explorer si vedono i servizi e i componenti attivi per una determinata region, è possibile aggiungere una region alla vista dalla barra dei comandi selezionando "Show region in explorer" oppure selezionando la voce nella vista nel bottone con i tre punti. Il Tool base non prevede moltissime funzionalità e potrebbe sembrare un tool inutile ma alcuni aspetti sono molto potenti e veramente utili.
La gestione degli script CloudFormation è l'esempio di utilizzo di questo tool visto che è possibile vedere tutti gli stack con la possibilità di installarne di nuovi e rimuoverne dal Cloud grazie alla barra dei comandi dove si può vedere l'elenco dei comandi disponibili inserendo genericamente AWS. L'uso del tool è totalmente gratuito ma bisogna sempre ricordarsi che sono le risorse usate come la potenza di calcolo delle lambda create con CloudFormation quindi bisogna sempre ricordarsi di prestare attenzione a cosa viene eseguito.
Una delle funzionalità principali di AWS Toolit su MS Visual Studio Code è la creazione di state machine, accedendo nella vista del plugin si possono vedere tutte le AZ (Avaibility zone) e tutti i servizi attivi in quella zona, nello specifico selezionando "Step functions" si vedono tutte le state machine disponibili. Con la combinazione di tasti Ctrl + Shift + P si apre la console testuale con cui si possono chiamare i comandi del plugin precedendoli sempre con dal prefisso "AWS:
".
Per creare una nuova macchina a stati si può usare il comando "AWS: Create a new Step function state machine
", la procedura di creazione chiede all'utente di inserire il tipo (come HelloWorld) e il formato tra json e yaml. La procedura guidata crea un file json (o YAML) che deve essere salvato per poter procedere con i successivi passi. Per aprire il plugin grafico bisogna premere la combinazione di tasti e selezionare la voce "AWS: Render state machine
", per ora non è disponibile una voce di menu cliccabile da cui aprire il tool grafico!
Per il rilascio bisogna usare il comando "AWS: Publish state machine to Step functions
" e la procedura guidata richiede alcune informazioni:
- la region di installazione della state machine, di default viene proposta quella dell'utente configurato su AWS-CLI
- se è una nuova installazione o un aggiornamento di una state machine esistente
- la regola IAM di esecuzione che deve essere precedentemente creata
- il nome da assegnare
Una volta creata può essere visualizzata nella console e nel plugin di Code. Per eseguire la macchina a stati si può usare la console oppure dal plugin selezionando la state machine desiderata basta cliccare con il tasto destro e usare la voce "start execution
" a cui sarà possibile inviare un file json come parametri di input dell'esecuzione. L'aggiornamento della step function da code prevede gli stessi passi della creazione con la sola differenza che si seleziona l'aggiornamento al secondo passo della procedura di aggiornamento.
CDK è un kit per sviluppare componenti nel cloud, un framework open source con il quale è possibile definire risorse e applicazioni nel cloud tramite linguaggi di programmazione. Il kit è basato su CloudFormation e sfrutta la AWS-CLI per eseguire i rilasci in ambiente target, può essere programmato con i principali linguaggi di programmazione: JavaScript, TypeScript, Python, Java, C# e Go. L'utilizzo di AWS CDK non comporta costi supplementari al di fuori di tutte le risorse create con i template. Per installare il kit CDK basta installare AWS-CLI e npm, successivamente bisogna installare il kit con
npm install -g aws-cdk
La prima esecuzione del kit bisogna lanciare il comando
cdk bootstrap
Che andrà a creare all'interno dell'infrastruttura cloud un template CloudFormation e un bucket S3, questi saranno usati come base di appoggio per tutti i template sviluppati e rilasciati con questo KIT. Il comando cdk destroy non cancella questi due elementi che non devono mai essere modificati a mano. Per creare un progetto da zero si può usare la procedura guidata eseguibile con il comando
cdk init sample-app --language=java
All'interno del progetto vengono creati un file cdk.json con la descrizione dei componenti dei template e due classi java importanti, in una c'è la dichiarazione del template mentre nella seconda i componenti del template stesso. Per preparare il template al rilascio si deve usare il comando
cdk synth
Mentre il comando per rilasciare un template è:
cdk deploy
Il comando per confrontare la versione locale con quello già rilasciato su AWS
cdk diff
L'elenco dei template presenti è recuperabile con il comando
cdk ls
Mentre per rimuovere un template si può usare il comando
cdk destroy
Da notare che per ogni template rilasciato con CDK sarà creato un template su CloudFormation ed è possibile sempre monitorare lo stato e i sotto-componenti nello stesso template ma è sconsigliato l'uso della console per modifiche puntuali: un template creato con CDK non deve mai essere modificato manualmente.
Semplici esempi di codice possono essere trovati nel git ufficiale:
https://github.com/aws-samples/aws-cdk-examples/tree/master/java
CloudShell è un piccolo servizio che permette di eseguire una shell GNU Linux all'interno del browser web, il servizio è disponibile in tutte le versioni della console web con un icona nella barra superiore, tra la barra di ricerca e il simbolo della campanella degli avvisi. In questa shell sono installati di default tutti i principali tool di gestione come AWS CLI, AWS SAM, AWS SDK, GIT, Npm e Pip.
Questa istanza è creata virtualmente con un 1Gb di spazio libero dove l'utente può caricare e scaricare file dal browser, la home directory è persistente anche dopo stop e ripristino ma lo storage non è sincronizzato tra le varie regioni di AWS. Un grosso limite di questo servizio è che, se una istanza o un oggetto si trova all'interno di una VPC privata, non è possibile collegarsi tramite ClousShell in quanto è un servizio globale al di fuori di qualsiasi rete privata. Pensando a questo servizio non è da confondere con il Connect-EC2 disponibile nella console web di AWS che ha una funzionalità completamente diversa.
Per l'uso di questo servizio non è previsto nessun requisito e non è necessario che sia eseguita una EC2 o altre risorse. Inoltre non prevede nessun costo aggiuntivo. Tale servizio non può essere usato per avviare demoni o server in quanto le risorse a disposizione sono limitate e la shell si spegne in automatico dopo un periodo di inattività della tastiera.
Trattandosi di una istanza GNU Linux con AMI di AWS, è posisible usare yum o apt per installare software, per esempio:
$ sudo yum install -y bind-utils
$ nslookup www.google.it
$ dig www.google.it
Una guida ufficiale al servizio è disponibile nel sito ufficiale.
E' stato sviluppato un bellissimo plugin per il programma Eclipse che permette di gestire una infrastruttura AWS e sviluppare componenti per l'ambiente Cloud. L'installazione del plugin è molto semplice e basta aggiungere nelle sorgenti del software nella voce di menù "Install New Software":
https://aws.amazon.com/eclipse
e successivamente all'installazione compare una nuova prospettiva "AWS". Se sono configurati AWS-CLI e i profili sarà possibile usare il plugin per gestire i servizi in cloud direttamente dal programma.
Attivata la prospettiva sarà disponibile la vista "AWS Explorer", prima di usarla bisogna sempre ricordarsi di configurare la zona (AZ) e il profilo (AWS-Cli) questi due sono configurabili nella testata della vista dove c'è la bandiera della zona e una icona con tre pallini con la voce "AWS Account", sottolineo che bisogna sempre prestare attenzione perché può risultare e scomodo cambiare profilo visto che non compare in nessun altro punto della schermata di Eclipse.
Nella vista sono elencati i principali servizi e sotto-servizi disponibili. Cliccando su un servizio compare una ulteriore vista dove è possibile gestire i componenti installati di quel servizio, per esempio cliccando su "Instances" nel menù "Amazon EC2" è possibile vedere l'elenco delle istanze e cliccando su una istanza è persino possibile riavviare, stoppare e gestire tutte le istanze. I vari servizi disponibili che trovo molto utili sono: S3 dove è possibile vedere gli elementi in un bucket, Lambda dove è possibile vedere le funzioni e i rispettivi log, CloudFormation dove è possibile vedere tutti i template con i rispettivi parametri e configurazioni.
Alcune funzionalità possono andare in errore a causa della versione di JAXBException perché il plugin necessità la versione 8 di Java o la libreria caricata in Eclipse.
Grazie al servizio di AWS chiamato SSM Parameter Store è possibile definire alcuni parametri dalla console di AWS e successivamente recuperare i valori da un template CloudFormation, questa tecnica può essere usata per salvare parametri diversi a seconda degli ambienti, per esempio diversificare i valori tra account di test e di produzione. L'uso di questo servizio è molto usato anche per salvare password e chiavi private, salvando i valori nel servizio SSM è possibile evitare di salvare dati sensibili come le password all'interno dei parametri di un template CloudFormation.
Il servizio è gratuito e maggiori dettagli possono essere trovati nel sito ufficiale. E' possibile creare un parametro da console oppure anche grazie alla AWS-CLI, per esempio:
aws ssm put-parameter --name "/dev/ec2/instenceType" --type "String" --value "t2.micro"
Grazie a questo servizio è possibile recuperare alcune variabili standard di AWS messe a disposizione proprio per facilitare la vita al programmatore che deve scrivere un template. Per esempio l'ultima versione AMI di una EC2 Linux è recuperabile con la variabile:
/aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-x86_64-gp2
E' possibile recuperare i valori di questi parametri standard e visualizzarli grazie alla AWS-CLI, per esempio il comando:
aws ssm get-parameters --names /aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-x86_64-gp2
recupera il valore più recente della AMI con sistema operativo GNU Linux per istanze EC2, valore poi utilizzabile su un template CloudFormation per creare istanze aggiornate in automatico. L'elenco completo di tutti i parametri standard AWS è disponibile nel solito sito ufficiale.
Amplify è un servizio di AWS molto specifico in quanto permette di costruire e distribuire applicazioni web e backend, con la possilità quindi di creare un ambiente FullStack molto performante e elastico.
Gli strumenti messi a disposizione sono:
- Amplify Studio: un ambiente intuitivo per lo sviluppo di applicazioni di qualsiasi tipo (front-end, back-end e full-stack).
- Amplify CLI: un tool con il quale è poossibile controllare il servizio con pochi comandi
- Librerie client open-source: sono delle librerie gratuite studiate proprio per ottimizzare le applicazioni che vengono eseguite con questo servizio
- Design system: componenti legati al cloud per lo sviluppo
- Hosting web: sistema di distribuzione continua e hosting gestito in Cloud per i siti statici e per le applicazioni back-end.
I framework e i linguaggi supportati sono i più comuni: angular, React, Vue, Java, Javascript, Go e tanti altri con la possibilità di trovare tantissime comunità in internet che già usano questo servizio. L'uso più semplice di questo servizio è di ospitare un sito web costruito con la tecnica del signle-page in Angular o Reeact basato sul gestore NPM. Per creare un ambiente basta usare CloudCommit come repository oppure un altro repository Git compatibile.
Nella procedura guidata di creazione di un ambiente bisogna selezionare il repository ed eventualmente la sottocartella, la regola IAM necessaria per regolare l'accesso al repository può essere creata nella procedura guidata e la console non ha bisogno di altre informazioni. Di default è attiva la configurazione di integrazione e distribuzione continua (CI/CD) ma è possibile disattivare questa opzione e configurare la modalità di integrazione e distribuzione tramite tag o altre proprietà del repository.
Sempre tramite la console è possibile configurare un dominio e il relativo certificato per la creazione di regole DNS specifiche in quanto di default l'app viene esposta con un url simile a:
<nome>.<codice>.amplifyapp.com
Il servizio mette anche a disposizione la possibilità di configurare notifiche (SNS) collegata alla CI/CD, regole di rete e redirect. Inoltre è possibile monitorare il traffico e l'uso del hosting. Le prime quattro componenti sono gratuite mentre l'hosting è a pagamento secondo una tabella a consumo dove sono calcolati i costi di compilazione e quelli di distribuzione a cui devono sommare i costi per l'uso dell'hosting. Maggior dettagli sull'uso di questo servizio sono disponibili nella documentazione ufficiale.
Nell'esempio di default di creazione di una Lambda Application viene creata in automatico una struttura PipeLine con CloudCommit in modo che ad ogni Push corrisponda una compilazione e un rilascio del codice delle lambda e anche del template YAML di CloudFormation. Per usare il servizio CloudCommit bisogna eseguire la clone con il comandi GIT usando con il comando:
git clone https://<username>:<password>@git-codecommit.<region>.amazonaws.com/v1/repos/<nome-repository>
dove le credenziali username e password sono create nel servizio IAM nella seziona apposita dedicata a CloudCommit, per la creazione delle credenziali si può seguire la guida ufficiale. Una volta eseguito il comando di clone sarà possibile lavorarci come un normale repository GIT, per eseguire il rilascio è possibile modificare le lambda e il template direttamente da console oppure eseguire il commit e il comando push di GIT. Alla PUSH nel branch principale il servizio PipeLine eseguirà la compilazione e il deploy nell'ambiente target di tutto il codice, nell'esempio il codice Lamdba e il template CloudFormation.
Per esempio aggiungendo il campo surname nel file put-item.js del progetto del articolo "Lambda Application", sarà possibile salvare e leggere il nuovo campo che prima non era presente nel tracciato della tabella. All'interno della console di AWS CodePipeline è possibile vedere si possono vedere lo stato della PipeLine e le informazioni addizionali con tutti i passi di compilazione e del deploy con il dettaglio di tutte le risorse coinvolte come Lambda, CloudFormation, EC2, ecc...
Nella cronologia della singola PipeLine si può notare la storia di tutti i rilasci con lo stato e la descrizione del commit GIT che ha scatenato l'esecuzione del deploy, per ogni rilascio è possibile cliccare su link che rimanda al servizio CloudCommit e si possono vedere le modifiche rilasciate da quel deploy nel formato "diff".
CloudFormation è uno dei servizi più complessi di AWS ma allo stesso tempo è uno dei più potenti: permette di creare risorse da un semplice file in formato json o yaml, questo file viene chiamato template. In tutti gli esempi esposti in questi articoli verrà usato il formato yaml che di solito viene preferito al json, anche grazie ai numerosi tool presenti su internet per la conversione dei formati. Il servizio è totalmente gratuito ma ovviamente saranno a pagamento tutte le risorse create con i file, per esempio eseguire un template per l'avvio di un server EC2, vedrà il costo solo dell'istanza stessa e non del template.
All'interno della console di AWS è possibile accedere al servizio CloudFormation, dove è disponibile la lista degli stack, all'interno del quale si vedono le varie versioni del template caricato come se fosse una forma di "repository". Grazie alla descrizione degli stack è possibile sapere se lo stack è stato eseguito correttamente, aggiornato o se presenta errori di qualche tipo. Nel dettaglio di ogni stack sono disponibili gli eventi nel tab dedicato dove si possono vedere tutti i passi eseguiti e il relativo esito, tipicamente se uno script presenta un errore infatti verrà eseguito il rollback di tutte le risorse descritte nello script.
Per creare un nuovo stack da console è disponile la procedura guidata a step eseguibile con il bottone "Crea stack" e i passi guidati sono:
- Tipo di modello: modello pronto, di esempio o modello in designer , se si dispone del file bisogna selezionare la prima opzione
- Origine del modello: è possibile caricare il modello da un URL S3 oppure caricare un modello dal pc locale, nel caso della seconda opzione comunque il sistema andrà a creare un bucket S3 dove depositare il file e viene visualizzato l'url di destinazione
- Nome interno dello stack che verrà usato per identificarlo nella console
- Elenco dei parametri del modello con l'obbligo di impostare i valori per il modello
- Tab e autorizzazioni dello stack
- Opzione "di fallimento della pila" dove è possibile indicare se, in caso di errore, eseguire rollback dell'esistente o mantenere le modifiche
- Riepilogo e conferma del modello
Una volta creato uno stack da un modello, questo entra nel ciclo di vita in stato "CREATE_IN_PROGRESS", nell'elenco degli eventi è possibile visualizzare tutte le fasi di creazione e configurazione delle risorse definite nel modello.
Molti esempi di template di CloudFront possono essere trovati nel github pubblico
https://github.com/alnao/AWSCloudFormationExamples
E' possibile creare un bucket S3 caricando su CloudFormation uno script di creazione, per esempio un file template.yaml e con il template pronto:
AWSTemplateFormatVersion: 2010-09-09
Description: CloudFormation template for s3 bucket
# nel file yaml bisogna prestare attenzione di inserire due spazi e non tabulazioni.
Resources:
S3Bucket:
DeletionPolicy: Retain
Type: 'AWS::S3::Bucket'
Description: Creating Amazon S3 bucket from CloudFormation
Properties:
BucketName: alberto-prova
AccessControl: Private
PublicAccessBlockConfiguration:
BlockPublicAcls: true
BlockPublicPolicy: true
IgnorePublicAcls: true
RestrictPublicBuckets: true
BucketEncryption:
ServerSideEncryptionConfiguration:
- ServerSideEncryptionByDefault:
SSEAlgorithm: AES256
VersioningConfiguration:
Status: Enabled
Outputs:
S3Bucket:
Description: Bucket Created using this template.
Value: !Ref S3Bucket
In questo esempio completo ci sono tutte le informazioni del bucket: il nome, il tipo di accesso, la attivazione dell'accesso pubblico e le logiche di entrypt. Entrando nella console di AWS nel servizio CloudFormation e creare lo stack, selezionando un template già esistente e caricando il file appena creato, si avvia la creazione automatica tramite script. Una volta lanciato, nella lista degli stack di CloudFormation sarà visibile lo stato della crazione. Una volta ricevuta la conferma di creazione basterà andare sula console di S3 per vedere il bucket appena creato. In questo caso, nel modello è indicato anche un output che viene visualizzato nella console nel dettaglio dello stack all'interno del tab "Output". Per eliminare il bucket e lo stack basta andare sulla console CloudFormation e premere il bottone "Elimina", però bisogna prestare attenzione visto che la cancellazione dello stack provoca anche la cancellazione del contenuto del bucket, quindi tutti i file caricati saranno persi. La documentazione ufficiale e completa dei parametri per CloudFormation e S3.
Con la stessa tecnica è possibile creare un sito statico da CloudFormation con la tecnica di esposizione diretta del bucket S3 senza l'uso di CloudFront, per fare questo bisogna definire una Policy, per esempio:
AWSTemplateFormatVersion: 2010-09-09
Description: CloudFormation template for s3 bucket
Resources:
S3Bucket:
Type: 'AWS::S3::Bucket'
Properties:
AccessControl: PublicRead
PublicAccessBlockConfiguration:
BlockPublicAcls: false
BlockPublicPolicy: false
IgnorePublicAcls: false
RestrictPublicBuckets: false
BucketName: alberto-prova
MetricsConfigurations:
- Id: EntireBucket
WebsiteConfiguration:
IndexDocument: index.html
ErrorDocument: error.html
DeletionPolicy: Retain
S3BucketPolicy:
Type: AWS::S3::BucketPolicy
Properties:
Bucket: 'alberto-prova-4aprile22'
PolicyDocument:
Version: 2012-10-17
Statement:
- Sid: AllowSSLRequestsOnly
Action: 's3:GetObject'
Effect: Allow
Resource:
- 'arn:aws:s3:::alberto-prova/*'
Principal: '*'
Outputs:
WebsiteURL:
Value: !GetAtt
- S3Bucket
- WebsiteURL
Description: URL for website hosted on S3
S3BucketSecureURL:
Value: !Join
- ''
- - 'https://'
- !GetAtt
- S3Bucket
- DomainName
Description: Name of S3 bucket to hold website content
Nella sezione dell'output è possibile visualizzare il url diretto con cui accedere al bucket da web, ovviamente bisogna ricordarsi di posizionare del contenuto all'interno del bucket altrimenti si otterrà un errore 403.
Il caricamento e la gestione dei modelli da console potrebbe essere molto pesante e complesso, soprattutto quando si devono gestire centinaia di moduli e migliaia di componenti. La soluzione è l'uso della CLI di AWS e del comando SAM che è stato studiato per gestire gli script di CloudFormation con la possiblità di gestire anche le versioni e il deploy automatico. Prima di tutto bisogna avere un profilo AWS-CLI attivo e funzionante, per verificarne il funzionamento basta lanciare il comando:
$ aws configure list-profiles
Poi bisogna installare la AWS-CLI-SAM disponibile per tutti i sistemi opearitivi, su windows basta seguire i passi indicati nella guida ufficiale.
Per effettuare una prima prova di funzionamento del comando SAM con un template yaml con il nome "template.yaml
", basta avviare i comandi indicati nella stessa guida ufficiale:
$ sam init
$ sam build
$ sam deploy --stack-name <nameStack> --capabilities CAPABILITY_IAM
e poi si può provare la APi da browser dall'url visualizzato dal precedente comando. Per rimuovere lo stack creato basta lanciare il comando della AWS-CLI (non SAM):
$ sam delete --stack-name <nameStack>
Questo esempio è la base poi per sviluppare funzioni e modelli sempre più complessi, nei prossimi articoli si darà per scontato l'uso di SAM e del build per tutti quegli esempi in Python o in altri linguaggi. Molto spesso i bucket S3 sono usati come cartella di deposito di file che poi devono essere elaborati, per sviluppare questo sistema si può creare un modello con le seguenti risorse:
- Bucket con un nome specifico
- Notifica dal Bucket alla funzione lambda
- Funzione lambda serverless che riceve il file
- Permesso al bucket di invocare la lambda
- Permesso della lamba di accedere ai file nel bucket
Come vedere i permessi sono sempre obbligatori in quanto, di default per ragioni di sicurezza tutti i permessi sono negati e bisogna sempre ricordarsi di abilitare la singola funzionalità. Uno script di esempio è disponibile nel git pubblico:
https://github.com/alnao/AWSCloudFormationExamples/tree/master/Esempio03parameters
In questo script è stato creato un parametro per personalizzare il nome del bucket e poi le risorse sono elencate una dopo l'altra, legati grazie al codice Arn di ogni elemento. La particolarità più interessante di questo esempio è la notifica che viene inviata dal Bucket alla Lambda:
NotificationConfiguration:
LambdaConfigurations:
- Event: s3:ObjectCreated:*
Filter:
S3Key:
Rules:
- Name: suffix
Value: csv
Function: !GetAtt S3NotificationAN7A22A.Arn
da notare che è stato usato il sistema di notifiche di S3 e non gli eventi con CloudEvent come descritto in uno dei prossimi articoli e come dovrebbe essere fatto di default. Per caricare lo script su AWS
$ sam validate
$ sam build
$ sam deploy --stack-name <nameStack> --capabilities CAPABILITY_IAM
Per caricare il file e vedere il comportamento dello stack:
$ aws s3 cp prova.csv s3://<nameBucket>
$ sam logs --stack-name <nameStack>
Per eliminare completamente lo stack:
$ sam delete --stack-name <nameStack>
Lo scopo di questo template è creare una tabella Dynamo con uno script di CloudFormation, ovviamente non rimarrà vuota a lungo ma come primo passo bisogna imparare a creare la tabella nel servizio Dynamo! Uno script semplificato per creare una tabella è:
Parameters:
DynamoName:
Type: String
Description: Nome del DB dynamo
Default: alberto-dynamo-example
Resources:
DynamoAN7A22D:
Type: AWS::DynamoDB::Table
Properties:
TableName: !Ref DynamoName
AttributeDefinitions:
-
AttributeName: "id"
AttributeType: "S"
KeySchema:
-
AttributeName: "id"
KeyType: "HASH"
ProvisionedThroughput:
ReadCapacityUnits: "5"
WriteCapacityUnits: "5"
In questo semplice script abbiamo definito il nome come parametro dello script ma è possibile impostarlo anche come stringa costante. L'elenco degli attributi è da elencare nella lista AttributeDefinitions ma bisogna inserire solo le chiavi primarie e secondarie, gli altri attributi non bisogna indicarli, essendo Dynamo un servizio schemaless è vietato farlo. Sempre all'interno delle proprietà della tabella bisogna definire le chiavi primarie KeySchema con il tipo HASH o RANGE. Poi bisogna sempre impostare i parametri dentro ProvisionedThroughput. Un esempio di definizione di chiave secondaria con GlobalSecondaryIndexes invece è disponibile nella guida ufficiale.
Il modello di questo esempio è molto semplice: creare un bucket S3 e un evento scatenato al caricamento di un file in questo bucket. L'evento prende i file csv e inserisce i dati dentro una tabella DynamoDB.
La particolarità di questo script è che oltre alla creazione di tutti gli elementi va a creare una regola IAM per permettere alla funzione lambda di accedere al bucket e di scrivere i dati su Dynamo, senza queste regole IAM la procedura andrebbe in errore. La policy completa è prevede quattro autorizzazioni
- s3:GetBucketNotification per permettere alla lamba di accedere alle informazioni dell'evento (oggetto event nella lambda)
- dynamodb:BatchWriteItem per permttere la scrittura dati su Dynamo
- s3:GetObject per permettere la lettura del file caricato
- logs:CreateLogGroup per permettere la scrittura dei log su CloudEvents
L'esempio completo è disponibile su GitHub:
https://github.com/alnao/AWSCloudFormationExamples/tree/master/Esempio05s3Csv2Dynamo
Una delle innovazioni maggiori di AWS è stata l'introduzione delle funzionali serverless, cioè porzioni di codice eseguiti senza uno specifico server e il codice viene eseguito da server "condivisi" solo al momento della chiamata con un incredibile risparmio di costi di server. Nei template CloudFormation è possibile definire delle funzioni per eseguire passi o codice specifico, nell'esempio precedente del db Dynamo è presente una funzione che prende i file csv su un bucket e carica i dati nella tabella dynamo. Per questo all'interno del template bisogna definire 3 risorse specifiche:
- AWS::Lambda::Function : definizione del codice della funzione con la possiblità di impostare le regole IAM e passare parametri dal template al codice
- AWS::IAM::Role : definizione delle regole IAM per la funzione, per esempio l'accesso al bucket S3 o la scrittura di log su CloudWatch
- AWS::Lambda::Permission : in caso di trigger su EventBridge bisogna definire il permesso del Trigger di lanciare la lambda
E' possibile definire il codice python all'interno del tepmlate (nel yaml) per esempio
StartLambda:
Type: 'AWS::Lambda::Function'
Properties:
Code:
ZipFile: |
import json
def lambda_handler(event, context):
print("Esecuzione" + json.dumps(event) )
Oppure è possibile e vivamente consigliato utilizzare file python separati posizionati nella stessa cartella del template (o in sottocartelle), in questo caso il template diventa
ExternalPyLambda:
Type: AWS::Serverless::Function
Properties:
CodeUri: lambda
Handler: nome_file.entrypoint
Runtime: python3.8
MemorySize: 512
Timeout: 900
All'interno di questo template sono presenti la proprietà CodeUri che indica il nome del pacakge python e la proprietà Handler che indica il metodo da richiamare. Da notare che il package python deve essere un package a tutti gli effetti con i file standard:
- __init__.py
- requirements.txt
questi file sono indispensabili per la gestione del pacakge con la possiblità di importare librerie esterne. Questo secondo esempio è da considerarsi lo standard, in quanto l'uso del codice lambda in-code nel template è da considerarsi obsoleto. Esempi di codice possono essere trovati nel git:
https://github.com/alnao/AWSCloudFormationExamples/tree/master/Esempio07pyEsterno
Una delle applicazioni più usate di CloudFormation è creare un mini ecosistema composto da : tabella Dynamo come base dati, API rest sviluppate con Lambda e esposte con API Manager di AWS, di fatto l'obbietto è creare un semplice CRUD completo per l'accesso e la modifica dei dati. Questo tipo di infrastruttura può essere realizzata in diversi modi anche all'interno di AWS ma il più semplice e il più pratico è di usare un template CloudFormation per creare ogni componente con semplici template.
I componenti principali sono la tabella dynamo dove sono definiti gli attributi di chiave primaria:
ES12Dynamo:
Type: AWS::DynamoDB::Table
Properties:
TableName: !Ref DynamoName
AttributeDefinitions:
-
AttributeName: "id"
AttributeType: "S"
Il metodo GET dell'api si definisce come API nel Serverless
ES12ApiGateway:
Type: AWS::Serverless::Api
Properties:
StageName: !Ref Stage
OpenApiVersion: 3.0.2
CacheClusterEnabled: false
CacheClusterSize: '0.5'
Cors:
AllowMethods: "'POST, GET'"
AllowOrigin: "'*'"
MaxAge: "'600'"
MethodSettings:
- ResourcePath: /
HttpMethod: GET
CachingEnabled: false
CacheTtlInSeconds: 300
Per definire la funzione lambda in Python per recuperare i dati dal Dynamo ed esporli in una API REST di tipo GET bisogna creare una funzione lambda, in questo esempio python viene usato una inline per semplicità:
ES12ApiGetFunction: # Adds a GET api endpoint
Type: AWS::Serverless::Function
Properties:
Role: !GetAtt ES12APIRole.Arn
Events:
ApiEvent:
Type: Api
Properties:
Path: /
Method: get
RestApiId:
Ref: ES12ApiGateway
Runtime: python3.7
Handler: index.handler
MemorySize: 128
Environment:
Variables:
DynamoName: !Ref DynamoName
InlineCode: |
import boto3
import os
import json
TABLE_NAME = os.environ['DynamoName']
def handler(event, context):
dynamodb = boto3.resource('dynamodb', region_name="eu-west-1")
table = dynamodb.Table(TABLE_NAME)
response = table.scan()
return {'body': json.dumps(response['Items']),'statusCode': 200 }
Per ottenerere l'url delle API create, si può indicare nel template un output dove visualizzare l'informazione richiesta:
UrlGet:
Description: Endpoint URL API REST
Value:!Sub https://${ES12ApiGateway}.execute-api.${AWS::Region}.amazonaws.com/${Stage}
Nell'esempio disponibile su GIT è possibile vedere anche il metodo POST per la modifica dei dati ed è stata aggiunta anche una funzione Lambda per il caricamento da file CSV in modo da rendere l'esempio più completo possibile. L'esempio completo è disponibile su GitHub:
https://github.com/alnao/AWSCloudFormationExamples/tree/master/Esempio12dynamoApiCrud
Per completare il CRUD iniziato nel precedente articolo bisogna aggiungere il metodo di aggiornamento e di cancellazione dei dati nel Dynamo, in questo caso basta aggingere i due metodi alla ApiGateway
ES12ApiGateway:
Type: AWS::Serverless::Api
Properties:
StageName: !Ref Stage
OpenApiVersion: 3.0.2
CacheClusterEnabled: false
CacheClusterSize: '0.5'
Cors:
AllowMethods: "'POST, GET'"
AllowOrigin: "'*'"
MaxAge: "'600'"
MethodSettings:
- ResourcePath: /
HttpMethod: GET
CachingEnabled: false
CacheTtlInSeconds: 300
- ResourcePath: /
HttpMethod: POST
CachingEnabled: false
CacheTtlInSeconds: 300
- ResourcePath: /
HttpMethod: DELETE
CachingEnabled: false
CacheTtlInSeconds: 300
Il metodo di aggiornamento con il metodo POST è un po' più complicato della GET perchè i dati devono essere serializzati secondo una libreria Dynamo disponibile, un esempio semplice è:
import boto3
import os
import json
import datetime
from boto3.dynamodb.types import TypeSerializer, TypeDeserializer
TABLE_NAME = os.environ['DynamoName']
def handler(event, context):
print("Esecuzione" + json.dumps(event) )
post_str = event['body']
post = json.loads(post_str)
current_timestamp = datetime.datetime.now().isoformat()
post['updatedAt'] = current_timestamp
#print("Esecuzione post" + json.dumps(post) )
ts= TypeSerializer()
serialized_post= ts.serialize(post)["M"]
#print("Esecuzione serialized_post" + json.dumps(serialized_post) )
client = boto3.client('dynamodb')
res = client.put_item(TableName=TABLE_NAME,Item=serialized_post)
return {'body': json.dumps(res), 'statusCode': 201}
Da notare che è presente la gestione del cors nell'header di output altrimenti si genererebbe errore in fase di chiamata esterna. Per il metodo di cancellazione è possibile sempre usare la libreria boto3 e il cliente Dynamo con il metodo delete_item al quale bisogna passare la chiave da eliminare, nell'esempio si usa solo il campo id:
import boto3
import os
import json
import datetime
from boto3.dynamodb.types import TypeSerializer, TypeDeserializer
TABLE_NAME = os.environ['DynamoName']
def handler(event, context):
print("Esecuzione" + json.dumps(event) )
post_str = event['body']
post = json.loads(post_str)
idValue = post['id']
client = boto3.client('dynamodb')
res = client.delete_item(TableName=TABLE_NAME,Key={ 'id' : { 'S' : idValue } } )
return {'body': json.dumps(res), 'statusCode': 201}
Per ottenrere l'url delle API create, si può indicare nel template un output dove visualizzare l'informazione richiesta
UrlGet:
Description: Endpoint URL API REST
Value:!Sub https://${ES12ApiGateway}.execute-api.${AWS::Region}.amazonaws.com/${Stage}
Nell'esempio disponibile su GIT è stata aggiunta anche una funzione Lambda per il caricamento da file CSV in modo da rendere l'esempio più completo possibile.
https://github.com/alnao/AWSCloudFormationExamples/tree/master/Esempio12dynamoApiCrud
Una delle funzionalità più evolute di AWS è la definizione di procedure ServerLess cioè senza la definizione di quale infrastruttura esegue il codice, ma le step-function prevedono la definizione dei vari step di una procedura e l'infrastruttura AWS esegue. Il servizio Cloud Formation permette di definire le "Step function" in maniera pulita e semplice con pochi click e facilmente mantenibile grazie proprio al servizio CloudFormation. Per il corretto funzionamento e per best-practice bisogna definire due file, nel primo si definiscono i componenti del template cloud Formation dove si devono censire gli elmenti della StateMachine, i suoi log e la regola IAM. Per esempio:
Resources:
Esempio08StateMachineRole:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: Allow
Principal:
Service:
- states.amazonaws.com
Action:
- 'sts:AssumeRole'
Policies:
- PolicyName: "buckets-and-logs"
PolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: Allow
Action: "s3:*"
Resource: !Sub "arn:aws:s3:::${SourceBucket}/*"
- Effect: Allow
Action: "s3:*"
Resource: !Sub "arn:aws:s3:::${DestBucket}/*"
Esempio08StateMachineLogGroup:
Type: AWS::Logs::LogGroup
Properties:
RetentionInDays: 3
LogGroupName: !Sub /aws/vendedlogs/states/${SFName}-logs
Esempio08StateMachine:
Type: AWS::Serverless::StateMachine
Properties:
Name: !Ref SFName
Type: STANDARD
DefinitionUri: statemachine.yaml
Role: !GetAtt Esempio08StateMachineRole.Arn
DefinitionSubstitutions:
DestFileName: !Ref DestFileName
SourcePath: !Ref SourcePath
SourceBucket: !Ref SourceBucket
DestBucket: !Ref DestBucket
DestFilePath: !Ref DestFilePath
Logging:
Destinations:
- CloudWatchLogsLogGroup:
LogGroupArn: !GetAtt Esempio08StateMachineLogGroup.Arn
Level: ALL
IncludeExecutionData: True
Successivamente bisogna definire il file yaml della step function, nell'esempio è il file statemachine.yaml, con i vari passi. In questo esempio la step function esegue la copia di un file da un bucket ad un altro e poi cancella il file sorgente:
StartAt: CopyInputFile
States:
CopyInputFile:
Type: Task
Resource: arn:aws:states:::aws-sdk:s3:copyObject
Parameters:
Bucket: ${DestBucket}
CopySource.$: States.Format('${SourceBucket}/${SourcePath}/{}', 'file.txt')
Key.$: States.Format('${DestFilePath}/${DestFileName}-{}', $$.Execution.StartTime)
ResultPath: null
Next: DeleteInputFile
DeleteInputFile:
Type: Task
Resource: arn:aws:states:::aws-sdk:s3:deleteObject
Parameters:
Bucket: ${SourceBucket}
Key.$: States.Format('${SourcePath}/{}', 'file.txt')
ResultPath: null
Next: End
End:
Type: Pass
End: true
Da notare che in questo caso si usano i parametri del template. Inoltre è usata una proprietà Execution che contiene alcune informazioni riguardo all'esecuzione della stessa, la documentazione ufficiale elenca tutti i campi disponibili. Oltre ai parametri del template è possibile ricevere nelle step function valori ritornati da altre funzioni, per esempio una lambda può richiamare la step function passando come parametri il valore in formato json:
client.start_execution(
stateMachineArn=os.environ['STATE_MACHINE_ARN'],
input='{ "filename": "' + file_name + '" }'
)
e il valore può essere recuperato dal template
Key.$: States.Format('${SourcePath}/{}', $.filename)
L'esempio completo può essere ritrovato nel git pubblico
https://github.com/alnao/AWSCloudFormationExamples/tree/master/Esempio08stepFunction
Il servizio EventBridge è studiato anche per essere configurato con CloudFormation: i trigger tipicamente sono costruiti tramite template che creano il servizio scatenante e anche la destinazione dell'evento, per esempio un trigger su un bucket S3 può essere descritto con una semplice regola dove si definisce la sorgente (source) e la destinazione (target):
TriggerOnFilePutEventRule:
Type: AWS::Events::Rule
Properties:
EventBusName: default
EventPattern:
source:
- "aws.s3"
detail-type:
- "Object Created"
detail:
bucket:
name:
- !Ref SourceBucket
object:
key:
- prefix: !Ref SourcePath
Targets:
- Id: id1
Arn: !GetAtt LambdaTarget.Arn
Se usata questa modalità di "EventPattern" si deve controllare se il bucket sorgente è abilitato a generare eventi in CloudBridge, senza questa abilitazione gli eventi non vengono generati dai bucket quindi i trigger non viene avviato.
Mentre un evento schedulato può essere definito con un semplice template
CloudBridgeSchedule:
Type: AWS::Events::Rule
Properties:
State: "ENABLED"
ScheduleExpression: cron(5 0 * * ? *)
Targets:
- Id: id1
Arn: !GetAtt CustomLambda.Arn
Da notare che il ?
è obbligatorio perchè si riferisce al giorno della settimana previsto dalla configurazione CRON di AWS e bisogna sempre ricordare che gli orari sono impostati sul fuso orario inglese (GMT) e non quello italiano (CEST). Maggiori dettagli si possono trovare nella pagina ufficiale della documentazione di riferimento per gli eventi schedulati nel sito AWS. In caso di eventi definiti con CloudFormation che hanno destinazione in funzioni lambda bisogna ricordarsi di aggiungere nel template la definizione del "permission", senza questo dettaglio ulteriore l'evento non sarà autorizzato ad eseguire la funzione e si genererà un errore in fase di esecuzione dell'evento stesso, la definizione è molto semplice e va a legale i due ARN di evento e lambda:
SchedulePermission:
Type: AWS::Lambda::Permission
Properties:
Action: lambda:InvokeFunction
FunctionName: !GetAtt CustomLambda.Arn
Principal: events.amazonaws.com
SourceArn: !GetAtt CloudBridgeSchedule.Arn
In alcune documentazioni e in molti articolo si può trovare una vecchie versione dei template che usava CloudTrail per generare gli eventi in CloudBridge, questa modalità è da considerare obsoleta e non conviene usarla in quanto legata al CloudTrail mentre la nuova modalità usa solo il servizio CloudBridge più efficente. La vecchia versione dell'oggetto EventPattern era del tipo:
EventPattern:
source:
- "aws.s3"
detail:
eventSource:
- 's3.amazonaws.com'
eventName:
- 'CopyObject'
- 'PutObject'
requestParameters:
bucketName:
- !Ref SourceBucket
key:
- prefix: !Ref SourcePath
E' possibile definire template per la creazione e la configurazione di istanze Ec2, in questo caso le configurazioni da fare sono molte perché il servizio Ec2 prevede diverse configurazioni indispensabili per assicucare al Cloud e ai dati la massima sicurezza possibile: di base bisogna prima definire una istanza con le indicazioni della zona, del disco EBS e dell'interfaccia di rete di base con l'indicazione alla subnet di rete e al security group:
ES14ServerAEC2:
Type: AWS::EC2::Instance
Properties:
AvailabilityZone: !Ref RegionAZ
KeyName: AlbertoNaoFormazione
BlockDeviceMappings:
- DeviceName: '/dev/sda1'
Ebs:
VolumeSize: 8 # in GB
ImageId: !Ref EC2Ami
InstanceType: 't2.micro' # t2.micro free tier
NetworkInterfaces:
- AssociatePublicIpAddress: true
PrivateIpAddress: '10.199.84.4'
SubnetId: !Ref ES14PubSubnetA
DeviceIndex: '0'
Description: 'Primary network interface'
GroupSet:
- !Ref ES14ServerSecurityGroup
Subnet di rete e al security group sono elementi indispensabili per i servizi AWS Ec2 e bisogna definirli nel template con l'indicazione delle regole di rete e la VPC indispensabile per questo tipo di configurazione:
ES14ServerSecurityGroup:
Type: AWS::EC2::SecurityGroup
Properties:
GroupDescription: 'Server security group'
GroupName: 'ServerSecurityGroup'
SecurityGroupIngress:
- CidrIp: '0.0.0.0/0'
IpProtocol: TCP
FromPort: 22
ToPort: 22
#- SourceSecurityGroupId: !Ref ES14LoadBalancerSecurityGroup
- CidrIp: '0.0.0.0/0'
IpProtocol: TCP
FromPort: 8080
ToPort: 8080
SecurityGroupEgress:
- CidrIp: '0.0.0.0/0' # Not for Prod
IpProtocol: -1 # Allow all
VpcId: !Ref VpcId
ES14PubSubnetA:
Type: AWS::EC2::Subnet
Properties:
AvailabilityZone: !Ref RegionAZ
CidrBlock: 10.199.84.0/24
VpcId: !Ref VpcId
Per l'avvio di una istanza Ec2 bisogna ricordarsi di configurare tutte le interfacce e le componenti di rete: l'internet gateway, il nat gateway, la route table e l'IP tramite il servizio di elastic IP. Un semplice esempio base per la configurazione dei componenti di rete necessaria al funzionamento di una EPC è
ES14IGW:
Type: AWS::EC2::InternetGateway
Properties:
Tags:
- Key: "Name"
Value: "ES14IGW"
ES14IgwAttachment:
Type: AWS::EC2::VPCGatewayAttachment
Properties:
InternetGatewayId: !Ref ES14IGW
VpcId: !Ref VpcId
ES14NATa:
Type: AWS::EC2::NatGateway
Properties:
AllocationId: !GetAtt ES14EIPa.AllocationId
SubnetId: !Ref ES14PubSubnetA
Tags:
- Key: "Name"
Value: "ES14NATa"
ES14MainRT:
Type: AWS::EC2::RouteTable
Properties:
VpcId: !Ref VpcId
Tags:
- Key: "Name"
Value: "MainRT"
ES14MainRTRoute:
Type: AWS::EC2::Route
Properties:
DestinationCidrBlock: 0.0.0.0/0
GatewayId: ES14IGW
RouteTableId: !Ref ES14MainRT
ES14EIPa:
Type: AWS::EC2::EIP
Properties:
Tags:
- Key: "Name"
Value: "ES14EIPa"
ES14MainRTSubnetAAssociation:
Type: AWS::EC2::SubnetRouteTableAssociation
Properties:
RouteTableId: !Ref ES14MainRT
SubnetId: !Ref ES14PubSubnetA
L'esempio completo è disponibile al GitHub:
https://github.com/alnao/AWSCloudFormationExamples/tree/master/Esempio14istanzeEC2
E' possibile creare con CloudFormation un template per la creazione API Rest sviluppata in Java il servizio Lambda e il paradigma del server-less. Proma di tutto bisogna creare un template in formato yaml (o json) e inseire la definizione dei vari componenti, in questo semplice esempio sono due: la funzione e httpApi:
HelloWorldFunction:
Type: AWS::Serverless::Function
Properties:
CodeUri: HelloWorldFunction
Handler: helloworld.App::handleRequest
Runtime: java8
Environment:
Variables:
PARAM1: VALUE
Events:
HelloWorld:
Type: HttpApi
Properties:
ApiId: !Ref ES15HttpApi
Path: /hello
Method: GET
ES15HttpApi:
Type: AWS::Serverless::HttpApi
Properties:
StageName: !Ref StageName
RouteSettings:
"GET /hello":
ThrottlingBurstLimit: 500 # overridden in HttpApi
Per il codice in java bisogna creare un progetto java dentro ad una sottocartella "HelloWorldFunction" (valore del CodeUri) come un progetto maven ufficiale, con con file pom.xml dove bisogna indicare le dipendenze del progetto e le configurazioni del compilatore java, un esempio è disponibile:
https://github.com/alnao/AWSCloudFormationExamples/blob/master/Esempio15lambdaJava/HelloWorldFunction/pom.xml
Poi ovviamente bisogna creare la classe che verrà eseguita come Lambda, in questo caso bisogna creare un metodo java indicato nella proprietà Handler del template cloudformation: il package (helloworld), la classe (App) e il metodo (handleRequest), per esempio:
public class App implements RequestHandler<Object, Object> {
public Object handleRequest(final Object input, final Context context) {
Map<String, String> headers = new HashMap<>();
headers.put("Content-Type", "application/json");
headers.put("X-Custom-Header", "application/json");
try {
String output = String.format("{ \"message\": \"hello world\" }");
return new GatewayResponse(output, headers, 200);
} catch (Exception e) {
return new GatewayResponse("{}", headers, 500);
}
}
}
In questo semplice esempio è stata usata una classe POJO creata custom dal nome GatewayResponse
public class GatewayResponse {
private final String body;
private final Map<String, String> headers;
private final int statusCode;
...
Una volta compilato in locale con il comando
mvn install
mvn build
si possono eseguire i comandi aws-sam per eseguire il caricamento della funzione in un ambiente AWS come tutti gli altri template. In questo caso la classe java viene compilata e inserita dentro ad un pacchetto jar (anche se con estensione zip) e caricata nel bucket indicato in fase di deloy del comando sam. In alternativa a maven e al pom.xml è possibile usare il gradle creando il file build.gradle con le configurazioni del compilatore
Un esempio completo funzionante è disponibile sul GIT:
https://github.com/alnao/AWSCloudFormationExamples/tree/master/Esempio15lambdaJava
Una delle necessità maggiori è quella di creare uno "strato" di sicurezza alle API esposte tramite API Gateway. Uno dei metodi più classici è implementare all'interno dell'API il controllo di un token all'interno del codice, per questo si può usare il JWT con la libreria dedicata di Python. In questo semplice esempio viene creato un template CloudFormation con i seguenti componenti:
- parametri JwtKey e Stage per indicare la chiave del token JWT
- IamRole per permettere alla lambda di scrivere un log
- ApiGateway per definire la regola di Cors, i metodi HTTP e l'endpoint API
- Lambda function per definire la risorsa API e il codice python
Nel codice Python bisogna aggiungere il file requirements.txt
con il pacchetto
pyjwt
E poi nel codice Python si può usare la funzione decode della libreria JWT.
import json
import jwt
import os
JwtKey = os.environ['JwtKey']
def entrypoint(event, context):
print("esempio16lambdaAPIconJWT Received event: " + json.dumps(event))
try:
token = ''+event['headers']['Authorization']
token = token.replace('Bearer ','')
decoded = jwt.decode(token, JwtKey, algorithms=['HS256'])
except:
return {'body':'','statusCode': 401}
# business logic per recuperare i dati da ritornare
data = { 'evento' : 'OK' }
return {'body': json.dumps(data), 'statusCode': 200 }
Per testare si può creare un token creato da un backend o nel sito ufficiale, usando lo stesso JwtKey indicato nel template e su Postman chiamare la api senza token per notare l'errore 401 mentre ritornerò OK 200 se viene aggiunto il token JWT alla chiamata API.
L'esempio completo può essere trovato nel GIT:
https://github.com/alnao/AWSCloudFormationExamples/tree/master/Esempio16lambdaAPIconJWT
Questo esempio è da intendersi solo un esempio di prova con la validazione del token inline cioè all'inteno della lambda che esegue la logica di business, AWS permette di definire una regola nel API manager per la gestione del token, procedura che sarà descritta in un successivo articolo.
In una infrastruttura AWS Cloud può capitare di dover scambiare file con altri sistemi o tra applicazioni all'interno del Cloud, per risparmiare spazio e ridurre il traffico può capitare di dover scambiare file in formato compresso ZIP, in questo caso è necessario avere un servizio per eseguire l'estrazione del contenuto del pacchetto compresso. Le regole di best-practice su Cloud indicano di dividere i vari compiti isolando quei servizi che possono essere isolati per permettere la riusabilità e la modularità. In questo è naturale usare le Lambda Function e definire un template CloudFormation base con solo la funzione di estrazione del pacchetto, con la possibilità di utilizzare questo semplice template all'interno di altri template CloudFormation o sarà possibile invocare la Lambda da altri servizi AWS.
Il template di CloudFormation di esempio prevede due componenti: il trigger e la lambda function, poi bisogna aggiungere la regola "permission" per legare i due componenti e la regola IAM per permettere alla Lambda di leggere e scrivere nei bucket S3, si rimanda agli altri esempi per vedere queste componenti. La particolarità di questo esempio è la definizione della lambda in Python che usa solo librerie standard di Python, definendo due metodi l'entrypoint della lambda e il metodo che esegue l'estrazione dal pacchetto compresso salvando tutti i files contenuti:
import zipfile
import io
import os
import fnmatch
from io import BytesIO
from boto3 import resource
def entrypoint(event, context):
global s3_resource
s3_resource = resource('s3')
sourcebucketname = os.environ['SourceBucket']
destination_bucket = s3_resource.Bucket( os.environ['DestBucket'])
s3_key = event['detail']['requestParameters']['key']
file_name = os.path.basename(s3_key)
print("Esempio17lambdaUnzip Filename: " + file_name)
if file_name=="":
return {'statusCode': 200}
if fnmatch.fnmatch(file_name, os.environ['SourceFilePattern']):
print("Esempio17lambdaUnzip File matched!")
unzip_files(s3_key, sourcebucketname, destination_bucket)
return {'statusCode': 200}
def unzip_files(filekey, sourcebucketname, destinationbucket):
zipped_file = s3_resource.Object(bucket_name=sourcebucketname, key=filekey)
buffer = BytesIO(zipped_file.get()["Body"].read())
zipped = zipfile.ZipFile(buffer)
for file in zipped.namelist():
final_file_path = os.environ['DestPath'] + "/" + file
print("Esempio17lambdaUnzip to file " + final_file_path)
with zipped.open(file, "r") as f_in:
content = f_in.read()
#gzipped_content = gzip.compress(f_in.read())
destinationbucket.upload_fileobj(io.BytesIO(content),
final_file_path,
ExtraArgs={"ContentType": "text/plain"})
Da notare che questo esempio esegue prima la verifica del pattern del nome file in modo da andare ad elaborare solo i pacchetti desiderati. Il codice completo dell'esempio può essere trovato nel GitHUB:
https://github.com/alnao/AWSCloudFormationExamples/tree/master/Esempio17lambdaUnzip
Grazie al servizio di AWS "SSM Parameter Store" è possibile definire alcuni parametri dalla console di AWS e successivamente recuperare i valori da un template CloudFormation, questa tecnica può essere usata per salvare parametri diversi a seconda degli ambienti, per esempio diversificare i valori tra account di test e di produzione.
Bisogna ricordare che usando tale il servizio SSM e il suo "parameter store", in CloudForamtion viene recuperato il valore al momento della creazione dello stack, se il valore viene aggiornato successivamente alla creazione, sarà necessario eseguire l'aggiornamento dello stack. I tipi di valori permessi sono : Stringhe, lista di stringhe, lista delimitata da virgola o uno specifico parametro di AWS standard recuperabile tra una lista di valori messi a disposizione del Cloud.
Un esempio di utilizzo è pensare di creare una istanza EC2 con un semplice template con due parametri: il tipo e l'immagine AMI recuperabili da SSM, nel primo caso bisogna ricordarsi di creare il parametro altrimenti la creazione dello stack di CloudFormation genererà un errore.
Parameters:
InstanceType:
Type: AWS::SSM::Parameter::Value<String>
Default: /dev/ec2/instenceType
ImageId:
Type: AWS::SSM::Parameter::Value<AWS::EC2::Image::Id>
Default: /aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-x86_64-gp2
Resources:
Esempio18parametriSSMinstance:
Type: AWS::EC2::Instance
Properties:
InstanceType: !Ref InstanceType
ImageId: !Ref ImageId
Dopo aver creato lo stack, nella console sarà possibile vedere i parametri SSM e il valore del parametro nella colonna "Resolved value" che risulta molto utile per sapere quale valore è stato usato durante le fasi di creazione di uno stack. Questo semplice esempio può essere trovato nel repository:
https://github.com/alnao/AWSCloudFormationExamples/tree/master/Esempio18parametriSSM
dove si possono notare anche le regole di rete indispensabili per la creazione di una istanza EC2.
Spesso in informatica un oggetto map è un insieme di coppie di chiavi e valori che possono essere usati come registro ordinato e consistente, spesso infatti viene visto che l'evoluzione degli array e delle liste dei classici linguaggi di programmazione ad oggetti. Anche nei template di CloudFormation è possibile definire questa matrice attraverso la sezione mappins dove ad un nome si definiscono la lista delle chiavi e dei valori, rispettivamente il nome della matrice è il primo livello, la chiave è il secondo livello metre il valore è il terzo livello.
Un semplice esempio è definire una matrice che per i diversi ambienti descriva la grandezza di una istanza del servizio EC2:
Mappings:
EnvInstance:
Dev:
EC2Type: t2.micro
Prod:
EC2Type: t2.small
In questo esempio: EnvInstance è il nome della matrice, dev e prod sono le chiavi, EC2Type è il valore. Da notare che è possibile definire più valori all'interno ella stessa chiave. In un template il valore è recuperabile con la funzione FindInMap dove bisogna passare i tre livelli:
InstanceType: !FindInMap [EnvInstance, Dev, EC2Type]
La comodita di questa tecnica è combinare il mapping e i parametri cioè recuperare il secondo livello da un parametro dinamico, per esempio:
InstanceType: !FindInMap [EnvInstance, !Ref 'EnvName', EC2Type]
Dove EnvName è un parametro così definito
Parameters:
EnvName:
Type: String
AllowedValues: [dev,prod]
Default: dev
Questa tecnica infatti permette di unire le due sezioni dei template per agevolare il lavoro del programmatore. Questa tecnica è usata SOLO nei casi in cui l'elenco dei valori è ben determinato e invariante nel tempo, altrimenti l'uso dei parametri classici è obbligatorio. Inoltre questa tecnica tende a rendere il template illeggibile perchè mappings e paramters sono sezioni divise e spesso risulta scomodo dover recuperare il valore di uno che dipende dell'altro. L'esempio completo di questo esempio, evoluzione del Esempio18parametriSSM, è disponibile nel solito repository:
https://github.com/alnao/AWSCloudFormationExamples/tree/master/Esempio19mappings
All'interno dei template CloudFormation è possibile creare delle condizioni, queste possono gestire la creazione di alcune risorse in maniera semplice in modo da poter avere un unico template con delle condizioni al suo interno. Il caso d'uso più semplice è creare lo stesso templare per l'ambiente di produzione e l'ambiente di test ma creare risorse diverse a seconda del tipo di ambiente, spesso questa tecnica viene chiamata come enviroments-template. La base è dichiarare la condizione e il suo valore che può dipendere da parametri o mappings, per esempio
Conditions:
CreateVolume: !Equals [!Ref EnvName, prod]
All'interno di queste condizioni possono essere usate tutte queste istruzioni logiche:
- Fn::And
- Fn::Equals
- Fn::If
- Fn::Not
- Fn::Or
All'interno delle risorse è possibile aggiungere la proprietà
Condition: CreateVolume
Esaminando il caso del precedente esempio, aggiungiamo un disco se si tratta 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
All'interno della sezione di outputs è possibile fare rifermenti a valori condizionali, per esempio è possibile ritornare il riferimento al Volume creato, anche in questo caso il messaggio di output sarà creato a seconda della condizione dichiarata all'inizio del template.
Outputs:
StackName:
Description: Deployed StackName for update
Value: !Ref AWS::StackName
VolumeId:
Description: Volume ID if created
Condition: CreateVolume
Value: !Ref Esempio20conditionsVolume
L'esempio completo è disponibile nel solito repository:
https://github.com/alnao/AWSCloudFormationExamples/tree/master/Esempio20conditions
CloudFormation è uno dei servizi più complessi di AWS ma allo stesso tempo è uno dei più potenti. In questa serie di articoli vengono esposti alcuni esempi completi di template avanzati con lo scopo di costruire infrastrutture realmente usabili in ambienti reali. Si danno per scontate le nozioni presenti negli articoli precedenti e il concetto di "nested stacks" o template nidificati che saranno usati molto nei prossimi esempi e che sono indispensabili in casi più complessi con template di grandi dimensioni.
L'uso più comunque dei nidificati è la riusabilità: per esempio un template che descrive una step function per copiare un file potrebbe essere riuato più volte in tutti qui processi che necessitano di questo tipo di operazione, un altro caso d'uso molto utile è la definizione di sotto-template specifici per singoli servizi come LoadBalancer o EC2 e poi richiamare questi da un template principale. Un esempio è la creazione di un file per creare un SecurityGroup in un file template che deve esportare nel output tutti i componenti e i riferimenti usati dal chiamante. Un template padre può richiamare sotto-template usando il tipo
AWS::CloudFormation:Stack
e recuperare l'output e usarlo con la funzione GetAtt, per esempio:
Resources:
SecurityGroup:
Type: AWS::CloudFormation:Stack
Properties:
TemplateUrl: !Ref TemplateUrl
Parameter:
ApplicationName: !Ref AWS::StackName
VPCId: !Ref VPCId
Ec2Instance:
Type: AWS::EC2::Instance
Properties:
InstanceType: t2.micro
ImageId: !Ref ImageId
SecurityGroupIds:
- !GetAtt SecurityGroup.Outputs.SSHGroupId
...
...
Da notare che l'uso di questa tecnica costringe il caricamento dei template preventivamente su un bucket S3 prima di poter essere inglobato in altro template. Un esempio completo può essere trovato al repository ufficiale ECS:
https://github.com/aws-samples/ecs-refarch-cloudformation/blob/master/master.yaml
Che richiama il template per creare una VPC dal template ufficiale AWS:
Resources:
VPC:
Type: AWS::CloudFormation::Stack
Properties:
TemplateURL: https://s3.amazonaws.com/ecs-refarch-cloudformation/infrastructure/vpc.yaml
Parameters:
EnvironmentName: !Ref AWS::StackName
VpcCIDR: 10.84.0.0/16
PublicSubnet1CIDR: 10.84.8.0/21
PublicSubnet2CIDR: 10.84.16.0/21
PrivateSubnet1CIDR: 10.84.24.0/21
PrivateSubnet2CIDR: 10.84.32.0/21
Nella maggior parte degli articoli che seguiranno verranno usati alcuni template pubblici ufficiali ma sarà sempre chiara la sorgente a la tecnica di import, in alcuni esempi i template ufficiali vengono scaricati e modificati ma è sempre indicata la sorgente originale e viene sempre indicata la risorsa aggiunta al template.
La creazione di un template CloudFormation per creare un VPN Endpoint è uno dei template più complessi da costruire perchè il programmatore deve aver ben presente l'infrastruttura di rete da creare con il template per permettere ai client dell VPN per accedere alla rete VPC in AWS. La base di partenza è il template standard per la creazione di una VPC completa di quattro subnet e tutti i componenti di rete, il template è disponibile al url:
https://s3.amazonaws.com/ecs-refarch-cloudformation/infrastructure/vpc.yaml
Poi bisogna aggiungere i componenti necessari per creare un VPN Endpoint per accedere con il Client VPN, i componenti sono:
- Endpoint: indicando un range IP diverso da quello della VPC
- Security Group: per impostare le regole di rete
- Target Network: per collegare il security group alla vpc
- Autorization Rules: limitare il range di ip dal quale ci si può collegare al endpoint con il client
- Route Table: regole di rotte tra le due reti (VPC e Enpoint devono stare su due range di IP differenti)
Il template completo è dispobile al solito repository:
https://github.com/alnao/AWSCloudFormationExamples/tree/master/Esempio22vpnEndpoint
Da notare che nel template sono indispensabili alcuni parametri da valorizzare:
- le regole di rete come i range IP (Cidr)
- ARN del server di certificazione su AWS Certificate Manager
- ARN del servizio SAML del identity provider
- ARN del servizio SAML del identity provider come SelfService
- IP range della regola SSH che può accedere al EndPoint dell VPN
questi componenti devono essere creati preventivamente oppure creati da un altro template.
Ricordo che questo tipo di componente è a pagamento quindi bisogna sempre fare riferimento alla documentazione ufficiale per calcolare il costo in caso di utilizzo, specialmente in casi di presenza di molti utenti collegati potrebbe essere più conveniente creare una VPN site-to-site.
Con CloudFormation è possibile creare qualsiasi risorsa AWS e si può far "dialogare" i vari servizi, in questo esempio lo scopo è creare un sito wordpress avviato in una istanza EC2 e la base dati su una base dati RDS collegata in automatico. I componenti necessari per una infrestruttura di questo tipo sono:
- VPN dedicata come fatto nel precedente articolo
- Istanza RDS con configurato database, username e password di accesso
- Subnet dedicata al RDS all'interno delle subnet private della VPC
- SecurityGroup per permettere di collegarsi al RDS (con il parametro SSHLocation come Cidr)
- E' possibile creare la password del RDS con KMS e SecretsManager, in questo esempio le risorse sono commentate per semplicità
- SecurityGroup per permettere di collegarsi alla istanza EC2 tramite HTTP con la porta 80 e via ssh con la porta 22 (con il parametro SSHLocation come Cidr)
- Istanza EC2
La istanza EC2 creata con cloudFormation viene configurata al momento della creazione grazie all'uso di un metadato "AWS::CloudFormation::Init" che definisce:
- configSets: definisce i passi da eseguire
- install_cfn: installa cfn (CFN-CLI è il tool per sviluppare e testare estensioni nelle risorse create con CloudFormation), per maggiori dettagli vedere la documentazione ufficiale.
- install_wordpress: definisce
- packages: l'elenco dei pacchetti da installare con yum (apache e php)
- sources: il pacchetto da scaricare e la posizione dove deve essere salvato
- files: i file di configurazione di mysql (esempio la CREATE DATABASE se necessaria)
- services: i demoni da abilitare nella istanza Linux
- configure_wordpress: la creazione del file wp-config.php di wordpress neccessario per la configurazione base del sito
Inoltre all'interno dell'userdata viene avviato il "aws-cfn-bootstrap" per eseguire i passi appena descritti e poi viene eseguito il comando "cfn-signal" con il quale CloudFormation verrà informato che l'istanza EC2 è stata avviata correttamente e che è in esecuzione, infatti nel template c'è l'indicazione di quanto CloudFormation deve aspettare prima di ricevere il segnale ok o di fare rollback con la proprietà
CreationPolicy:
ResourceSignal:
Timeout: PT20M
Nel template di esempio si usa un database esterno grazie al servizio RDS ma è possibile usare un dabatase interno mysql, in questo caso nel template si possono commentare alcune risorse del template.
L'esempio completo può essere trovato al solito repository:
https://github.com/alnao/AWSCloudFormationExamples/tree/master/Esempio23wordpressSingle
E' possibile creare e gestire un volume EFS tramite un template CloudFormation, anche in questo casi si usa un template "needest" (annidato). Nell'esempio più semplice c'è bisogno di una VPC specifica e il disco viene creato in una subnet specifica della rete, inoltre si può creare una istanza EC2 che monta il disco velocemente nello script di user data. La complicazione maggiore in questo caso è che bisogna creare un security group per regolare il traffico tra la EC2 e il EFS, per fare questo bisogna creare questo elementi prima del volume e prima dell'istanza quindi, a titolo di esempio, viene creato esternamente. Nel Security group specifico del EFS si mette il riferimento al Security group globale in modo che la regola sia consistente e non si creino regole di rete cicliche, il rischio infatti è di creare una regola che dipende dell'altra e viceversa.
Per montare il volume nella istanza è necessario che il template che genera il EFS ritorni in output il riferimento al volume
Outputs:
EFSFileSystemId:
Description: EFS name
Value: !GetAtt EFS.Outputs.FileSystemId
che poi viene usato nel template che crea la EC2 nella definizione del user-data
UserData: !Base64
'Fn::Join':
- ''
- - |
#!/bin/bash -xe
sudo yum install -y amazon-efs-utils
sudo mkdir /mnt/efs
sudo chmod 777 /mnt/efs
- 'sudo mount -t efs -o tls '
- !Ref EFSFileSystemId
- ':/ /mnt/efs '
Questo semplice esempio è disponibile al solito repository:
https://github.com/alnao/AWSCloudFormationExamples/tree/master/Esempio24efsEc2
Oltre all'operazione di mount del volume, all'interno dell'istanza viene avviato il server web Apache e che nel volume EFS viene creato un file index.html esposto dal web-server, questo è da ritenersi un solo esempio esplicativo in quanto il volume e l'istanza si trovano nella subnet pubblica. Le regole di sicurezza e best-practice prevedono la segregazione delle componenti nelle subnet private e poi la definizione di un Load Balancer per l'esposizione in internet, questo viene esposto in un successivo esempio.
Un sistema molto efficace per sicurizzare le API è il sistema Lambda Authorizer che prevede la creazione di un metodo lambda specifico invocato per la autenticazione e la autorizzazione per ogni chiamata alla API, in un semplice esempio la lambda può validare che il token non sia scaduto. Il template si basa su AWS::Serverless::Api
e non su AWS::ApiGateway::RestApi
, per questo secondo tipo si rimanda agli articoli dedicati. Nella sezione di dichiarazione della API è possibile definire il nodo di autenticazione “Auth” con l’indicazione del tipo e quale elemento viene usato per il processo di validazione:
Auth:
DefaultAuthorizer: MyLambdaRequestAuthorizer
Authorizers:
MyLambdaRequestAuthorizer:
FunctionPayloadType: REQUEST
FunctionArn: !GetAtt Esempio16lambdaConAuthorizerLambdaAuth.Arn
Identity:
Headers:
- Authorization
Inoltre (per sicurezza) bisogna sempre ricordarsi di aggiungere il permesso di invocazione della Lambda dal ApiGateway
Esempio16lambdaConAuthorizerPermission:
Type: AWS::Lambda::Permission
Properties:
Action: lambda:InvokeFunction
FunctionName: !Ref Esempio16lambdaConAuthorizerLambdaAuth
Principal: apigateway.amazonaws.com
SourceArn: !Sub arn:aws:execute-api:${AWS::Region}:${AWS::AccountId}:${Esempio16lambdaConAuthorizerApiGateway}
Il template completo e funzionante di questo esempio può essere trovato al solito repository:
https://github.com/alnao/AWSCloudFormationExamples/tree/master/Esempio16lambdaAuthorizer
Una guida su questa tecnica può essere trovata nel blog ufficiale.
Una delle applicazioni più usate di CluodFormation è creare sistemi applicativi in reti private ma esposte in internet con un Application Load Balancer che permette anche di creare un Autoscaling group per garantire la resilienza e la scalabilità della stessa applicazione. Usando CloudFormation è possibile disegnare e creare tutta l'architettura che comprende:
- VPC con subnet private e pubbliche
- VPC endpoint per accedere via client alla rete
- Database applicativo con il servizio RDS
- LoadBalancer per bilanciare il traffico e creare un endpoint pubblico
- TargetGroup e AutoScalingGroup per gestire le istanze applicative e le regole di scalabilità
- LaunchConfiguration per creare le regole di avvio delle istanze
In un semplice esempio è possibile installare l'applicativo WordPress e il server Apache usando l'userData e le ConfigSet previste dal servizio EC2, in questo modo è possibile gestire tutto in autonomia in modo da permettere che ogni istanza avvii l'applicazione indipendente che punta alla stessa base dati (RDS) ma vive di vita proprio. L'esempio completo è disponibile al solito repository:
https://github.com/alnao/AWSCloudFormationExamples/tree/master/Esempio25balancer
Questo esempio presenta dei difetti strutturali: ogni istanza è isolata e non c'è un filesystem condiviso, framework o applicazioni che necessitano storage condiviso non funziona, per esempio un sito WordPress in questo modo non funzionerebbe perché i media sarebbero storicizzati in una istanza e le altre non vedrebbero i files delle altre istanze, per risolvere il problema si può usare un disco EFS condiviso, template che sarà esposto nel prossimo esempio.
Una dei linguaggi più usato al mondo è Java ed è ovviamente possibile usare tale linguaggio per sviluppare funzioni AWS-Lambda per tutte le necessità. In questa serie di articoli saranno esposti alcuni esempi di funzioni per usi diversi ma avendo sempre come base il componente di accesso ai servizi AWS chiamato AmazonS3Client. In questo articolo sarà esposto il metodo base e "manuale" per creare funzioni lambda a titolo di esempio per mostrare nel dettaglio ogni singolo componente dell'architettura, in successivi articoli saranno esposti i metodi più automatici grazie ad AWS CLI, AWS SAM e AWS SDK che permettono al programmatore di saltare alcuni passaggi manuali che vengono eseguiti dai tool messi a disposizione dalla piattaforma. Il primo passo è creare un progetto Java con Maven, questo è possibile sia da Eclipse sia da MS Code, nel file pom.xml bisogna aggiungere alcune dipendenze necessarie per la compilazione:
<dependency>
<groupId>com.amazonaws</groupId>
<artifactId>aws-java-sdk-s3</artifactId>
</dependency>
<dependency>
<groupId>com.amazonaws</groupId>
<artifactId>aws-lambda-java-core</artifactId>
<version>1.1.0</version>
</dependency>
<dependency>
<groupId>com.amazonaws</groupId>
<artifactId>aws-lambda-java-events</artifactId>
<version>1.3.0</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
Oppure, nella procedura guidata di Eclipse, è possibile selezionare il tipo "aws-lambda-s3-example". Quello che bisogna creare è una classe e un metodo specifici che poi saranno il corpo della funzione lambda. La classe deve implementare RequestHandler che ha due archetipi: l'elenco scatenante in input e il tipo di output della funzione, infatti poi bisogna definire una funzione che i due tipi in ingresso e in uscita. Esempio:
public class LambdaRequestHandler implements RequestHandler<S3Event, String> {
@Override
public String handleRequest(S3Event s3event, Context context) {
System.out.println("Funzione lambda eseguita");
return "OK";
}
}
questa semplice classe è già pronta per essere compilata con il comando:
mvn pacakge
oppure lanciando la procedura guidata di ecplise mettendo "pacakge" come "goals", il comando va a creare un file jar all'interno della cartella target, questo pacchetto è pronto per esser rilaciato in AWS.
Nella console di AWS, nel servizio lambda si devono eseguire i seguenti passi:
- creare manualmente una nuova funzione selezionando il nome e il tipo "Java 8 on Amazon Linux 1"
- caricare il jar, selezionado il file dopo aver premuto la tendina "Upload from" nella vista code
- impostare la classe nella sezione "Runtime settings" nella vista code, inserendo il valore nel tipo pacakge::metodo, per esempio "it.alnao.lambda.examples.Esample1::handleRequest"
- impostare memoria e timeout nella scheda "General" nella vista "Configuration", di default i valori sono 512Mb e 15 secondi rispettivamente
- impostare trigger e permission se necessario, in questo primo esempio non sono previsti
Per provare manualmente la funzione basta andare nella vista test e lanciare il bottone "test", il risultato sarà un messaggio "OK" e aprendo i dettagli si potrà vedere anche il messaggio scritto nella stream di output. Nella vista monitor sono disponibili i grafici di tutte le esecuzioni con il dettaglio di errori e un tab specifico per accedere ai log su CloudWatch.
L'esempio completo può essere trovato al git
https://github.com/alnao/AwsLambdaExamples/tree/master/java-maven-example01
Grazie al plugin AWS di Eclipse è possibile creare funzioni lambda in Java con pochi click. Il plugin mette a disposizione alcuni tipi di progetto e in fase di creazione basta selezionare il tipo "Aws Lambda Java Project" indicando il pacakge java di destinazione; una volta creato il progetto sarà possibile eseguire il comando di compilazione:
mvn install
mvn build
visto che il progetto creato è un maven-standard può essere gestito e compilato come in normale progetto java e le relative dipendenze nel file pom.
Per eseguire il rilascio nel Cloud AWS bisogna selezionare la classe Handler (che di default è "LambdaFunctionHandler"), cliccando con il tasto destro del mouse compare la voce "Amazone web service" e la sottovoce "Upload function", nella procedura guidata di caricamento bisogna indicare le configurazioni base della Lambda:
- il nome della lambda e il riferimento alla classe, è possibile sostituire una lambda esistente oppure crearne una nuova
- la regola IAM, si può usare una regola pre-esistente o crearne una nuova direttamente nel tool
- il bucket s3 bucket dove viene depositato il pachetto (jar/zip) del codice
- le configurazioni avanzate di AWS-Lambda (per esempio la memoria e timeout)
Io non riesco ad usarlo in quanto, in fase di rilascio, si genera sempre un errore bloccante a causa della versione di JAXBException.
Grazie all'estensione AWS Toolkit per Visual studio Code è possibile creare e sviluppare velocemente Lambda con il linguaggio Java con pochi click e risulta anche molto più pratico e veloce del corrispondente per Eclipse. Dopo aver installato AWS Toolkit basta aprire il riquadro dei comandi (Ctrl+Maiusc+P) e selezionare la voce:
> Create lambda SAM application
In questa piccola procedura guidata è possibile selezionare il tipo di linguaggio (java e maven), il modello (consigliato il base HelloWorld) e la cartella dove salvare il progetto.
Il risultato sarà un piccolo progetto con i componenti
- cartella event con un file json di esempio che permetterà di eseguire i test da locale
- il file template.yaml con il template completo di cloudformation con la definizione della lambda e la definizione della API tramite gateway
- il progetto java-maven in una sotto-cartella con la classe App già pronta per essere eseguita
In questo piccolo progetto di esempio la lambda esegue una chiamata al servizio "checkip" per ritornare l'ip del chiamante. E' possibile eseguire localmente la lambda usando il comando CLI-SAM invocando la lambda e usando il file json di esempio come evento
$ sam local invoke HelloWorldFunction --event events/event.json
In questo caso il comando eseguirà sul docker locale la lambda e ritornerà il risultato. E' ovvio che docker deve essere installato e l'utente deve disporre delle autorizzazioni per eseguire i comandi docker.
In questo caso non funziona la funzionalità "upload lambda" disponibile cliccando con il tasto destro sul nome della cartella appena creata ma bisogna usare la CLI-SAM.
Il primo metodo per eseguire il rilascio è usare la riga di comando per compilare il progetto
$ sam build
che crea una sotto-catella .aws-sam
con dentro il compilato da maven pronto per essere rilasciato con il comando
$ sam deploy --guided
con il quale è possibile indicare ad AWS alcuni parametri come il nome del template su CloudFormation e poi viene salvato un file samconfig.toml con le configurazioni salvate. Una volta creato si può andare nella console web per vedere la lambda e il suo template CloudFormation, inoltre è possibile usare il toolkit per eseguire la lambda. Per rimuovere la lambda basta lanciare uno dei comandi:
aws cloudformation delete-stack --stack-name java-maven-example3
sam delete --stack-name java-maven-example3
Il secondo metodo per eseguire il rilascio è usare il toolkit: dal riquadro dei comandi bisogna selezionare la voce
> AWS deploy sam application
dove bisogna indicare il file yaml base, la region, il nome del bucket di appoggio e il nome del template. Nella output sarà possibile vedere lo stato avanzamento e l'esito finale del caricamento. Usando l'esensione del AWS Toolkit è possibile vedere l'elenco di tutte le funzionli Lambda create ed è possibile selezionare la voce "Invoke lambda" cliccando con il tasto destro del mouse in una lambda, nella schermata è possibile anche impostare i parametri di chiamata con la possiblità di selezionare il file json di esempio.
Per distruggere e rimuovere la lambda è possibile selezionare il template CloudFormation creato in fase di caricamento e selezionare l'opzione "Delete CloudFormation Stack", ovviamente tale operazione andrà a rimuovere tutte le risorse del template comprese altre se inserite manualmente quindi bisogna sempre prestare attenzione a quando si cancella uno stack in CloudFormation. La guida completa è disponibile nel sito ufficiale.
L'esempio completo funzionante può essere trovato nel GitHUB:
https://github.com/alnao/AwsLambdaExamples/tree/master/java-maven-example03-vscode
D'ora in avanti, per i successivi esempi verrà sempre usato questo Toolkit e non verrà usato Eclipse (visto che a me non funziona).
Tramite lambda è possibile creare una API per generare link con "signature", link che può essere da un client (browser) per scarire file da un bucket S3 che altrimenti sarebbe inaccessibile da internet. Per creare la lambda si usa la solita procedura da Eclipse o da VsCode, per esempio nel secondo caso
> Create lambda SAM application
nel progetto creato di default con la Hello di esempio bisogna prima di tutto aggiungere la libreria S3 al pom.xml:
<dependency>
<groupId>com.amazonaws</groupId>
<artifactId>aws-java-sdk-s3</artifactId>
<version>1.12.340</version>
</dependency>
e poi bisogna ricordarsi di aggiungere la regola IAM perchè quella di default non prevede che la lambda acceda ad un bucket, per questo bisogna modificare il file template.yaml aggiungendo la regola di CloudFormation per la regola IAM, si rimanda agli articoli dedicati, nel dettaglio la regola deve avere la forma:
- Effect: Allow
Action:
- 's3:*'
Resource:
- 'arn:aws:s3:::nome-bucket/*'
Senza la regola IAM dedicata il link con signature sarà creato ma se usato il servizio S3 restituirà un errore "Access denied". Il codice java poi deve prevedere l'uso delle classi AmazonS3 e il client (tipo il boto3 di python)
APIGatewayProxyResponseEvent response =
new APIGatewayProxyResponseEvent().withHeaders(new HashMap<>());
Regions clientRegion = Regions.EU_WEST_1;
AmazonS3 s3Client = AmazonS3ClientBuilder.standard()
.withRegion(clientRegion)
.withCredentials(DefaultAWSCredentialsProviderChain.getInstance())
.build();
La impostazione della scadenza
java.util.Date expiration = new java.util.Date();
long expTimeMillis = Instant.now().toEpochMilli();
expTimeMillis += 1000 * 60 * 60 * 24;
expiration.setTime(expTimeMillis);
E poi si può creare il link con il metodo dedicato
URL url = s3Client.generatePresignedUrl(bucket, objectKey,expiration);
return response.withStatusCode(200).withBody(url.toURI().toString() );
Il codice completo di questo progetto di esempio può essere trovato al solito repository:
https://github.com/alnao/AwsLambdaExamples/tree/master/java-maven-example04-s3signature
Un esempio di sviluppo di Lamda con il linguaggio Java è scrivere una API che recuperi valori da una coda dal servizio SQS. Con la procedura guidata di VS Code si può creare un progetto HelloWord e poi bisogna ricordarsi di rinominare tutto il progetto, i package e i nomi da HelloWord nel nome desiderato, nel nostro esempio è stato usato Sqs. La libreria di default non contiene i package necessari, quindi nel pom.xml è necessario aggiungere la dipendenza alla libreria specifica di Sqs:
<dependency>
<groupId>com.amazonaws</groupId>
<artifactId>aws-java-sdk-sqs</artifactId>
<version>1.12.356</version>
</dependency>
Successivamente bisogna modificare il file yaml del template Cloud-Formation aggiungendo la regola IAM per permettere alla lambda di accedere alla coda, senza questa regola la lambda otterrebbe un brutto errore "access denied
". La regola base che permette l'accesso a tutte le code è:
- Effect: Allow
Action:
- 'sqs:*'
Resource:
- '*'
Nella classe e nel template creato di default è già disponibile una api con protocollo get, perfetto per un esempio di recupero di dati con una API-Rest. Nella classe java i passi semplici da eseguire sono: recuperare il riferimento alla coda (queueUrl) e poi recupeare i messaggi grazie alla libreria di AWS. In questo semplice esempio i messaggi della coda vengono concatenati in una stringa e poi ritornati come oggetto della riposta:
AmazonSQS sqs = AmazonSQSClientBuilder.defaultClient();
String queueUrl = sqs.getQueueUrl(QUEUE_NAME).getQueueUrl();
List<Message> messages = sqs.receiveMessage(queueUrl).getMessages();
//for (Message m : messages) {
// sqs.deleteMessage(queueUrl, m.getReceiptHandle());
//}
String messagess="";
for (Message m : messages) {
messagess+=m.toString();
}
return response.withStatusCode(200).withBody(messagess);
L'esempio completo e funzionante è disponibile nel solito repository:
https://github.com/alnao/AwsLambdaExamples/tree/master/java-maven-example05-sqs
La guida completa a tutte le funzioni previste dalla libreria ufficiale è disponibile nella documentazione ufficiale.
Uno dei casi d'uso più frequesti dell'uso di lambda in Java è l'uso delle librerie comuni per eseguire operazioni su oggetti o file in AWS, un semplice ma completo esempio è la costruzione di una lambda per convertire un file Excel in CSV. Partendo dal progetto base creato da Visual Studio Code si devono sviluupare un po' di modifica:
- modificare il pacakge Java di default con un nome più consono, per esempio exc2csv
- nel pom.xml oltre alle librerie base AWS si possono aggiungere le librerie necessarie, per esempio :
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>3.11</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>3.11</version>
</dependency>
- aggiungere nel template.yaml le regole IAM per permettere alla Lambda di accedere al Bucket e la definizione del trigger EventBridge, in modo che la lambda venga invocata ogni volta che viene caricato un file nel bucket nel path specificato, per questo si può vedere l'esempio nel repository o leggere la sezione dedicata su CloudFormation.
- nella classe java bisogna prima recuperare i dati da EventBridge e poi suare la libreria per convertire il file.
I componenti Java usati sono:
- client S3
private AmazonS3 s3Client = AmazonS3ClientBuilder.standard().build();
- recupero dell'evento eventBridge (da verificare)
java.util.LinkedHashMap m1=(java.util.LinkedHashMap) event;
java.util.LinkedHashMap m3=(java.util.LinkedHashMap) m1.get("detail");
java.util.LinkedHashMap m4=(java.util.LinkedHashMap) m3.get("bucket");
java.util.LinkedHashMap m5=(java.util.LinkedHashMap) m3.get("object");
String bucket = (String) m4.get("name");
String key = (String) m5.get("key");
- lettura del file
S3Object response = s3Client.getObject(bucket, key);
InputStream in = response.getObjectContent();
Workbook workbook = null;
workbook = new XSSFWorkbook(in);
- conversione del file con la libreria "org.apache.poi"
- scrittura del file CSV
ByteArrayInputStream inputStream =
new ByteArrayInputStream(data.toString().getBytes());
String destFile=key.replace(".xlsx",".csv").replace(".xls",".csv");
s3Client.putObject(bucket, destFile, inputStream, new ObjectMetadata());
context.getLogger().log("destFile ");
if (workbook!=null){
workbook.close();
}
return destFile;
L'esempio completo può essere trovato al solito repository
https://github.com/alnao/AwsLambdaExamples/tree/master/java-maven-example06-excel2csv
Il pacchetto SDK di AWS mette a disposizione un insieme di strumenti con le quali è possibile creare codice e applicazioni che comunicano e sfruttano con i sottoservizi AWS usando le API. Utilizzando il linguaggio Java si deve usare Apache Maven per la gestione delle dipendente delle librerie e della compilazione. Per usare questo SDK, oltre all'ambiente di sviluppo con Java e Maven è necessario configurare un profilo programmatico AWS e la AWS CLI come indicato nella documentazione ufficiale e spiegato nell'articolo "CLI Command line interface".
Per la creazione del progetto è possibile usare il comando mvn visto che il SDK mette a disposizione un archetype:
mvn archetype:generate
-DarchetypeGroupId=software.amazon.awssdk
-DarchetypeArtifactId=archetype-app-quickstart
-DarchetypeVersion=2.18.16
comando che necessita l'inserimento delle informazioni base del progetto, per esempio:
javaSdkVersion: 2.18.16
service: service
httpClient: apache-client
nativeImage: false
groupId: ALNAO
artifactId: 001CreateBucket
version: 1.0-SNAPSHOT
package: it.alnao.awssdkexamples
Da notare che, trattandosi di progetto maven standard, sono presenti anche le classi di test, visto che è possibile creare unit test specifiche.
La documentazione ufficiale è molto fornita di esempi che possono essere seguiti ed analizzati.
Inoltre è disponibile anche un repository pubblico ufficiale dove sono disponibili esempi di tutti i tipi:
https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/javav2
Un semplicissimo ma utile esempio di sviluppo con la piattaforma SDK di AWS in Java è la realizzazione di un piccolo programma per la creazione ed la distruzione di un bucket S3. Questo semplice esempio è stato costruito studiando la documentazione ufficiale e gli esempi presenti nel repository ufficiale.
In questo esempio vengono definiti tre metodi per la creazione, la canncellazione e la verifica dell'esistenza di un bucket S3. Si basano sul client S3 del SDK che deve essere creata con i comandi:
ProfileCredentialsProvider credentialsProvider =
ProfileCredentialsProvider.create();
Region region = Region.EU_WEST_1;
S3Client s3 = S3Client.builder().region(region)
.credentialsProvider(credentialsProvider).build();
Poi un semplice metodo per la creazione di un bucket è
public static void createBucket( S3Client s3Client, String bucketName) {
try {
CreateBucketRequest bucketRequest = CreateBucketRequest.builder()
.bucket(bucketName).build();
s3Client.createBucket(bucketRequest);
// Wait until the bucket is created and print out the response.
HeadBucketRequest bucketRequestWait = HeadBucketRequest.builder()
.bucket(bucketName).build();
S3Waiter s3Waiter = s3Client.waiter();
WaiterResponse<HeadBucketResponse> waiterResponse = s3Waiter
.waitUntilBucketExists(bucketRequestWait);
//waiterResponse.matched().response().ifPresent(System.out::println);
logger.info(bucketName +" is ready");
} catch (S3Exception e) {
System.err.println("Errore: " + e.awsErrorDetails().errorMessage());
return;
}
}
La relativa test-unit definisce un semplice metodo che crea il bucket e ne verifica l'esistenza con un secondo metodo
@Test
@Order(2)
public void createBucket() {
System.out.println("Test 2 createBucket started");
App.createBucket(s3,bucketName);
boolean result=App.checkIfBucketExist(s3,bucketName);
assertTrue(result);
System.out.println("Test 2 createBucket passed");
}
Il metodo dell'esistenza del bucket può essere sempre definito nella classe principale, basta infatti andare a scaricare l'elenco dei bucket esistenti e fare una ricarca del nome
public static boolean checkIfBucketExist( S3Client s3Client, String bucketName) {
logger.info(bucketName +" checkIfBucketExist");
ListBucketsRequest listBucketsRequest = ListBucketsRequest.builder().build();
ListBucketsResponse listBucketsResponse = s3Client.listBuckets(listBucketsRequest);
boolean exist=false;
Iterator<Bucket> it=listBucketsResponse.buckets().iterator();
while(it.hasNext()) {
Bucket b=it.next();
if (b.name().equals(bucketName))
exist=true;
}
logger.info(bucketName +" checkIfBucketExist " + (exist ? "YES" : "NO" ) );
return exist;
}
Questo esempio completo e funzionante è disponibile al repository
https://github.com/alnao/JavaExamples/tree/master/AwsSdkJava/01_CreateBucket
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 in altre previsioni delle Condizioni Generali d’Uso, AlNao.it non potrà essere ritenuta 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.