Contenuti




AWS - La Guida Completa: Dalla Teoria alla Pratica

Tutto quello che devi sapere per iniziare con Amazon Web Services


Contenuti

AWS - La Guida Completa: Dalla Teoria alla Pratica

Amazon Web Services (AWS) è la piattaforma cloud più utilizzata al mondo, offrendo oltre 200 servizi completamente gestiti per ogni tipo di applicazione. Questa guida completa ti accompagnerà dai concetti fondamentali fino alle pratiche avanzate, fornendoti tutte le competenze necessarie per lavorare efficacemente con AWS.

A chi è rivolta questa guida

Questa guida è pensata per:

  • Sviluppatori che vogliono migrare al cloud
  • Sistemisti che desiderano specializzarsi in infrastrutture cloud
  • Studenti che si preparano alle certificazioni AWS
  • Decision maker che valutano AWS per la propria azienda
  1. AWS Cloud - Casi d’uso e Vantaggi
  2. AWS Global Infrastructure
  3. AWS Console: Global Services e Region-Scoped
  4. IAM: Identity and Access Management
  5. CLI: Command Line Interface
  6. AWS Budget Setup e Cost Management
  1. Compute Services (EC2, Lambda, ECS)
  2. Storage Services (S3, EBS, EFS)
  3. Database Services (RDS, DynamoDB)
  4. Networking Services (VPC, CloudFront, Route 53)
  1. Container Services (ECS, EKS, Fargate)
  2. Serverless Architecture (Lambda, API Gateway, Step Functions)
  3. Infrastructure as Code (CloudFormation, CDK)
  4. DevOps Tools (CodePipeline, CodeBuild, CodeDeploy)
  1. Security Services (WAF, Shield, GuardDuty)
  2. Monitoring e Logging (CloudWatch, CloudTrail)
  3. Best Practices di Sicurezza
  4. Cost Optimization Strategies
  1. Disaster Recovery e Alta Disponibilità
  2. Preparazione alle Certificazioni AWS
  3. Progetti Pratici e Labs
  4. Risorse e Prossimi Passi


  1. Aws consente di creare applicazioni sofisticate e scalabili.
  2. È applicabile a diversi tipi di industrie (es. McDonald, 21 Century Fox, Activision, Netflix).
  3. Casi d’uso includono:
    1. Enterprice IT, Backup & Storage, Big Data analytics
    2. Website hosting, Mobile & Social Apps
    3. Gaming


AWS ha regions in tutto il mondo. Le regiono possono essere intese come le aree in cui sono presenti i server di AWS. Le region hanno nomi, ad esempio ue-east-1, eu-west-3 … Una regiono è un cluster di data centers Molti servizi di AWS sono “region-scoped”(localizati). Questo significa che usando un serivizio su una region, se apro lo stesso servizio su un’altra region sarà come se lo sto aprendo per la prima volta.

Domanda d'esame

How do you choose an AWS Regin?” La risposta è dipende. Ci sono diversi fattori che influenzano la scelta:

  • Compliance dei dati e requisiti legali. In AWS i dati non lasciano mai la region dove si trovano senza un tuo esplicito permesso. Ad esempio se crei un applicazione in Spagna potrebbero esserci dei vincoli legali per avere i dati nello stesso paese.
  • Proximity rispetto ai clienti per ridurre la latenza. Ad esempio se ho un’applicazione e la maggior parte degli utenti sono americani, ha senso mettere l’applicazione in America per ridurre i lag.
  • Available services in una specifica Region. I nuovi servizi e le nuove funzionalità non sono disponibili in tutte le Region. Il concetto che non tutte le Region hanno tutti i servizi è importante.
  • Pricing: i prezzi variano da regiorne a region e si possono vedere dall’apposita pagina dei prezzi.


Ogni Region si divide in Availability Zones (AZ), possiamo intenerle come sottogruppi della region.

  • Ogni Region ha più Availability Zones: normalmente ogni Region ha 3 availability zones, il minimo è 2 e il massimo è 6. Ad esempio:
    Availability Zones 1
    Availability Zones 2
    Availability Zones 3
    AWS Region: Sydney: ap-southeast-2
    ap-southeast-2a
    ap-southeast-2b
    ap-southeast-2c
  • Ogni availability zone (AZ) è uno (o più) data ceters di grandi dimensioni, con alimentazione ridondata, rete e connessione.
  • Ogni availability zone (AZ) è separate fisicamente dalle altre, così da essere isolata dai disastri e garantire continuità di servizio.
  • Ogni availability zone (AZ) è connessa con connessione molto performante e rete a bassissima latenza.


  • Amazon ha 216 punti di presenza (al momento della guida) divisi in 205 Edge Locations e 11 Cache regionali, suddivisi in 84 città in 42 stati diversi.
  • I contenusi sono serviti agli utenti finali con un bassa latenza
AWS Edge Network
https://aws.amazon.com/cloudfront/features


I servizi di AWS di dividono in due tipologie in base alla loro disponibilità:

  • AWS Global Services: sono i servizi che sono in comune a tutte le Region, ad esempio:
    • Identity and Access Management (IAM)
    • Route 53 (DNS service)
    • CloudFront (Content Delivery Network)
    • WAF ( Web Application Firewall)
  • AWS Region-Scoped services: la maggior parte dei servizi sono di questo tipo, ad esempio:
    • Amazon EC2 (infrasctructures as a Service)
    • Elastic Beanstalk (Platform as a Service)
    • Labda (Funcion as a Service)
    • Rekognition (Software as a Service)
Link utile: AWS elenco servizi regionali
Per maggiori informazioni sui servizi che sono disponiobili e le relative region consultare la pagina ufficiale di AWS


Overview AWS Console
  1. Region-selector: qui è possibile cambiare la Region in cui si sta lavorando.
  2. Sevices: qui si possono vedere tutti i servizi disponibili in ordine alfabetico
  3. Barra di ricerca, si possono cecare servizi, funzionalità e documentazione.


AIM è la console di gestione degli utenti e dei gruppi che possono accedere a aws e ai servizi.

  • Gli utenti sono intesi come persone dell’organizzazione che possono accedere a aws.
  • Gli utenti possono essere organizzati in gruppi.
  • I gruppi possono contenere solo utenti e non altri gruppi.
  • Gli utenti possono appartenere a più gruppi.
  • È possibile avere un utente senza gruppi ma non è una best practice.
Group: Developers
User1c
User2d
User3e
Group: Operations
User1a
User2b
User3c
User1
AIM Best practice

Utente Root: Quando si accede per la prima volta a AWS viene creato il “Root Accoun”. Questo account non dovrebbe mai essere usato, fatto salvo la prima volta per creare un primo utente amministratore.

Gestione Utenti AIM: di norma ogni utente dovrebbe appartanere almeno a un gruppo che lo identifica e ne assegna i permessi. È buona norma applicare questa regola anche agli amministratori.

