Il servizio CloudFront è studiato per distribuire contenuti in modo sicuro ad alta velocità, i suoi caso d’uso più comuni sono l’esposizione di un sito web statico, trasmissione di video in streaming e distribuzione di software e aggiornamenti a grandi dimensioni di client. Il servizio è proprio pensato e studiato per condividere dal Cloud oggetti in tutto il mondo attraverso le zone geografica (AZ) e gli Edge di distribuzione risultando integrato con il servizio di firewall (WAF) che garantisce la sicurezza e la gestione della cache ottimizzata proprio per migliorare ulteriormente le performance e diminuire il traffico tra CloudFormation e la sorgente.
Per Edge si intendono i punti di connessione gestiti da AWS:
Il suo funzionamento è descritto dall’immagine del sito ufficiale:
Il servizio non è gratuito ma prevede un piano gratuito senza limiti di tempo con 1 TB di trasferimento dati su Internet al mese, 10.000.000 richieste HTTP/HTTPS al mese e 2.000.000 chiamate di CloudFront Function al mese. Nel sito ufficiale è disponibile una guida che spiega i passi per condividere un sito web statico salvati in bucket S3 e esposto con CloudFront, i passi descritti in questo esempio sono:
- creazione di un bucket contenente il sito statico
- creazione della distrubuzione CloudFront configurando il “Origin Domain Name” cioè il bucket S3 sorgente dei contenuti da distribuire
- creazione dalla regola “Origin Access Control” indispensabile per permettere alla distribuzione di accedere al contenuto nel Bucket, senza questa regola la distribuzione otterrà un brutto errore HTTP di tipo 403 (Forbiden – accesso negato)
- configurazione della cache “default cache behavior”
- configurazione delle regole di rete come la gestione del HTTP/HTTPS, il certificato TLS/TTL, un certificato SSL e la configurazione di un firewall tramite il servizio WAF
La distribuzione creata ha sempre come endpoint il tipo xxxxxx.cloudfront.net e da Route53 è possibile creare la regola DNS per puntare a questa distribuzione con un dominio come record A oppure con una regola CNAME. La gestione delle cache è molto evoluta ed ottimizzata in questo servizio, l’invalidazione della cache per il refresh dei contenuti dalla sorgente è chiamata invalidazione della distribuzione ed è un’operazione che può essere eseguita da console o via CLI, si rimanda alla documentazione ufficiale per approfondimenti. Nel blog ufficiale è disponibile una guida per accelerare le prestazioni di un sito WordPress, configurando CloudFront per esporre i media statici del sito in maniera veloce e sicura.
La CLI mette a disposizione una serie di comandi per la gestione delle distribuzioni, si rimanda alla documentazione o ai tanti siti di esempi. I principali comandi sono:
elenco delle distribuzioni:
aws cloudfront list-distributions
elenco delle distribuzioni con solo id e nome:
aws cloudfront list-distributions --output table
--query 'DistributionList.Items[*].[Id,Origins.Items[0].DomainName]'
dettaglio di una singola distribuzione:
aws cloudfront get-distribution --id xxxxxxxxxxxx
creazione e modifica di una distribuzione inserendo i parametri in un file di configurazione:
aws cloudfront create-distribution --distribution-config file://distribution.json
aws cloudfront update-distribution --id xxxx --distribution-config file://distribution.json
invalidazione di una distribuzione e dettaglio dell’operazione:
aws cloudfront create-invalidation --distribution-id xxxx --paths "/*"
aws cloudfront get-invalidation --distribution-id xxxx --id yyyy
La libreria SDK per Java e Boto3 per python mettono a disposizione metodi per la gestione delle distribuzioni, i principali metodi sono:
def list_distributions(profile_name): boto3.setup_default_session(profile_name=profile_name) client = boto3.client('cloudfront') response = client.list_distributions(MaxItems='200') if 'DistributionList' in response: if 'Items' in response['DistributionList']: return response['DistributionList']['Items'] #['ResponseMetadata'] return [] def get_distribution(profile_name, distribution_id): boto3.setup_default_session(profile_name=profile_name) client = boto3.client('cloudfront') response = client.get_distribution(Id=distribution_id) return response['Distribution'] #['ResponseMetadata']
Con CloudFormation è possibile creare le risorse legando il bucket S3 e la distribuzione CloudFormation, ricordandosi che è necessario creare anche la regola OriginAccessControl e il BucketPolicy, risorse necessarie per evitare di avere un “Access denied”. Un esempio completo di creazione di una infrastuttura con i 4 componenti:
Resources: S3Bucket: Type: AWS::S3::Bucket Properties: AccessControl: Private BucketName: !Ref NomeBucket CloudFrontOriginAccessControl: Type: AWS::CloudFront::OriginAccessControl Properties: OriginAccessControlConfig: Description: "OAC for allowing cloudfront to access S3 bucket" Name: !Join ['', ['static-hosting-OAC-',!Ref NomeBucket]] OriginAccessControlOriginType: s3 SigningBehavior: always SigningProtocol: sigv4 CloudFrontDistribution: Type: AWS::CloudFront::Distribution Properties: DistributionConfig: Origins: - DomainName: !Join ['', [!Ref S3Bucket, '.s3.amazonaws.com']] Id: static-hosting S3OriginConfig: OriginAccessIdentity: "" OriginAccessControlId: Ref: CloudFrontOriginAccessControl Enabled: "true" DefaultRootObject: index.html ... BucketPolicy: Type: AWS::S3::BucketPolicy Properties: Bucket: !Ref NomeBucket PolicyDocument: Version: "2012-10-17" Statement: - Effect: Allow Principal: Service: "cloudfront.amazonaws.com" Action: "s3:GetObject" Resource: !Join ['', ['arn:aws:s3:::', !Ref NomeBucket, '/*']]
L’esempio completo fuzionante può essere trovaro al solito repository:
https://github.com/alnao/AWSCloudFormationExamples/tree/master/Esempio07cloudFront