Cara Membangun Arsitektur Serverless

Microservices adalah layanan independen yang berkomunikasi melalui API atau application programming interface. Microservices ini merupakan antonim dari monolitik. Karakteristik dari microservices adalah autonomous (pengembangan, deploy, operasi, dan scale tidak mempengaruhi fungsi service lain) dan specialized (dapat dipecah menjadi service yang lebih kecil). Penerapan dari arsitektur tersebut masih membutuhkan VM atau virtual machine, sehingga untuk menunjang fleksibelitas diperlukan container. Dengan container dimungkinkan adanya isolasi aplikasi dan dependensi dari resources. Hal tersebut akan membuat lingkungan lebih konsisten dan operasional yang efisien.

Sedikitnya ada 2 masalah yang dapat ditangani dengan container, yaitu perbedaan lingkungan deployment dan pemanfaatan sumber daya komputasi (tidak perlu menggunakan hypervisor). Layanan untuk mengelola container tersebut adalah Amazon Elastic Container Service yang scalable dan mendukung docker container. Ada 3 hal yang perlu diingat untuk menerapkan Amazon ECS, yaitu container (container dibuat dalam bentuk docker image dan disimpan di dalam penyimpanan yang bisa diakses internet, rekomendasi penyimpanannya adalah Amazon Elastic Container Registry), ECS definition (semacam blueprint untuk aplikasi), dan ECS cluster (pengelompokan task secara logika).

AWS Cloud Map dan AWS App Mesh merupakan dua alat yang dapat membatu dalam penerapan Amazon ECS. AWS Cloud Map digunakan untuk mendaftarkan sumber daya aplikasi, sedangkan AWS App Mesh digunakan untuk menangkap metrik, log, dan jejak microservices yang dapat diekspor ke CloudWatch, AWS X-ray, serta tool AWS Partner. Penggunaan kedua layanan tersebut memang sedikit memakan waktu, namun jika ingin lebih cepat bisa digunakan layanan AWS Fargate. Tentu dengan kemudahan itu perlu ada yang dibayar.

Komputasi serverless merupakan teknologi yang memungkinkan sebuah komunitas pengelola aplikasi menghindari pengurusan server baik on-premise maupun cloud. Layanan untuk teknologi komputasi serverless adalah AWS Lambda yang dapat langsung digunakan hanya dengan memasukkan kode seperti Node.js, Java, C#, Python, Go, Ruby, dan PowerShell. Komponen inti dari AWS Lambda adalah Event Source dan Lambda Function. Fungsi dari event source adalah mem-publish event sedangkan lambda function berfungsi menulis kode untuk memproses event. AWS Lambda mendukung beberapa source seperti S3, DynamoDB, SNS, SQS, CloudWatch events, Target Group (ALB) serta AWS IoT button. Saat ini waktu yang dimiliki AWS Lambda untuk menjalankan program adalah 15 menit.

Sebelumnya telah dibahas bahwa arsitektur microservices akan mengelola API, nah, layanan yang disediakan adalah Amazon API Gateway. Ada 2 jenis API yang akan dibuat yaitu RESTful dan WebSocket API. Contoh alur penggunaan Amazon API Gateway adalah saat pelanggan mengirimkan request kemudian Amazon Gateway akan mengirimkan request tersebut ke Lambda Function yang sesuai. Kemudian request tersebut diteruskan ke Amazon Cognito, AWS STS, dan Amazon DynamoDB. Kemudian core business logic akan mengirimkan request ke Amazon DynamoDB, Amazon S3, Amazon ElastiCache, dan Amazon RDS.

Perlu dicatat bahwa menjalankan lambda function di atas masih belum terstruktur, maksudnya apakah akan dijalankan bersamaan atau ada langkah tertentu. Nah, untuk menjawab kebutuhan tersebut diciptakan AWS Step Functions yang merupakan state machine atau sebuah mesin yang mengeluarkan output bergantung dari kondisi sebelumnya. State machine tersebut menggunakan Amazon State Language yang berbasis JSON. Di dalam ASL yang berbasis JSON itu akan terdapat 2 state, yaitu StartState dan FinalState. Berikut adalah arsitektur serverless yang akan dibangun:

Sumber: anonim

Langkah:

  1. Masuk ke halaman AWS IAM melalui AWS Management Console
  2. Pada panel navigasi pilih menu Roles dan klik tombol Create role
  3. Pilih AWS Service, klik lambda kemudian Next: Permission
  4. Gunakan kotak pencarian dan centang:
    • AmazonDynamoDBFullAccess
    • AmazonS3ReadOnlyAccess
  5. Klik tombol Next: Tags dan tambahkan tag dengan konfigurasi:
    • Key : Name
    • Value : Load-Inventory
  6. Klik tombol Next: Review dan tambahkan role dengan konfigurasi:
    • Role name : Load-Inventory
    • Role description : Allows Lambda function to have read only access to Amazon S3 and have full access to DynamoDB
  7. IAM role pertama sudah berhasil dibuat, sekarang akan dibuat IAM role kedua
  8. Klik tombol Create role
  9. Pilih AWS Service, klik lambda kemudian Next: Permission
  10. Gunakan kotak pencarian dan centang:
    • AWSLambdaDynamoDBExecutionRole
    • AmazonSNSFullAccess
  11. Klik tombol Next: Tags dan tambahkan tag dengan konfigurasi:
    • Key : Name
    • Value : Check-Stock
  12. Klik tombol Next: Review dan tambahkan role dengan konfigurasi:
    • Role name : Check-Stock
    • Role description : Allows Lambda function to execute DynamoDB and have full access to SNS
  13. Sekarang 2 IAM role telah berhasil terbuat!
  14. Pada langkah selanjutkan akan dibuat AWS Lambda Function
  15. Masuk ke halaman AWS Lambda melalui AWS Management Console
  16. Klik tombol Create function
  17. Pilih Author from scratch
  18. Di bagian Basic information gunakan konfigurasi:
    • Function name : Load-Inventory
    • Runtime : Python 3.8
  19. Klik tanda panah Change default execution role, lalu pilih Use an existing role
  20. Lalu pada Existing role pilih Load-Inventory
  21. Klik tombol Create function
  22. Pada tab code klik dua kali lambda_function.py dan copy-paste kode di bawah:
    • # Load-Inventory Lambda function
    • #
    • # This function is triggered by an object being created in an Amazon S3 bucket.
    • # The file is downloaded and each line is inserted into a DynamoDB table.
    •  
    •  
    • import json, urllib, boto3, csv
    •  
    •  
    • # Connect to S3 and DynamoDB
    • s3 = boto3.resource('s3')
    • dynamodb = boto3.resource('dynamodb')
    •  
    •  
    • # Connect to the DynamoDB tables
    • inventoryTable = dynamodb.Table('Inventory');
    •  
    •  
    • # This handler is run every time the Lambda function is triggered
    • def lambda_handler(event, context):
    •  
    •  
    •   # Show the incoming event in the debug log
    •   print("Event received by Lambda function: " + json.dumps(event, indent=2))
    •  
    •  
    •   # Get the bucket and object key from the event
    •   bucket = event['Records'][0]['s3']['bucket']['name']
    •   key = urllib.parse.unquote_plus(event['Records'][0]['s3']['object']['key'])
    •   localFilename = '/tmp/inventory.txt'
    •  
    •  
    •   # Download the file from S3 to the local filesystem
    •   try:
    •     s3.meta.client.download_file(bucket, key, localFilename)
    •   except Exception as e:
    •     print(e)
    •     print('Error getting object {} from bucket {}. Make sure they exist and your bucket is in the same region as this function.'.format(key, bucket))
    •     raise e
    •  
    •  
    •   # Read the Inventory CSV file
    •   with open(localFilename) as csvfile:
    •     reader = csv.DictReader(csvfile, delimiter=',')
    •  
    •  
    •     # Read each row in the file
    •     rowCount = 0
    •     for row in reader:
    •       rowCount += 1
    •  
    •  
    •       # Show the row in the debug log
    •       print(row['store'], row['item'], row['count'])
    •  
    •  
    •       try:
    •         # Insert Store, Item, and Count into the Inventory table
    •         inventoryTable.put_item(
    •           Item={
    •             'Store':  row['store'],
    •             'Item':   row['item'],
    •             'Count':  int(row['count'])})
    •  
    •  
    •       except Exception as e:
    •          print(e)
    •          print("Unable to insert data into DynamoDB table".format(e))
    •  
    •  
    •     # Finished!
    •     return "%d counts inserted" % rowCount
  23. Klik tombol Deploy
  24. AWS Lambda Function telah berhasil dibuat!
  25. Masuk ke halaman S3 melalui AWS Management Console
  26. Klik tombol Create bucket
  27. Berikan nama bucket dengan inventory-xxx (ganti xxx dengan nomor unik) dan pastikan memilih region yang telah ditetapkan sebelumnya kemudian klik tombol Create bucket
  28. Masuk ke bucket yang telah di buat kemudian ke tab properties dan cari Event notifications kemudian klik tombol Create event nofitication
  29. Pada kolom Event name beri nama Load-Inventory
  30. Pada Event types klik All object create events
  31. Pada bagian Destination gunakan konfigurasi:
    • Destination : Lambda function
    • Specify Lambda function : Choose from your Lambda functions
    • Lambda function : Load-Inventory
  32. Klik tombol Save changes
  33. Lambda function telah berhasil dibuat!
  34. Masuk ke halaman Amazon DynamoDB melalui AWS Management Console
  35. Klik tombol Create table, gunakan konfigurasi:
    • Table name : Inventory
    • Primary key
      • Store  {String}
      • Ceklis Add sort key
      • Item   {String}
  36. Klik tombol Create di bagian bawah
  37. AWS Lambda Function, Amazon S3 Bucket, dan Amazon DynamoDB Table telah berhasil dibuat!
  38. Buka notepad kemudian copy-paste teks dibawah:
      • store,item,count
      • Medan,Robusta,12
      • Medan,Arabika,19
      • Medan,Luwak,18
      • Medan,Liberika,0
      • Medan,Gayo,10
      • Medan,Toraja,15
    1. Kemudian simpan dengan format .csv (inventory-medan.csv)
    2. Masuk kembali ke Amazon S3 bucket, klik pada nama bucket yang sebelumnya telah dibuat dan upload file csv tersebut
    3. Masuk kembali ke Amazon DynamoDB kemudian pilih Tables dan klik pada Inventory
    4. Pilih tab Items, jika berhasil data csv tadi akan terbaca di sana
    5. Sekarang akan dibuan Amazon SNS Topic dan Lambda Function kedua
    6. Masuk halaman Amazon SNS melalui AWS Management Console
    7. Pada panel navigasi pilih Topics dan klik tombol Create topic
    8. Pada halaman create topic pilih standard dan beri nama NoStock
    9. Klik tombol Create topic di bagian bawah
    10. Cari tab Subscriptions dan klik tombol Create subscription, gunakan konfigurasi:
      • Protocol : Email
      • Endpoint : (Isi dengan email Anda)
    11. Klik tombol Create subscription di bagian bawah
    12. Cek pesan masuk pada email, dan klik tombol Confirm subscription
    13. Pastikan terbuka tab baru yang menginfokan bahwa email sudah terdaftar di SNS topic
    14. Masuk ke halaman AWS Lambda kemudian klik tombol Create function dan gunakan konfigurasi:
        • Choose one of the following options to create your function : Author from scratch
        • Function name : Check-Stock
        • Runtime : Python 3.8
      1. Pada bagian Permission klik tanda panah pada Create default execution role dan gunakan konfigurasi:
        • Execution role : Use an existing role
        • Existing role : Check-Stock
      2. Klik tombol Create function dibagian bawah
      3. Pada tab code pilih lambda_function.py klik dua kali dan copy-paste kode di bawah ini:
        • # Stock Check Lambda function
        • #
        • # This function is triggered when values are inserted into the Inventory DynamoDB table.
        • # Inventory counts are checked, and if an item is out of stock, a notification is sent to an SNS topic.
        •  
        •  
        • import json, boto3
        •  
        •  
        • # This handler is run every time the Lambda function is triggered
        • def lambda_handler(event, context):
        •  
        •  
        •   # Show the incoming event in the debug log
        •   print("Event received by Lambda function: " + json.dumps(event, indent=2))
        •  
        •  
        •   # For each inventory item added, check if the count is zero
        •   for record in event['Records']:
        •     newImage = record['dynamodb'].get('NewImage', None)
        •     if newImage:
        •  
        •  
        •       count = int(record['dynamodb']['NewImage']['Count']['N'])
        •  
        •  
        •       if count == 0:
        •         store = record['dynamodb']['NewImage']['Store']['S']
        •         item  = record['dynamodb']['NewImage']['Item']['S']
        •  
        •  
        •         # Construct message to be sent
        •         message = store + ' is out of stock of ' + item
        •         print(message)
        •  
        •  
        •         # Connect to SNS
        •         sns = boto3.client('sns')
        •         alertTopic = 'NoStock'
        •         snsTopicArn = [t['TopicArn'] for t in sns.list_topics()['Topics']
        •                         if t['TopicArn'].lower().endswith(':' + alertTopic.lower())][0]
        •  
        •  
        •         # Send message to SNS
        •         sns.publish(
        •           TopicArn=snsTopicArn,
        •           Message=message,
        •           Subject='Inventory Alert!',
        •           MessageStructure='raw'
        •         )
        •  
        •  
        •   # Finished!
        •   return 'Successfully processed {} records.'.format(len(event['Records']))
      4. Klik tombol Deploy
      5. Scroll ke atas klik tombol Add trigger dan gunakan konfigurasi:
        • Select a trigger : DynamoDB
        • DynamoDB table : Inventory
      6. Klih tombol Add yang ada dibawah
      7. Trigger DynamoDB ke Lambda Function telah berhasil dibuat!
      8. Sekarang kita uji coba
      9. Buka notepad dan copy-paste teks di bawah:
        • store,item,count
        • Makassar,Robusta,14
        • Makassar,Arabika,13
        • Makassar,Luwak,24
        • Makassar,Liberika,19
        • Makassar,Gayo,23
        • Makassar,Toraja,0
      10. Simpan dengan format csv (inventory-makssar.csv)
      11. Masuk ke halam S3 kemudian buka bucket yang telah dibuat tadi dan upload file inventory-makassar.csv
      12. Tunggu sejenak, jika berhasil maka akan ada email notifikasi yang masuk
      13. Arsitektur serverless berhasil dibuat!
      Jangan lupa melakukan clean up untuk S3 bucket, Lambda function. DynamoDB table, dan SNS topic yang telah dibuat agar terhindar dari biaya.

      Jika telah memiliki satu cluster ECS dengan tipe EC2 dan telah dibuat service di dalam cluster tersebut maka akan bermasalah saat me-launching cluster baru. Nah, untuk mengatasi hal tersebut agar tidak perlu membuat service baru di cluster baru yang akan di-launching perlu dibuat AMI atau amazon machine image dari server AWS ECS-EC2 tersebut kemudian dimasukkan ke dalam template. Untuk langkah lebih detail bisa dilihat di website Amazon tentang ec2-launch-templates.




      ref:
      https://aws.amazon.com/

      Komentar