Agli utenti o ai gruppi è possibile assegnare permessi. I permessi sono dei documenti JSON chiamati policy

Esempio di una policy JSON: TODO mettere una policy JSON

Non è richiesto conoscere i JSON, le policy vengono gestite direttamente dalla console AWS.

AIM Best practice
In AWS bisognerebbe semple applicare “The least privilege principle”, ovvero assegnare agli utenti (o gruppo) solo i permessi di cui hanno bisogno. Ad esempio se un utente ha bisogno di accedere solo a tre servizi, allora di daremo i permessi solo per quei servizi. Per maggiorni informazioni vedi la sezione Credential Report


TODO Mettere immagine AIM

  1. Per creare un utente accedere alla console AIM.
  2. Nel menù di sinistra, sotto Access management selezionare Users.
  3. Nella nuova schermata scrivere lo Username e selezionare il Credential Type (Se impostato come password, creare la nuova password).
  4. Impostare i permessi dell’utente (se necessario creare un nuovo gruppo).
  5. Aggiungere eventuali Tags, i tag sono semplicemente informazioni aggiuntive per identificare meglio gli utenti, ad esempio possiamo dichiarare un tag che ne identifichi il reparto “Key: Department” “Value: Engineering”.
  6. Rivedere i dati inseriti e procedere alla creazione dell’utente.
  7. Dopo il messaggio di avvenuta creazione è possibile scaricare il csv con le credenziali o inviare tutto tramite e-mail.

Andando nel menu User, sotto Access management selezionare Users, è possibile vedere l’elenco degli utenti. Apreno un utente è possibile vedere tutti i gruppi di cui fa parte e i permessi associati.



I gruppi possono essere creati in due modi:

  1. Durante la creazione di un utente, quando si arriva alla sezione per l’assegnazione dei permessi, è possibile creare un nuovo gruppo di cui farà parte l’utente.
  2. Dal menù di sinistra, sotto Access management selezionare User groups.
    1. Selezionare Create group In entrabi i casi si arriverà alla schermata di creazione del gruppo. Qui occorre specificare il nome del gruppo, gli utenti che ne fanno parte (se sono in fase di creazione di un utente, quest’ultimo sarà aggiunto autonomamente) e le policy da agganciare al gruppo.
AIM Best practice
Si consiglia di creare sempre il gruppo Admin che conterrà gli utenti amministratori al posto di assegnare i permessi direttamente agli utenti. In futuro questa scelta tornerà utile se si deve modificare i pemessi di un utente o eliminarlo. Inoltre offre il vantaggio di avere subito una chiara visione di chi sono gli amministratori dell’organizzazione.

Nel menu User groups, sotto Access management selezionare User groups, è possibile vedere l’elenco dei gruppi creati, i relativi membri e le policy associate al gruppo. Si può associare più policy a un gruppo ma si sconsiglia (salvo alcune eccezzioni) di farlo. Associare più policy può facilmente far perdere la percezione dei permessi assegnati agli utenti.



Nella dashboard di IAM è possibile configurare un alias per il login. Impostare un alias al posto del codice numerico consentirà di creare un link personalizzato e più semplice da ricordare. Modificando l’alias non funzionerà più il link vecchio e tutti gli utenti dovranno usare il link nuovo.



Le policy in AWS sono dei file JSON che contengono le impostazioni dei permessi.

Esempio di una policy:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
{
  "Version": "2012-10-17",
  "Id": "S3-Account-Permission",
  "Statement": [
    {
      "Sid": "1",
      "Effect": "Allow",
      "Principal": {
        "AWS": ["arn:aws:iam::123456789012:root"]
      },
      "Action": [
        "s3:GetObject",
        "s3:PutObject"
      ],
      "Resource": ["arn:aws:s3:::mybucket/*"]
    }
  ]
}

Le pocicy sono sempre costituite dai seguenti paramentri:

  1. Version: la versione della policy, include sempre “2012-10-17”.
  2. Id: l’identificativo della policy (opzionale).
  3. Statement: una o più dichiarazioni, sono i permessi contenuti nella policy. Lo statement è composta da:
    1. Sid: un identificatore le lo statement (opzionale).
    2. Effect: l’effetto della policy, ovvero se consente o nega un accesso. (può solo essere Allow o Deny).
    3. Principal: account/user/role a cui la policy è applicata.
    4. Action: lista delle azioni che la policy attiva o disattiva.
    5. Resource list: lista delle risorse a cui la policy viene applicata.
    6. Condition: condizione in cui la policy viene applicata (opzionale)


Per aggiungere un gruppo a un utente ci sono due modi:

  1. Aggiungere il gruppo partendo dai gruppi: andare su Users Group, selezionare il gruppo corretto e cliccare su Add users.
  2. Aggiungere l’utente partendo dall'utente: andare su Users, selezionare l’utente. Quando si apre la scheda dell’utente andare su Groups e cliccare su Add users to groups.


Alcuni servizi hanno la necessità di compiere azioni su al di fuori del loro ambito. Per faro occore assegnazione ai servizi i permessi per accedere ad altri servizi di AWS.

Alcuni esempio sono:

  1. EC2 Instance Roles
  2. Lamda Function Roles
  3. Role for CloudFormation

Per accedere alla configurazioni dei ruoli andare sulla console di IAM, nel menù Access Management selezionare Roles e Create role.

Esempio di un role per EC2

Esempio di un ruolo per una istanza EC2

  1. Creo un nuovo ruolo
  2. Seleziono il tipo di entity: “AWS Service
  3. Selezioni il use case: “EC2” e click su next.
  4. Seleziono la policy da assegnare: “IAMReadOnlyAccess” e click su next
  5. Asseno il nome al Role : “DemoRoleForEC2” e click su Create Role


Da IAM è possibile generare un report che indica dati di generali e di sicurezza relativi agli utenti. Per generare il report andare su IAM, nel menù di sinistra e selezionare Credential Report.

Per avere informazioni più dettagliate degli utenti è possibile andare nel menù di sinistra, nella sezione Access Management, selezionare Users, selezionare l’utente di cui si vogliono avere maggiori dettagli. Nella scheda dell’utente andare su Access Advisor per visualizzare gli accessi eseguiti dall’utente ai vari servizi. Viene salvato uno storico di 365 giorni.

AIM Best practice
Per applicare il princio “The least privilege principle” può essere molto utile andare periodicamente nella sezione “Access Advisor” e verificare quali serivizi non sono utilizzati dagli utenti e rimuoverne i permessi.


Raccolta delle principali best practice di IAM

  1. Non usare l’account root fatto salvo per il setup iniziale.
  2. Un utente fisico = un utente di AWS. Non convididere mai gli account tra più persone.
  3. Assegna gli utenti ai gruppi e assegna i permessi ai gruppi. È meglio non assegnare mai i permessi direttamente agli utenti.
  4. Creare una password policy forte per garantire che tutti gli utenti abbiano password sufficientemente effici.
  5. Se possibile implementa la Multi Factor Authentication (MFA).
  6. Crea e usa i Ruoli per dare i permessi ai servizi di AWS.
  7. Usa le chiavi di accesso per gli accessi tramite CLI/SKD e matienile il più segrete possibile.
  8. Controllare i permessi degli utenti con Credential report e IAM Access Analyzer.
  9. Non condividere mai l’accounbt IAM e le chiavi di accesso.


