Mencoba S3 Object Lambda Menggunakan Python

4 min read

Disclaimer
Saya bekerja di AWS, semua opini adalah dari saya pribadi. (I work for AWS, my opinions are my own.)
Mencoba S3 Object Lambda Menggunakan Python
S3 Object Lambda Menggunakan Python (Ilustrasi: Youtube AWS Web Services)

TeknoCerdas.com – Salam cerdas untuk kita semua. Pada tutorial kali ini kita akan mencoba fitur terbaru dari S3 yaitu S3 Object Lambda. S3 Object Lambda adalah sebuah fitur dimana ketika sebuah S3 object diambil menggunakan S3 GET maka sebuah fungsi Lambda dijalankan dan fungsi Lambda tersebut akan mengambil alih respon yang akan dikembalikan. Untuk mencoba fitur ini runtime Lambda yang digunakan adalah Python 3.8.

Dengan adanya fitur ini maka terbuka banyak peluang yang sebelumnya tidak dapat dilakukan pada S3. Misal melakukan resize gambar on-the-fly pada sebuah object S3 berdasarkan request nama file. Contoh lainnya melakukan filtering atau transformasi data dari data CSV yang dibuka pada S3. Dan masih banyak lagi peluang pengembangan yang lain.

Baca Juga
Serverless PHP: Hosting Normal PHP Website dengan Lambda

Layanan AWS yang akan kita gunakan pada tutorial ini adalah AWS Lambda dan Amazon S3. Tujuan dari tutorial ini adalah fungsi Lambda yang dibuat akan melakukan intercept atau mengembalikan respon yang berbeda dengan isi asli dari object S3 yang direquest.

Jika dibuatkan bagan sederhana maka tampilannya akan seperti berikut.

+-------------+            +-------------+            +-------------+
|  S3 Object  | ---------> |    LAMBDA   | ---------> |    Client   |
+-------------+            +-------------+            +-------------+

Daftar isi

0. Persiapan

Untuk mempersingkat tulisan yang dibuat maka diasumsikan anda telah memiliki pengatahuan tentang hal-hal berikut ini.

  • Memiliki akun AWS yang aktif
  • Memiliki pemahaman dasar tentang Amazon S3
  • Memiliki pemahaman dasar tentang AWS Lambda
  • Memiliki pemahaman dasar tentang AWS IAM
  • Memiliki pemahaman dasar tentang Python dan PIP

Jika anda tidak memiliki prasyarat diatas silahkan lanjutkan membaca. Karena mungkin banyak informasi baru yang diperoleh meskipun tanpa mencoba langsung tutorial ini.

1. Membuat IAM Role

Role ini akan digunakan oleh fungsi Python di Lambda untuk menulis log ke CloudWatch dan melakukan request ke S3 API WriteGetResponseObject.

Buat sebuah role dengan nama LambdaS3ObjectRole. Inline policy yang dapat dimasukkan adalah sebagai berikut.

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "AllowLambdaWriteCloudWatch",
            "Effect": "Allow",
            "Action": [
                "logs:CreateLogGroup",
                "logs:CreateLogStream",
                "logs:PutLogEvents"
            ],
            "Resource": "*"
        },
        {
            "Sid": "AllowWriteObjectLambdaAccess",
            "Action": [
                "s3-object-lambda:WriteGetObjectResponse"
            ],
            "Effect": "Allow",
            "Resource": "*"
        }
    ]
}

2. Membuat S3 Bucket

Buat sebuah S3 bucket untuk menyimpan object yang akan digunakan sebagai test. Object yang akan kita gunakan sebagai test nantinya adalah sebuah plain text biasa.

Pada contoh ini saya menggunakan nama bucket teknocerdas-s3-object-lambda-test dan berada pada region Singapore ap-southeast-1.

S3 Object Lambda - Membuat Bucket
Membuat Bucket

3. Membuat S3 Access Point

S3 Access Point adalah sebuah alias untuk mengakses object yang ada pada suatu bucket S3. Menariknya adalah S3 Access Point dapat memiliki Access Control List (ACL) yang berbeda. Untuk maka endpoint dari keduanya untuk mengakses object juga berbeda.

Karakteristik utama yang membedakan bucket biasa dengan access point adalah cara object didalamnya diakses. Salah satu yang paling terlihat adalah object pada access point tidak dapat diakses oleh public atau anonymous. Jadi harus menggunakan AWS account atau melalui pre-signed url.

Pada contoh ini saya menggunakan nama access point teknocerdas-s3-ap. Parameter saat pembuatan access point ini adalah:

  • Access point name: teknocerdas-s3-ap
  • Bucket name: teknocerdas-s3-object-lambda-test
  • AWS Region: Asia Pacific (Singapore) ap-southeast-1
  • Network Origin: Internet
  • Selebihnya biarkan default
S3 Object Lambda - Membuat Access Point
Contoh S3 Access Point

4. Membuat Lambda Layer

Pustaka boto3 pada Lambda Python 3.8 Runtime belum memiliki versi terbaru yang mendukung S3 API WriteGetObjectResponse. Sehingga kita perlu menggunakan pustaka versi lebih baru.

Kenapa menggunakan Layer? Karena dengan Layer maka kode Lambda kecil sehingga mudah dilakukan debungging dengan code editor built-in dari Console Lambda.

Diasumsikan bahwa versi default Python yang terinstal pada mesin anda adalah Python 3.8.

Baca Juga
Tutorial Serverless: Membuat Deno Runtime untuk AWS Lambda

Buat sebuah direktori baru bernama python

$ mkdir python

Kemudian lakukan pip install boto3 versi terbaru pada direktori tersebut.

$ pip install --verbose --target ./python boto3

Langkah berikutnya adalah memasukkan direktori python tersebut kedalam format zip.

