Funkcja lambda będzie miała zadanie automatycznie przenieść nowo dodany plik z jednego bucketu S3 do drugiego. Plik źródłowy zostanie automatycznie usunięty po zakończeniu kopiowania. Funkcja będzie działała automatycznie. Gdy ktoś doda plik do odpowiedniego folderu w bucket_1, zostanie on automatycznie przeniesiony do wyznaczonego folderu w bucket_2 i usunięty z pierwszego.
Z tego artykułu dowiesz się jak utworzyć:
- bucket S3 z odpowiednimi uprawnieniami,
- politykę dla roli IAM,
- rolę IAM i przypisać do niej odpowiednie poliyki,
- funkcję lambda i przypisać do niej odpowiednią rolę IAM,
- mechanizm pozwalający na automatyczne działanie funkcji lambda
1) S3 bucket
Ja stworzę 2 osobne buckety S3. Pierwszy będzie źródłowy, z niego funkcja lambda będzie kopiować pliki. Drugi będzie docelowy, tam będą kopiowane pliki.
Klikasz ‘Create bucket‘ i nadajesz nazwę. Upewnij się, że wybrałeś dobry region. Jeśli nie masz takiej potrzeby, to najlepiej nie włączaj publicznego dostępu Block all public access. To na razie na tyle. Więcej na temat S3 znajdziesz w CDN i 2 sposoby na ‘Statyczną Stronę WWW’ w AWS – blog (lepczynski.it)
2) Rola IAM dla Lambda
Na początku można utworzyć nową rolę IAM dla funkcji lambda. Do funkcji należy dodać odpowiednie polityki. Dla zapewnienia większego bezpieczeństwa najlepiej przyznać tylko minimalne uprawnienia, potrzebne do wykonania zadania.
Najlepiej stworzyć nową politykę, przejść do zakładki JSON i dodać co trzeba. Ciekawym rozwiązaniem jest też AWS Policy Generator.
Poniżej minimalne uprawnienia potrzebne do pobierania i usuwania obiektów w źródłowym buckecie oraz do zapisywania obiektów w docelowym buckecie.
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "VisualEditor0",
"Effect": "Allow",
"Action": [
"s3:GetObject",
"s3:DeleteObject"
],
"Resource": "arn:aws:s3:::test-ndgegy4364gdu-source-bucket/images/*"
},
{
"Sid": "VisualEditor1",
"Effect": "Allow",
"Action": "s3:ListBucket",
"Resource": [
"arn:aws:s3:::test-ndgegy4364gdu-source-bucket",
"arn:aws:s3:::test-ndgegy4364gdu-source-bucket/images/*"
]
},
{
"Sid": "VisualEditor2",
"Effect": "Allow",
"Action": "s3:PutObject",
"Resource": "arn:aws:s3:::test-ndgegy4364gdu-destination-bucket/images/*"
}
]
}
Gdy utworzysz odpowiednią politykę, to wyszukujesz jej nazwę i dodajesz do roli:
Później przechodzisz dalej, nadajesz super fajną nazwę dla nowej roli IAM i możesz przejść do kolejnego punktu.
Więcej o tworzeniu roli IAM i polityk znajdziesz w artykule Jak automatycznie uruchomić EC2 w chmurze AWS? – blog po polsku (lepczynski.it).
3) Funkcja Lambda
Jak utworzyć funkcję Lambda
Dobra, teraz przechodzimy do najważniejszej części, do tworzenia funkcji Lambda. Ja robię to od podstaw, używając do tego Python 3.9.
Pamiętaj, żeby użyć stworzonej w punkcie numer 2 roli IAM:
import boto3
import json
s3 = boto3.resource('s3')
def lambda_handler (event, context):
bucket = s3.Bucket('test-ndgegy4364gdu-source-bucket')
dest_bucket=s3.Bucket('test-ndgegy4364gdu-destination-bucket')
print(dest_bucket)
print(bucket)
for obj in bucket.objects.filter(Prefix='images/',Delimiter='/'):
dest_key=obj.key
print(dest_key)
print('copy file ' + dest_key)
s3.Object(dest_bucket.name, dest_key).copy_from(CopySource= {'Bucket': obj.bucket_name, 'Key': obj.key})
print('delete file from source bucket ' + dest_key)
s3.Object(bucket.name, obj.key).delete()
test-ndgegy4364gdu-source-bucket – to jest mój źródłowy bucket, z którego kopiuję pliki (pamiętaj, aby zmienić jego nazwę)
test-ndgegy4364gdu-destination-bucket – to jest docelowy bucket, gdzie pliki się pojawią (pamiętaj, aby zmienić jego nazwę)
Pliki kopiuję z folderu images w test-ndgegy4364gdu-source-bucket do folderu images w test-ndgegy4364gdu-destination-bucket. Jeśli zmienisz wartość Prefix='images/'
na Prefix=''
wtedy będą kopiowane wszystkie pliki z jednego bucketu do drugiego.
Funkcję lambda możesz dowolnie dostosować do swoich potrzeb. Ja miałem na celu pokazanie, że nie wszystkie pliki z S3 muszą być kopiowane, może to być tylko konkretny folder.
Upewnij się, że funkcja działa prawidłowo, klikając deploy i test. Jeśli wszystko zrobiłeś dobrze, pliki powinny zostać przeniesione z do docelowego bucketu i usunięte ze źródłowego.
Jak dodać automatyzację do S3
Gdy upewnisz się, że wszystko działa, to możesz dodać automatyzację. W Function overview klikasz Add trigger:
Wybierasz z listy S3 i nazwę swojego źródłowego bucketu, czyli tam, gdzie będziesz dodawał pliki.
Event type ustawiasz na PUT, ponieważ chcesz, żeby funkcja była uruchamiana tylko podczas dodawania obiektów.
Bardzo ważne, żeby dodać prefix, jeśli chcesz kopiować tylko pliki z określonego folderu. W innym przypadku funkcja będzie wywoływana za każdym razem, jak cokolwiek zostanie dodane do bucketu nawet w innym folderze.
Klikasz dodaj i to generalnie wszystko. Możesz sprawdzić działanie funkcji, dodając pliki do S3 przez UI, albo na przykład za pomocą cli:
aws s3 cp ./directory s3://test-ndgegy4364gdu-source-bucket/images --recursive
Podsumowanie
Warto zapoznać się z funkcją lambda nawet jak nie jesteś devem, bo może ona bardzo ułatwić życie.
Powyższy artykuł był tylko początkiem przygody z automatyzacją S3 za pomocą funkcji Lambda. Teraz możesz dodać kilka linijek kodu do funkcji, które sprawią np., że będzie ona dodatkowo zmienić rozmiar obrazków.
W przyszłości może napiszę artykuł, jak dodawane pliki do S3 mogą być nie tylko przenoszone do innego bucketu, ale np. także automatycznie dodawane do strony internetowej bez żadnej dodatkowej akcji ze strony użytkownika. Wystarczy, że doda on pliki do S3, a one automatycznie pojawią się na statycznej stronie www. Jeśli interesuje cię temat statycznych stron internetowych tworzonych w prosty sposób w AWS, to zachęcam do przeczytania CDN i 2 sposoby na ‘Statyczną Stronę WWW’ w AWS – blog (lepczynski.it)