Con l’infrastruttura di AWS è possibile interagire tramite console installando la AWS CLI version 2.

Per utitlizzare la CLI occore generare una security credential dall’interfaccia di AWS.

Security credential

Non generare mai security credetial con l’account root, farlo creerebbe un potenziale rischio.

Generare solo security credential di Utenti IAM



Comando Descrizione
aws iam list-users Restituisce l’elenco degli utenti di IAM
Attributo Descrizione
–region “nomeregion” Specifica a quale region si riferisce il comando


In alcune regioni è disponibile la CloudShell. La lista completa è disponibile qui.

Nella CloudShell si possono eseguire tutti i comandi della CLI. La AWS CLI v2 è già preinstallata.

I file creati sono persinstenti, anche riavviando la console non vengono cancellati. È inoltre possibile fare il download/upload dei file direttamente nella console.

Il controllo dei costi è fondamentale quando si lavora con AWS. Il servizio AWS Budgets permette di monitorare e controllare la spesa in tempo reale.

  1. Accedere al servizio Budget:

    • Dalla console AWS, cercare “Budget” o andare su “Billing and Cost Management”
    • Selezionare “Budgets” dal menu laterale
  2. Configurare il Budget:

    1
    2
    3
    4
    
    Budget Type: Cost budget
    Budget Name: Monthly-Budget-$10
    Budgeted Amount: $10 USD
    Time Period: Monthly
    
  3. Impostare gli Alerts:

    • 80% del budget: Alert via email quando si raggiunge l'80% ($8)
    • 100% del budget: Alert quando si supera il budget ($10)
    • Forecasted 100%: Alert quando AWS prevede il superamento
Importante sui costi
  • AWS ha un Free Tier valido 12 mesi dalla registrazione
  • Alcuni servizi hanno limiti gratuiti permanenti
  • Sempre configurare budget alerts per evitare sorprese
  • Monitorare regolarmente il Cost Explorer

AWS fornisce un dashboard dedicato per monitorare l’utilizzo del Free Tier:

  • Servizi inclusi: EC2, S3, RDS, Lambda e molti altri
  • Limiti mensili: Ogni servizio ha limiti specifici (es. 750 ore EC2 t2.micro)
  • Notifications: Alert automatici quando ci si avvicina ai limiti

AWS offre centinaia di servizi, ma alcuni sono fondamentali per iniziare. Ecco una panoramica dei servizi più importanti organizzati per categoria.

EC2 fornisce capacità di calcolo scalabile nel cloud AWS.

Caratteristiche principali:

  • Instance Types: Diversi tipi ottimizzati per compute, memoria, storage
  • AMI (Amazon Machine Images): Template pre-configurati per le istanze
  • Elastic IP: Indirizzi IP statici per le istanze
  • Security Groups: Firewall virtuale per controllare il traffico

Esempio di lancio istanza:

1
2
3
4
5
6
7
# Lanciare un'istanza t2.micro con AWS CLI
aws ec2 run-instances \
    --image-id ami-0abcdef1234567890 \
    --count 1 \
    --instance-type t2.micro \
    --key-name MyKeyPair \
    --security-group-ids sg-903004f8

Servizio di compute serverless che esegue codice senza gestire server.

Vantaggi:

  • Pay per execution: Paghi solo per il tempo di esecuzione
  • Auto-scaling: Scala automaticamente in base alla domanda
  • Event-driven: Può essere attivato da eventi di altri servizi AWS

Servizio di object storage scalabile e duraturo.

Storage Classes:

  • S3 Standard: Per dati acceduti frequentemente
  • S3 IA (Infrequent Access): Per dati acceduti raramente
  • S3 Glacier: Per archiviazione a lungo termine
  • S3 Glacier Deep Archive: Per archiviazione ultra-economica

Esempio di utilizzo:

1
2
3
4
5
6
7
8
# Creare un bucket S3
aws s3 mb s3://my-unique-bucket-name-2024

# Caricare un file
aws s3 cp myfile.txt s3://my-unique-bucket-name-2024/

# Sincronizzare una directory
aws s3 sync ./my-folder s3://my-unique-bucket-name-2024/folder/

Storage a blocchi persistente per istanze EC2.

Tipi di volumi:

  • gp3/gp2: SSD general purpose
  • io2/io1: SSD ad alte performance
  • st1: HDD throughput optimized
  • sc1: HDD cold storage

Database relazionale gestito che supporta MySQL, PostgreSQL, Oracle, SQL Server, MariaDB.

Vantaggi:

  • Backup automatici: Backup giornalieri con point-in-time recovery
  • Multi-AZ: Replica sincrona per alta disponibilità
  • Read Replicas: Replica asincrona per migliorare le performance di lettura
  • Patch automatiche: Aggiornamenti gestiti da AWS

Database NoSQL completamente gestito con performance consistenti.

Caratteristiche:

  • Serverless: Non richiede gestione dell’infrastruttura
  • Auto-scaling: Scala automaticamente in base al carico
  • Global Tables: Replica multi-regione
  • DAX: Cache in-memory per microsecond latency

Rete virtuale isolata dove lanciare le risorse AWS.

Componenti principali:

  • Subnets: Segmentano la VPC in sottoreti pubbliche e private
  • Internet Gateway: Permette l’accesso a Internet
  • NAT Gateway: Consente alle istanze private di accedere a Internet
  • Route Tables: Definiscono le regole di routing

Esempio di architettura VPC:

1
2
3
4
5
6
7
VPC (10.0.0.0/16)
├── Public Subnet (10.0.1.0/24)
│   ├── Internet Gateway
│   └── Web Servers
└── Private Subnet (10.0.2.0/24)
    ├── NAT Gateway
    └── Database Servers

Content Delivery Network (CDN) globale per distribuire contenuti con bassa latenza.

Benefici:

  • Edge Locations: 400+ punti di presenza globali
  • Cache: Riduce il carico sui server origin
  • SSL/TLS: Certificati gratuiti tramite AWS Certificate Manager
  • Lambda@Edge: Esegue codice ai margini della rete

Protegge le applicazioni web da exploit comuni.

Protezioni:

  • SQL Injection: Blocca tentativi di SQL injection
  • XSS: Previene cross-site scripting
  • Rate Limiting: Limita le richieste per IP
  • Geo-blocking: Blocca traffico da specifiche regioni

Protezione DDoS gestita per applicazioni AWS.

