Simple Storage Service, abbreviato con la sigla S3, è il principale servizio di archiviazione del servizio Cloud di AWS, studiato per memorizzare e recuperare qualsiasi volume di dati, in qualunque momento e da qualunque luogo. Le caratteristiche principali del servizio sono: gli oggetti sono salvati in contenitori chiamati bucket (non a caso il logo di questo servizio è proprio un secchio), ogni elemento ha un nome (key), gli oggetti sono organizzati in strutture (path), l’accesso agli oggetti può essere personalizzato grazie a regole IAM, gli accessi possono essere salvati in registri specifici nel servizio CloudWatch. E’ possibile cancellare o spostare oggetti e il servizio permette di attivare il sistema di versioning per avere la storia di tutti gli oggetti. Per qualsiasi informazione e approfondimenti si può fare riferimento alla pagina dedicata al servizio S3 nel sito ufficiale.
La AWS-CLI mette a disposizione tutta una serie di comandi per la gestione dei bucket e degli oggetti, in particolare “mb” può essere usato per creare bucket:
$ aws s3 mb s3://bucket-name
ricordandosi che il nome deve essere globalmente unico (globally unique unique across all of Amazon S3) e deve rispettare le regole imposte da AWS. La lista dei bucket disponibili si recupera con il comando:
$ aws s3 ls
e per cancellare un bucket (che non contiene nessun oggetto) si usa il comando rb:
$ aws s3 rb s3://bucket-name
Per ottenere la lista di tutti gli oggetti contenuti in un bucket:
$ aws s3 ls bucket-name
E per muovere oggetti tra bucket o scaricare un oggetto cancellandolo si usa la sintassi:
$ aws s3 mv s3://bucket-name/example.txt s3://bucket-name2/ $ aws s3 mv s3://bucket-name/filename.txt ./
Mentre per copiare tra bucket o dal sistema locale da/per un bucket si usa la sintassi:
$ aws s3 cp s3://bucket-name/example.txt s3://my-bucket/ $ aws s3 cp ./filename.txt s3://bucket-name $ aws s3 cp s3://bucket-name/filename.txt ./
I comandi possono essere combinati con i comandi Linux, per esempio per scrivere o leggere un oggetto:
$ echo "hello world" | aws s3 cp - s3://bucket-name/filename.txt $ aws s3 cp s3://bucket-name/filename.txt -
Il comando Sync permette di tenere sincronizzato una cartella locale con un bucket, quindi eventuali orfani vengono cancellati e nuovi file vengono copiati, la sintassi preve solo la cartella sorgente e il bucket di destinazione:
$ aws s3 sync . s3://my-bucket/path
Per svuotare un bucket da tutti gli oggetti contenuti si può usare il comando rm con il parametro ricorsivo:
$ aws s3 rm s3://my-bucket/path --recursive
è ovvio che bisogna sempre prestate attenzione a questo ultimo comandi in quanto rimuove tutti gli oggetti e, senza sistema di versionamento attivo, gli oggetti vengono cancellati in maniera permanente. Tutti i parametri e le caratteristiche di questo comando sono disponibili alla pagina della documentazione ufficiale.
I template CloudFormation spesso hanno al proprio interno definizione o riferimenti a bucket S3, il tipo specifico AWS::S3::Bucket
che ha come unico parametro obbligatorio il nome (che deve sempre rispettare le regole previste da AWS)
Resources: S3Bucket: Type: 'AWS::S3::Bucket' Properties: BucketName: !Ref NomeBucket
La documentazione ufficiale è ricca di esempi e può essere sempre consultata come fonte principale di informazioni. Il più semplice esempio è la gestione di siti web esposti dallo stesso servizio S3 senza l’uso di CloudFront o altri servizi dedicati, ispirato alla documentazione ufficiale con in aggiunta le regole ACL, nel template è indispensabile aggiungere la regola di accesso al bucket tramite un oggetto di tipo BucketPolicy:
S3BucketPolicy: Type: AWS::S3::BucketPolicy Properties: Bucket: !Ref NomeBucket PolicyDocument: Version: 2012-10-17 Statement: - Sid: AllowSSLRequestsOnly Action: 's3:GetObject' Effect: Allow Resource: !Join - '' - - 'arn:aws:s3:::' - !Ref NomeBucket - /* Principal: '*'
L’esempio completo funzionante può essere trovato al solito repository
github.com/alnao/AWSCloudFormationExamples/tree/master/Esempio03bucketS3sito
La libreria CDK mette a disposizione classi per la gestione dei bucket, la documentazione ufficiale è ricca di esempi pratici. Per il linguaggio Java la principale risorsa è proprio il builder di Bucket:
Bucket bucket = Bucket.Builder.create(this, "MyBucket") .versioned(true) .encryption(BucketEncryption.KMS_MANAGED) .build();
Per il linguaggio Python la creazione di bucket è ancora più semplice, un esempio ripreso dalla guida ufficiale:
from aws_cdk import (aws_s3 as s3,core) class MyStack(core.Stack): def __init__(self, scope: core.Construct, id: str, **kwargs) -> None: super().__init__(scope, id, **kwargs) # Create an S3 bucket bucket = s3.Bucket(self, "MyBucket", bucket_name="my-unique-bucket-name",#unique bucket name versioned=True, # enable versioning for the bucket encryption=s3.BucketEncryption.S3_MANAGED ) app = core.App() MyStack(app, "MyStack") app.synth()
La libreria SDK è ricca di classi e metodi per la gestione dei bucket e dei contenuti, per il linguaggio di programmazione Python il sito ufficiale mette a disposizione diversi esempi i principali metodi messi a disposizione del servizio S3 sono:
#Lista dei bucket s3_client.list_buckets()["Buckets"] #Lista di oggetti response = s3_client.list_objects_v2( Bucket=bucket_name, Delimiter="/", Prefix=path, ) if "Contents" in response: response["objects"]=response["Contents"] if "CommonPrefixes" in response: response["folders"]=response["CommonPrefixes"] #Lista di oggetti con metodo paginante s3_paginator = s3_client.get_paginator('list_objects_v2') for page in s3_paginator.paginate(Bucket=bucket_name, Prefix=path, Delimiter='/'): #, StartAfter=start_after): if "Contents" in page: response["objects"]=response["objects"] + page["Contents"] #sum to append if "CommonPrefixes" in page: response["folders"]=response["folders"] + page["CommonPrefixes"] #sum to append #Contenuto di un file di testo content = s3_client.get_object(Bucket=bucket_name, Key=key)["Body"].iter_lines() #Scrivere un file di testo string_encoded = body.encode("utf-8") s3_client.put_object(Bucket=bucket_name, Key=key, Body=string_encoded)
Nel la libreria per il linguaggio Java le classi disponibili sono nel package:
software.amazon.awssdk.services.s3
Per esempio per ottenere la lista completa di tutti i bucket si può usare il semplice metodo:
S3Client client = S3Client.builder().build(); ... public static List<Bucket> getBucketList(S3Client s3Client){ ArrayList<Bucket> l=new ArrayList<Bucket>(); ListBucketsRequest listBucketsRequest = ListBucketsRequest.builder().build(); ListBucketsResponse listBuckets = s3Client.listBuckets(listBucketsRequest); listBuckets.buckets().stream().forEach(x -> l.add(x)); return l; }
Un semplice esempio dei vari metodi messi a disposizione della libreria può essere trovato al solito repository oppure mella documentazione ufficiale sono disponibili molti esempi di gestione dei bucket