$ zip python-boto3-latest-sdk.zip -r python

Terakhir adalah membuat Lambda Layer dengan parameter berikut.

  • Name: latestBoto3
  • Description: Latest boto3 which support new S3 API WriteGetObjectResponse
  • Upload a .zip file: Pilih python-boto3-latest-sdk.zip
  • Compatible runtimes: Python 3.8
S3 Object Lamda - Membuat Lambda Layer
Membuat Layer untuk boto3 terbaru

5. Membuat Fungsi Python di Lambda

Fungsi Python yang akan dibuat adalah menghitung jumlah karakter yang ada pada object di S3 dan menampilkannya dibawah konten asli object tersebut.

Parameter-parameter yang saya gunakan untuk Lambda yang dibuat adalah:

  • Function name: teknocerdas-python-s3-object
  • Runtime: Python 3.8
  • Existing Role: LambdaS3ObjectRole
  • Selebihnya biarkan default

Pada console Lambda tab Code edit file lambda_function.py dengan source code berikut.

import urllib.request
import boto3

def lambda_handler(event, context):
    print(event)
    
    httpResponse = urllib.request.urlopen(event['getObjectContext']['inputS3Url'])
    originalContent = httpResponse.read().decode('utf-8')
    print('ORIGINAL CONTENT', originalContent)
    
    transformedContent = originalContent + "\n" + 'Number of char(s): ' + str(len(originalContent))
    
    s3 = boto3.client('s3')
    s3.write_get_object_response(Body=transformedContent,
        RequestToken=event['getObjectContext']['outputToken'],
        RequestRoute=event['getObjectContext']['outputRoute']
    )
    
    return {
        'statusCode': 200
    }

Langkah berikutnya adalah menambahkan Lambda Layer pada fungsi Python yang dibuat. Agar boto3 yang dipanggil adalah versi terbaru.

Scroll ke bawah pada bagian Layers tambahkan layer baru yang dibuat sebelumnya yaitu latestBoto3. Tekan tombol Add a Layer kemudian pilih Custom layers.

Inti dari kode yang dibuat diatas adalah mengambil konten object asli kemudian menghitung jumlah karakter yang ada pada object tersebut.

Lambda yang dibuat tidak perlu permission untuk mengambil object S3 tersebut karena sudah terdapat pre-signed URL yang dapat digunakan dari event['getObjectContext']['inputS3Url'].

Setelah konten berhasil dimodifikasi maka Lambda perlu memanggil API S3 WriteGetResponseObject dengan token dan kode route yang diambil dari event['getObjectContext'].

Lambda tidak perlu mengembalikan response body, cukup kembalikan HTTP status code 200.

6. Membuat Object Lambda Access Point

Jika Lambda Access Points hanyalah alias atau endpoint berbeda dengan ACL berbeda dari bucket aslinya, maka Object Lambda Access Point menambahkan kemampuan untuk mengubah respon object pada S3 tersebut sebelum dikembalikan ke client.

Tentunya pemrosesan akan menggunakan AWS Lambda. Berikut ini adalah parameter pembuatan untuk Object Lambda Access Point pada tutorial ini.

  • Object Lambda Access Point name: teknocerdas-python-ap
  • Supporting Access Point: Pilih teknocerdas-s3-ap yang dibuat sebelumnya.
  • Lambda function: Pilih fungsi Lambda teknocerdas-python-s3-object yang dibuat sebelumnya.
  • Selebihnya biarkan default
Membuat Object Lambda Access Point
Membuat Object Lambda Access Point

7. Melakukan Tes

Buat sebuah file teks dengan nama teknocerdas.txt dengan konten sebagai berikut.

TeknoCerdas.com - Berita Teknologi Mencerdaskan

Apa yang diupload di bucket juga otomatis akan tersedia di Access Points dan Object Lambda Access Points tentunya dengan endpoint yang berbeda.

Ingat bahwa apapun yang berada pada Object Lambda Access Points tidak dapat diakses secara public. Jadi harus menggunakan akun AWS atau pre-signed URL. Untuk itu pada aplikasi yang anda buat harus mempertimbangkan pemrosesan ini.

Setelah object berhasil diupload maka masuh pada halaman Object Lambda Access Points.

  1. Pilih Object Lambda Access Point teknocerdas-python-ap
  2. Centang object teknocerdas.txt
  3. Klik tombol Action kemudian pilih Open
Membuka object lewat Object Lambda Access Point
Membuka object lewat Object Lambda Access Point

Object akan dibuka menggunakan pre-signed URL dengan endpoint Object Lambda Access Point. Tampilan yang terbuka harusnya seperti dibawah.

TeknoCerdas.com - Berita Teknologi Mencerdaskan

Number of char(s): 48

Jika terdapat kesalahan coba lihat log yang ditampilkan pada CloudWatch.

Kesimpulan

Terdapat banyak hal yang bisa dilakukan dengan fitur baru ini. S3 Object Lambda membuka banyak peluang kreatifitas yang dapat dilakukan pengembang diatas S3.

Namun fitur ini masih sangat baru dan saya tidak menyarankan menggunakannya di production. Kenapa?

Saya menggunakan Python untuk tutorial ini bukan tanpa alasan. Awalnya saya menggunakan NodeJS dan AWS Javascript SDK terbaru namun ternyata tidak berhasil. Kemudian saya coba menggunakan runtime custom yaitu PHP dan menggunakan AWS PHP SDK terbaru juga belum berhasil.

Kendati Javascript dan PHP SDK sudah mendukung API WriteGetObjectResponse namun sepertinya terdapat bug pada kedua library tersebut.

Akhirnya saya memutuskan untuk mencoba runtime Python dan menggunakan AWS Python SDK (boto3) terbaru dan berhasil.