Livelli:

  • Shield Standard: Protezione base gratuita per tutti i clienti AWS
  • Shield Advanced: Protezione avanzata con supporto 24/7 e protezione costi
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "s3:GetObject"
      ],
      "Resource": "arn:aws:s3:::specific-bucket/*"
    }
  ]
}
  • Abilitare MFA per tutti gli utenti, specialmente admin
  • Utilizzare hardware MFA per account critici
  • Virtual MFA per utenti standard (Google Authenticator, Authy)
  • Encryption at Rest: Utilizzare KMS per crittografare dati su S3, RDS, EBS
  • Encryption in Transit: Sempre HTTPS/TLS per comunicazioni
  • Client-side Encryption: Crittografare dati prima di inviarli ad AWS
1
2
3
4
5
6
7
8
9
# Monitorare l'utilizzo delle istanze
aws cloudwatch get-metric-statistics \
    --namespace AWS/EC2 \
    --metric-name CPUUtilization \
    --dimensions Name=InstanceId,Value=i-1234567890abcdef0 \
    --start-time 2024-01-01T00:00:00Z \
    --end-time 2024-01-02T00:00:00Z \
    --period 3600 \
    --statistics Average
  • Reserved Instances: Fino al 75% di sconto per commitment 1-3 anni
  • Savings Plans: Flessibilità maggiore con sconti simili
  • Spot Instances: Fino al 90% di sconto per workload fault-tolerant
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
{
  "Rules": [
    {
      "Status": "Enabled",
      "Transitions": [
        {
          "Days": 30,
          "StorageClass": "STANDARD_IA"
        },
        {
          "Days": 90,
          "StorageClass": "GLACIER"
        }
      ]
    }
  ]
}

Servizio di monitoraggio per risorse e applicazioni AWS.

Metriche principali:

  • EC2: CPU, Disk, Network utilization
  • RDS: Database connections, CPU, freeable memory
  • S3: Number of objects, bucket size bytes
  • Lambda: Invocations, duration, errors

Registra tutte le API call per audit e compliance.

Informazioni tracciate:

  • Chi: Quale utente/servizio ha fatto l’azione
  • Cosa: Quale API è stata chiamata
  • Quando: Timestamp preciso dell’azione
  • Da dove: IP address e user agent
  1. Backup and Restore (RTO: ore, RPO: ore)

    • Backup regolari su S3
    • Restore quando necessario
  2. Pilot Light (RTO: 10 minuti, RPO: minuti)

    • Core infrastructure sempre attiva
    • Scale-up durante disaster
  3. Warm Standby (RTO: minuti, RPO: minuti)

    • Ambiente ridotto sempre attivo
    • Scale-out durante disaster
  4. Multi-Site Active/Active (RTO: secondi, RPO: zero)

    • Ambiente completo in multiple regioni
    • Traffico distribuito normalmente

Certificazione entry-level che copre:

  • Cloud concepts: Vantaggi del cloud, modelli di deployment
  • AWS services: Panoramica dei servizi principali
  • Security: Best practices di sicurezza
  • Pricing: Modelli di prezzo e supporto

Certificazione per architetti che copre:

  • Design resilient architectures: HA, fault tolerance
  • Performance: Auto Scaling, caching, database optimization
  • Security: Encryption, compliance, network security
  • Cost optimization: Right-sizing, Reserved Instances
  • AWS Training and Certification: Corsi ufficiali gratuiti e a pagamento
  • AWS Hands-on Labs: Laboratori pratici guidati
  • AWS Well-Architected Labs: Best practices implementabili
  • AWS User Groups: Meetup locali con altri utenti AWS
  • AWS re:Invent: Conferenza annuale con migliaia di sessioni
  • AWS Summits: Eventi regionali gratuiti

AWS rappresenta una piattaforma completa per ogni tipo di workload, dalla semplice pagina web statica alle applicazioni enterprise più complesse. Questa guida ti ha fornito le basi teoriche e pratiche per iniziare il tuo percorso con AWS.

  1. Hands-on Practice:

    • Crea il tuo account AWS e sperimenta con il Free Tier
    • Segui i tutorials AWS per implementare architetture comuni
  2. Approfondimenti:

    • Studia servizi specifici per il tuo use case (machine learning, analytics, IoT)
    • Impara Infrastructure as Code con CloudFormation o CDK
  3. Certificazioni:

    • Inizia con AWS Cloud Practitioner
    • Prosegui con certificazioni role-based (Solutions Architect, Developer, SysOps)
  4. Community:

    • Partecipa agli AWS User Groups della tua città
    • Segui il blog ufficiale AWS per rimanere aggiornato
Risorse Gratuite
  • AWS Free Tier: 12 mesi di servizi gratuiti per nuovi account
  • AWS Educate: Programma per studenti e educatori
  • AWS Training: Centinaia di corsi digitali gratuiti
  • AWS Architecture Center: Pattern e best practices

Servizio completamente gestito per eseguire container Docker su AWS.

Modalità di Launch:

  • EC2 Launch Type: Container su istanze EC2 che gestisci tu
  • Fargate Launch Type: Serverless, AWS gestisce l’infrastruttura
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
{
  "family": "sample-app",
  "taskRoleArn": "arn:aws:iam::123456789012:role/ecsTaskRole",
  "executionRoleArn": "arn:aws:iam::123456789012:role/ecsTaskExecutionRole",
  "networkMode": "awsvpc",
  "requiresCompatibilities": ["FARGATE"],
  "cpu": "256",
  "memory": "512",
  "containerDefinitions": [
    {
      "name": "sample-app",
      "image": "httpd:2.4",
      "portMappings": [
        {
          "containerPort": 80,
          "protocol": "tcp"
        }
      ],
      "essential": true,
      "logConfiguration": {
        "logDriver": "awslogs",
        "options": {
          "awslogs-group": "/ecs/sample-app",
          "awslogs-region": "us-east-1",
          "awslogs-stream-prefix": "ecs"
        }
      }
    }
  ]
}

Kubernetes gestito su AWS.

Componenti principali:

  • Control Plane: Gestito da AWS (API server, etcd, scheduler)
  • Worker Nodes: Istanze EC2 o Fargate che eseguono i pod
  • Add-ons: CoreDNS, kube-proxy, Amazon VPC CNI
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
# Creare cluster EKS con eksctl
eksctl create cluster \
  --name my-cluster \
  --version 1.27 \
  --region us-east-1 \
  --nodegroup-name standard-workers \
  --node-type t3.medium \
  --nodes 3 \
  --nodes-min 1 \
  --nodes-max 4

# Deploy applicazione
kubectl apply -f - <<EOF
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.21
        ports:
        - containerPort: 80
EOF

Compute engine serverless per container.

Vantaggi:

  • No server management: Non gestisci istanze EC2
  • Pay per use: Paghi solo per vCPU e memoria utilizzati
  • Security: Isolamento a livello di kernel
  • Integration: Funziona con ECS e EKS
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
# Lambda function per processing S3 eventi
import json
import boto3
from urllib.parse import unquote_plus

s3_client = boto3.client('s3')

def lambda_handler(event, context):
    """Process S3 upload events"""

    for record in event['Records']:
        bucket = record['s3']['bucket']['name']
        key = unquote_plus(record['s3']['object']['key'])

        print(f"Processing file: {key} in bucket: {bucket}")

        # Download file
        download_path = f'/tmp/{key}'
        s3_client.download_file(bucket, key, download_path)

        # Process file (example: image resize, data validation, etc.)
        processed_result = process_file(download_path)

        # Upload processed file
        output_key = f"processed/{key}"
        s3_client.upload_file(processed_result, bucket, output_key)

    return {
        'statusCode': 200,
        'body': json.dumps('Successfully processed files')
    }

def process_file(file_path):
    """Your processing logic here"""
    # Image processing, data transformation, etc.
    return file_path  # Return path to processed file
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
# Creare Lambda Layer
mkdir python
pip install requests -t python/
zip -r requests-layer.zip python/

# Deploy layer
aws lambda publish-layer-version \
    --layer-name requests-layer \
    --description "Requests library for Lambda" \
    --zip-file fileb://requests-layer.zip \
    --compatible-runtimes python3.9 python3.10

Servizio completamente gestito per creare, pubblicare e gestire API REST e WebSocket.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
# SAM template per API Gateway + Lambda
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31

Resources:
  MyApi:
    Type: AWS::Serverless::Api
    Properties:
      StageName: prod
      Cors:
        AllowMethods: "'GET,POST,PUT,DELETE'"
        AllowHeaders: "'Content-Type,X-Amz-Date,Authorization'"
        AllowOrigin: "'*'"

  GetUserFunction:
    Type: AWS::Serverless::Function
    Properties:
      CodeUri: src/
      Handler: users.get_user
      Runtime: python3.9
      Events:
        GetUser:
          Type: Api
          Properties:
            RestApiId: !Ref MyApi
            Path: /users/{id}
            Method: get

  CreateUserFunction:
    Type: AWS::Serverless::Function
    Properties:
      CodeUri: src/
      Handler: users.create_user
      Runtime: python3.9
      Events:
        CreateUser:
          Type: Api
          Properties:
            RestApiId: !Ref MyApi
            Path: /users
            Method: post

Orchestrazione di workflow serverless.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
{
  "Comment": "E-commerce order processing workflow",
  "StartAt": "ValidateOrder",
  "States": {
    "ValidateOrder": {
      "Type": "Task",
      "Resource": "arn:aws:lambda:us-east-1:123456789012:function:ValidateOrder",
      "Next": "CheckInventory",
      "Catch": [
        {
          "ErrorEquals": ["ValidationError"],
          "Next": "OrderValidationFailed"
        }
      ]
    },
    "CheckInventory": {
      "Type": "Task",
      "Resource": "arn:aws:lambda:us-east-1:123456789012:function:CheckInventory",
      "Next": "ProcessPayment",
      "Catch": [
        {
          "ErrorEquals": ["OutOfStockError"],
          "Next": "NotifyOutOfStock"
        }
      ]
    },
    "ProcessPayment": {
      "Type": "Task",
      "Resource": "arn:aws:lambda:us-east-1:123456789012:function:ProcessPayment",
      "Next": "FulfillOrder",
      "Catch": [
        {
          "ErrorEquals": ["PaymentError"],
          "Next": "PaymentFailed"
        }
      ]
    },
    "FulfillOrder": {
      "Type": "Task",
      "Resource": "arn:aws:lambda:us-east-1:123456789012:function:FulfillOrder",
      "End": true
    },
    "OrderValidationFailed": {
      "Type": "Fail",
      "Cause": "Order validation failed"
    },
    "NotifyOutOfStock": {
      "Type": "Task",
      "Resource": "arn:aws:lambda:us-east-1:123456789012:function:NotifyOutOfStock",
      "End": true
    },
    "PaymentFailed": {
      "Type": "Task",
      "Resource": "arn:aws:lambda:us-east-1:123456789012:function:HandlePaymentFailure",
      "End": true
    }
  }
}

Servizio per provisioning dell’infrastruttura utilizzando template.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
AWSTemplateFormatVersion: '2010-09-09'
Description: 'Complete web application stack with VPC, ALB, EC2, RDS'

Parameters:
  EnvironmentName:
    Description: Environment name prefix
    Type: String
    Default: Production

  InstanceType:
    Description: EC2 instance type
    Type: String
    Default: t3.micro
    AllowedValues: [t3.micro, t3.small, t3.medium]

Resources:
  # VPC and Networking
  VPC:
    Type: AWS::EC2::VPC
    Properties:
      CidrBlock: 10.0.0.0/16
      EnableDnsHostnames: true
      EnableDnsSupport: true
      Tags:
        - Key: Name
          Value: !Sub ${EnvironmentName}-VPC

  InternetGateway:
    Type: AWS::EC2::InternetGateway
    Properties:
      Tags:
        - Key: Name
          Value: !Sub ${EnvironmentName}-IGW

  InternetGatewayAttachment:
    Type: AWS::EC2::VPCGatewayAttachment
    Properties:
      InternetGatewayId: !Ref InternetGateway
      VpcId: !Ref VPC

  PublicSubnet1:
    Type: AWS::EC2::Subnet
    Properties:
      VpcId: !Ref VPC
      AvailabilityZone: !Select [0, !GetAZs '']
      CidrBlock: 10.0.1.0/24
      MapPublicIpOnLaunch: true
      Tags:
        - Key: Name
          Value: !Sub ${EnvironmentName}-Public-Subnet-AZ1

  PublicSubnet2:
    Type: AWS::EC2::Subnet
    Properties:
      VpcId: !Ref VPC
      AvailabilityZone: !Select [1, !GetAZs '']
      CidrBlock: 10.0.2.0/24
      MapPublicIpOnLaunch: true
      Tags:
        - Key: Name
          Value: !Sub ${EnvironmentName}-Public-Subnet-AZ2

  PrivateSubnet1:
    Type: AWS::EC2::Subnet
    Properties:
      VpcId: !Ref VPC
      AvailabilityZone: !Select [0, !GetAZs '']
      CidrBlock: 10.0.3.0/24
      Tags:
        - Key: Name
          Value: !Sub ${EnvironmentName}-Private-Subnet-AZ1

  PrivateSubnet2:
    Type: AWS::EC2::Subnet
    Properties:
      VpcId: !Ref VPC
      AvailabilityZone: !Select [1, !GetAZs '']
      CidrBlock: 10.0.4.0/24
      Tags:
        - Key: Name
          Value: !Sub ${EnvironmentName}-Private-Subnet-AZ2

  # Security Groups
  WebServerSecurityGroup:
    Type: AWS::EC2::SecurityGroup
    Properties:
      GroupDescription: Security group for web servers
      VpcId: !Ref VPC
      SecurityGroupIngress:
        - IpProtocol: tcp
          FromPort: 80
          ToPort: 80
          SourceSecurityGroupId: !Ref ALBSecurityGroup
        - IpProtocol: tcp
          FromPort: 22
          ToPort: 22
          CidrIp: 10.0.0.0/16

  ALBSecurityGroup:
    Type: AWS::EC2::SecurityGroup
    Properties:
      GroupDescription: Security group for Application Load Balancer
      VpcId: !Ref VPC
      SecurityGroupIngress:
        - IpProtocol: tcp
          FromPort: 80
          ToPort: 80
          CidrIp: 0.0.0.0/0
        - IpProtocol: tcp
          FromPort: 443
          ToPort: 443
          CidrIp: 0.0.0.0/0

  DatabaseSecurityGroup:
    Type: AWS::EC2::SecurityGroup
    Properties:
      GroupDescription: Security group for RDS database
      VpcId: !Ref VPC
      SecurityGroupIngress:
        - IpProtocol: tcp
          FromPort: 3306
          ToPort: 3306
          SourceSecurityGroupId: !Ref WebServerSecurityGroup

  # Application Load Balancer
  ApplicationLoadBalancer:
    Type: AWS::ElasticLoadBalancingV2::LoadBalancer
    Properties:
      Scheme: internet-facing
      SecurityGroups:
        - !Ref ALBSecurityGroup
      Subnets:
        - !Ref PublicSubnet1
        - !Ref PublicSubnet2
      Type: application

  # Auto Scaling Group
  LaunchTemplate:
    Type: AWS::EC2::LaunchTemplate
    Properties:
      LaunchTemplateName: !Sub ${EnvironmentName}-LaunchTemplate
      LaunchTemplateData:
        ImageId: ami-0c55b159cbfafe1d0  # Amazon Linux 2
        InstanceType: !Ref InstanceType
        SecurityGroupIds:
          - !Ref WebServerSecurityGroup
        UserData:
          Fn::Base64: !Sub |
            #!/bin/bash
            yum update -y
            yum install -y httpd
            systemctl start httpd
            systemctl enable httpd
            echo "<h1>Hello from ${EnvironmentName}!</h1>" > /var/www/html/index.html

  AutoScalingGroup:
    Type: AWS::AutoScaling::AutoScalingGroup
    Properties:
      VPCZoneIdentifier:
        - !Ref PrivateSubnet1
        - !Ref PrivateSubnet2
      LaunchTemplate:
        LaunchTemplateId: !Ref LaunchTemplate
        Version: !GetAtt LaunchTemplate.LatestVersionNumber
      MinSize: 1
      MaxSize: 6
      DesiredCapacity: 2
      TargetGroupARNs:
        - !Ref TargetGroup

  # RDS Database
  DBSubnetGroup:
    Type: AWS::RDS::DBSubnetGroup
    Properties:
      DBSubnetGroupDescription: Subnet group for RDS database
      SubnetIds:
        - !Ref PrivateSubnet1
        - !Ref PrivateSubnet2

  Database:
    Type: AWS::RDS::DBInstance
    Properties:
      DBInstanceIdentifier: !Sub ${EnvironmentName}-database
      DBInstanceClass: db.t3.micro
      Engine: mysql
      MasterUsername: admin
      MasterUserPassword: !Ref DatabasePassword
      AllocatedStorage: 20
      VPCSecurityGroups:
        - !Ref DatabaseSecurityGroup
      DBSubnetGroupName: !Ref DBSubnetGroup
      MultiAZ: false
      PubliclyAccessible: false

Outputs:
  LoadBalancerDNS:
    Description: DNS name of the load balancer
    Value: !GetAtt ApplicationLoadBalancer.DNSName
    Export:
      Name: !Sub ${EnvironmentName}-ALB-DNS

  DatabaseEndpoint:
    Description: RDS instance endpoint
    Value: !GetAtt Database.Endpoint.Address
    Export:
      Name: !Sub ${EnvironmentName}-DB-Endpoint

Framework per definire infrastruttura cloud utilizzando linguaggi di programmazione.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
from aws_cdk import (
    aws_ec2 as ec2,
    aws_ecs as ecs,
    aws_ecs_patterns as ecs_patterns,
    aws_rds as rds,
    core
)

class WebAppStack(core.Stack):
    def __init__(self, scope: core.Construct, construct_id: str, **kwargs) -> None:
        super().__init__(scope, construct_id, **kwargs)

        # VPC
        vpc = ec2.Vpc(
            self, "WebAppVPC",
            max_azs=2,
            nat_gateways=1
        )

        # ECS Cluster
        cluster = ecs.Cluster(
            self, "WebAppCluster",
            vpc=vpc
        )

        # Fargate Service with ALB
        fargate_service = ecs_patterns.ApplicationLoadBalancedFargateService(
            self, "WebAppService",
            cluster=cluster,
            memory_limit_mib=512,
            cpu=256,
            task_image_options=ecs_patterns.ApplicationLoadBalancedTaskImageOptions(
                image=ecs.ContainerImage.from_registry("nginx:latest"),
                container_port=80
            ),
            desired_count=2,
            public_load_balancer=True
        )

        # RDS Database
        database = rds.DatabaseInstance(
            self, "WebAppDB",
            engine=rds.DatabaseInstanceEngine.mysql(
                version=rds.MysqlEngineVersion.VER_8_0_28
            ),
            instance_type=ec2.InstanceType.of(
                ec2.InstanceClass.T3,
                ec2.InstanceSize.MICRO
            ),
            vpc=vpc,
            multi_az=False,
            allocated_storage=20,
            deletion_protection=False
        )

        # Allow connections from Fargate to RDS
        database.connections.allow_from(
            fargate_service.service,
            ec2.Port.tcp(3306)
        )

        # Output the load balancer URL
        core.CfnOutput(
            self, "LoadBalancerDNS",
            value=fargate_service.load_balancer.load_balancer_dns_name
        )

app = core.App()
WebAppStack(app, "WebAppStack")
app.synth()

Servizio di continuous integration e continuous delivery (CI/CD).

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
# CodePipeline per deploy applicazione Node.js
Resources:
  CodePipeline:
    Type: AWS::CodePipeline::Pipeline
    Properties:
      RoleArn: !GetAtt CodePipelineRole.Arn
      ArtifactStore:
        Type: S3
        Location: !Ref ArtifactBucket
      Stages:
        - Name: Source
          Actions:
            - Name: SourceAction
              ActionTypeId:
                Category: Source
                Owner: ThirdParty
                Provider: GitHub
                Version: '1'
              Configuration:
                Owner: myusername
                Repo: my-node-app
                Branch: main
                OAuthToken: !Ref GitHubToken
              OutputArtifacts:
                - Name: SourceOutput

        - Name: Build
          Actions:
            - Name: BuildAction
              ActionTypeId:
                Category: Build
                Owner: AWS
                Provider: CodeBuild
                Version: '1'
              Configuration:
                ProjectName: !Ref CodeBuildProject
              InputArtifacts:
                - Name: SourceOutput
              OutputArtifacts:
                - Name: BuildOutput

        - Name: Deploy
          Actions:
            - Name: DeployAction
              ActionTypeId:
                Category: Deploy
                Owner: AWS
                Provider: ECS
                Version: '1'
              Configuration:
                ClusterName: !Ref ECSCluster
                ServiceName: !Ref ECSService
                FileName: imagedefinitions.json
              InputArtifacts:
                - Name: BuildOutput

  CodeBuildProject:
    Type: AWS::CodeBuild::Project
    Properties:
      ServiceRole: !GetAtt CodeBuildRole.Arn
      Artifacts:
        Type: CODEPIPELINE
      Environment:
        Type: LINUX_CONTAINER
        ComputeType: BUILD_GENERAL1_SMALL
        Image: aws/codebuild/amazonlinux2-x86_64-standard:3.0
        EnvironmentVariables:
          - Name: AWS_DEFAULT_REGION
            Value: !Ref AWS::Region
          - Name: AWS_ACCOUNT_ID
            Value: !Ref AWS::AccountId
          - Name: IMAGE_REPO_NAME
            Value: !Ref ECRRepository
      Source:
        Type: CODEPIPELINE
        BuildSpec: |
          version: 0.2
          phases:
            pre_build:
              commands:
                - echo Logging in to Amazon ECR...
                - aws ecr get-login-password --region $AWS_DEFAULT_REGION | docker login --username AWS --password-stdin $AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com
            build:
              commands:
                - echo Build started on `date`
                - echo Building the Docker image...
                - docker build -t $IMAGE_REPO_NAME:$IMAGE_TAG .
                - docker tag $IMAGE_REPO_NAME:$IMAGE_TAG $AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com/$IMAGE_REPO_NAME:$IMAGE_TAG
            post_build:
              commands:
                - echo Build completed on `date`
                - echo Pushing the Docker image...
                - docker push $AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com/$IMAGE_REPO_NAME:$IMAGE_TAG
                - printf '[{"name":"web","imageUri":"%s"}]' $AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com/$IMAGE_REPO_NAME:$IMAGE_TAG > imagedefinitions.json
          artifacts:
            files:
              - imagedefinitions.json          

Stack completo per CI/CD nativo AWS.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
# Setup repository CodeCommit
aws codecommit create-repository --repository-name my-app
git clone https://git-codecommit.us-east-1.amazonaws.com/v1/repos/my-app

# buildspec.yml per CodeBuild
cat > buildspec.yml << EOF
version: 0.2
phases:
  install:
    runtime-versions:
      nodejs: 16
  pre_build:
    commands:
      - npm install
      - npm run test
  build:
    commands:
      - npm run build
  post_build:
    commands:
      - echo Build completed
artifacts:
  files:
    - '**/*'
  name: myapp-build-artifact
EOF

# appspec.yml per CodeDeploy
cat > appspec.yml << EOF
version: 0.0
os: linux
files:
  - source: /
    destination: /var/www/html
hooks:
  BeforeInstall:
    - location: scripts/install_dependencies.sh
      timeout: 300
  ApplicationStart:
    - location: scripts/start_server.sh
      timeout: 300
  ApplicationStop:
    - location: scripts/stop_server.sh
      timeout: 300
EOF

Servizio di threat detection che utilizza machine learning.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
# Enable GuardDuty via AWS SDK
import boto3

guardduty = boto3.client('guardduty')

# Create detector
detector_response = guardduty.create_detector(
    Enable=True,
    FindingPublishingFrequency='FIFTEEN_MINUTES'
)

detector_id = detector_response['DetectorId']

# Configure threat intelligence feeds
guardduty.create_threat_intel_set(
    DetectorId=detector_id,
    Name='CustomThreatIntel',
    Format='TXT',
    Location='s3://my-threat-intel-bucket/threats.txt',
    Activate=True
)

# Setup SNS notification for findings
guardduty.create_filter(
    DetectorId=detector_id,
    Name='HighSeverityFindings',
    Action='ARCHIVE',
    Description='Filter for high severity findings',
    FindingCriteria={
        'Criterion': {
            'severity': {
                'Gte': 7.0
            }
        }
    }
)

Servizio per audit e compliance della configurazione delle risorse.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
{
  "ConfigRuleName": "ec2-security-group-attached-to-eni",
  "Description": "Checks if Amazon Elastic Compute Cloud (Amazon EC2) security groups are attached to Amazon Elastic Network Interfaces (ENIs).",
  "Source": {
    "Owner": "AWS",
    "SourceIdentifier": "EC2_SECURITY_GROUP_ATTACHED_TO_ENI"
  },
  "Scope": {
    "ComplianceResourceTypes": [
      "AWS::EC2::SecurityGroup"
    ]
  }
}

Gestione centralizzata delle istanze EC2 e on-premises.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
# Patch management
aws ssm create-patch-baseline \
    --name "MyPatchBaseline" \
    --operating-system "AMAZON_LINUX_2" \
    --approval-rules 'PatchRules=[{PatchFilterGroup={PatchFilters=[{Key=CLASSIFICATION,Values=[Security,Bugfix,Critical]}]},ApproveAfterDays=0,EnableNonSecurity=false}]'

# Parameter Store
aws ssm put-parameter \
    --name "/myapp/database/password" \
    --value "mySecretPassword" \
    --type "SecureString" \
    --key-id "alias/aws/ssm"

# Run Command
aws ssm send-command \
    --document-name "AWS-RunShellScript" \
    --parameters 'commands=["yum update -y"]' \
    --targets "Key=tag:Environment,Values=Production"

Analisi programmatica dei costi.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
import boto3
from datetime import datetime, timedelta

ce = boto3.client('ce')

# Get cost and usage data
end_date = datetime.now().strftime('%Y-%m-%d')
start_date = (datetime.now() - timedelta(days=30)).strftime('%Y-%m-%d')

response = ce.get_cost_and_usage(
    TimePeriod={
        'Start': start_date,
        'End': end_date
    },
    Granularity='DAILY',
    Metrics=['BlendedCost'],
    GroupBy=[
        {
            'Type': 'DIMENSION',
            'Key': 'SERVICE'
        }
    ]
)

# Analyze top services by cost
services_cost = {}
for result in response['ResultsByTime']:
    for group in result['Groups']:
        service = group['Keys'][0]
        cost = float(group['Metrics']['BlendedCost']['Amount'])
        services_cost[service] = services_cost.get(service, 0) + cost

# Print top 10 services by cost
sorted_services = sorted(services_cost.items(), key=lambda x: x[1], reverse=True)
print("Top 10 Services by Cost:")
for service, cost in sorted_services[:10]:
    print(f"{service}: ${cost:.2f}")
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
# Get Trusted Advisor recommendations
import boto3

support = boto3.client('support', region_name='us-east-1')

# List checks
checks = support.describe_trusted_advisor_checks(language='en')

# Get specific check results (Cost Optimization)
cost_checks = [check for check in checks['checks'] if 'cost' in check['name'].lower()]

for check in cost_checks:
    result = support.describe_trusted_advisor_check_result(
        checkId=check['id'],
        language='en'
    )

    if result['result']['status'] in ['warning', 'error']:
        print(f"Check: {check['name']}")
        print(f"Status: {result['result']['status']}")
        print(f"Resources flagged: {len(result['result']['flaggedResources'])}")

Architettura completa per un e-commerce serverless.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
# SAM Template per E-commerce
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31

Globals:
  Function:
    Runtime: python3.9
    Environment:
      Variables:
        PRODUCTS_TABLE: !Ref ProductsTable
        ORDERS_TABLE: !Ref OrdersTable

Resources:
  # API Gateway
  EcommerceApi:
    Type: AWS::Serverless::Api
    Properties:
      StageName: prod
      Cors:
        AllowMethods: "'*'"
        AllowHeaders: "'*'"
        AllowOrigin: "'*'"

  # DynamoDB Tables
  ProductsTable:
    Type: AWS::DynamoDB::Table
    Properties:
      BillingMode: PAY_PER_REQUEST
      AttributeDefinitions:
        - AttributeName: productId
          AttributeType: S
      KeySchema:
        - AttributeName: productId
          KeyType: HASH

  OrdersTable:
    Type: AWS::DynamoDB::Table
    Properties:
      BillingMode: PAY_PER_REQUEST
      AttributeDefinitions:
        - AttributeName: orderId
          AttributeType: S
        - AttributeName: userId
          AttributeType: S
      KeySchema:
        - AttributeName: orderId
          KeyType: HASH
      GlobalSecondaryIndexes:
        - IndexName: UserIndex
          KeySchema:
            - AttributeName: userId
              KeyType: HASH
          Projection:
            ProjectionType: ALL

  # Lambda Functions
  GetProductsFunction:
    Type: AWS::Serverless::Function
    Properties:
      CodeUri: functions/
      Handler: products.get_products
      Events:
        GetProducts:
          Type: Api
          Properties:
            RestApiId: !Ref EcommerceApi
            Path: /products
            Method: get
      Policies:
        - DynamoDBReadPolicy:
            TableName: !Ref ProductsTable

  CreateOrderFunction:
    Type: AWS::Serverless::Function
    Properties:
      CodeUri: functions/
      Handler: orders.create_order
      Events:
        CreateOrder:
          Type: Api
          Properties:
            RestApiId: !Ref EcommerceApi
            Path: /orders
            Method: post
      Policies:
        - DynamoDBCrudPolicy:
            TableName: !Ref OrdersTable
        - DynamoDBReadPolicy:
            TableName: !Ref ProductsTable

  ProcessOrderFunction:
    Type: AWS::Serverless::Function
    Properties:
      CodeUri: functions/
      Handler: orders.process_order
      Events:
        ProcessOrder:
          Type: DynamoDB
          Properties:
            Stream: !GetAtt OrdersTable.StreamArn
            StartingPosition: LATEST
      Policies:
        - SNSPublishMessagePolicy:
            TopicName: !GetAtt OrderNotifications.TopicName

  # SNS Topic for notifications
  OrderNotifications:
    Type: AWS::SNS::Topic
    Properties:
      Subscription:
        - Endpoint: admin@example.com
          Protocol: email
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
# Lambda function per processing data pipeline
import json
import boto3
import pandas as pd
from io import StringIO

s3 = boto3.client('s3')
athena = boto3.client('athena')

def lambda_handler(event, context):
    """
    Process CSV files uploaded to S3, clean data, and prepare for Athena queries
    """

    bucket = event['Records'][0]['s3']['bucket']['name']
    key = event['Records'][0]['s3']['object']['key']

    # Download CSV file
    obj = s3.get_object(Bucket=bucket, Key=key)
    df = pd.read_csv(obj['Body'])

    # Data cleaning and transformation
    df_clean = clean_data(df)

    # Convert to parquet for better performance
    parquet_buffer = StringIO()
    df_clean.to_parquet(parquet_buffer, index=False)

    # Upload processed data
    processed_key = key.replace('.csv', '.parquet').replace('raw/', 'processed/')
    s3.put_object(
        Bucket=bucket,
        Key=processed_key,
        Body=parquet_buffer.getvalue()
    )

    # Trigger Athena table refresh
    refresh_athena_table(bucket, processed_key)

    return {
        'statusCode': 200,
        'body': json.dumps(f'Successfully processed {key}')
    }

def clean_data(df):
    """Data cleaning logic"""
    # Remove duplicates
    df = df.drop_duplicates()

    # Fill missing values
    df = df.fillna(method='ffill')

    # Standardize column names
    df.columns = [col.lower().replace(' ', '_') for col in df.columns]

    return df

def refresh_athena_table(bucket, key):
    """Update Athena table metadata"""
    query = f"""
    MSCK REPAIR TABLE sales_data
    """

    athena.start_query_execution(
        QueryString=query,
        ResultConfiguration={
            'OutputLocation': f's3://{bucket}/athena-results/'
        }
    )
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
#!/bin/bash
# Deploy script per applicazione multi-tier

# 1. Deploy VPC e Networking
aws cloudformation deploy \
  --template-file infrastructure/vpc.yaml \
  --stack-name webapp-vpc \
  --parameter-overrides EnvironmentName=Production

# 2. Deploy Database Layer
aws cloudformation deploy \
  --template-file infrastructure/database.yaml \
  --stack-name webapp-db \
  --parameter-overrides \
    VpcStackName=webapp-vpc \
    DBPassword=$DB_PASSWORD

# 3. Deploy Application Layer
aws cloudformation deploy \
  --template-file infrastructure/application.yaml \
  --stack-name webapp-app \
  --parameter-overrides \
    VpcStackName=webapp-vpc \
    DatabaseStackName=webapp-db \
    KeyName=$EC2_KEY_PAIR

# 4. Deploy CDN e DNS
aws cloudformation deploy \
  --template-file infrastructure/cdn.yaml \
  --stack-name webapp-cdn \
  --parameter-overrides \
    ApplicationStackName=webapp-app \
    DomainName=$DOMAIN_NAME \
    CertificateArn=$SSL_CERTIFICATE_ARN

echo "Deployment completed. Application available at:"
aws cloudformation describe-stacks \
  --stack-name webapp-cdn \
  --query 'Stacks[0].Outputs[?OutputKey==`DistributionDomainName`].OutputValue' \
  --output text

Il cloud computing e AWS in particolare continuano ad evolversi rapidamente. La chiave del successo è mantenere un approccio di apprendimento continuo, sperimentare regolarmente con nuovi servizi e rimanere aggiornati sulle best practices della community.

Buon viaggio nel mondo AWS! ☁️🚀