Skip to content

Instantly share code, notes, and snippets.

@ejlp12
Last active January 14, 2021 07:31
Show Gist options
  • Save ejlp12/62170706a53c7eba9fd1b43e9d85c524 to your computer and use it in GitHub Desktop.
Save ejlp12/62170706a53c7eba9fd1b43e9d85c524 to your computer and use it in GitHub Desktop.
Memulai membuat aplikasi serverless dengan AWS Serverless Application Model (AWS SAM)

Tautan ke halaman ini: https://bit.ly/2UJlHIc

SAM the Squirrel

Jika anda belum mengetahui apa itu komputasi serverless dan AWS Lambda, silakan baca di tautan ini: https://bit.ly/2RkuhLv

SAM

AWS Serverless Application Model (AWS SAM) adalah sebuah open-source framework untuk membangun aplikasi nirserver (serverless) di AWS. Proyek open source AWS SAM dibuat dan didukung oleh AWS, tetapi anda atau komunitas dapat berkontribusi untuk ikut mengembangkannya.

Aplikasi serverless yang dimaksud pada konteks AWS SAM bukan berarti sebuah fungsi Lambda saja, tetapi juga sumberdaya AWS lainnya yang membentuk sebuah aplikasi utuh, seperti misalnya spesifikasi API pada API gateway, database dan pemetaan sumber kejadian (event sources).

Dengan AWS SAM, developer diberikan kemudahan dengan alat command line interface (CLI) yang bisa kita gunakan untuk beberapa hal diantaranya:

  • membuat rangka proyek dari aplikasi serverless dalam sebuah struktur direktori
  • menjalankan sebuah fungsi Lambda di komputer lokal untuk keperluan ujicoba (test)
  • melakukan pengemasan (packaging) dan deployment aplikasi ke layanan komputasi awan AWS

Nanti anda akan pelajari bagaimana menggunakan SAM CLI ini di artikel ini. Anda bisa membaca semua bentuk perintah yang bisa anda lakukan dengan SAM CLI di AWS SAM CLI Command Reference.

Untuk dapat melakukan deployment ke AWS maka sebuah proyek aplikasi serverless yang dikelola menggunakan SAM akan memiliki sebuah SAM template spesification yang digunakan untuk mendefinisikan komponen applikasi seperti fungsi-fungsi Lambda, semua API, permission, konfigurasi dan event-event. Pada dasarnya sebuah file SAM template spesification merupakan sebuah ekstensi dari template CloudFormation.

Praktek menggunakan AWS SAM

Aplikasi yang akan kita buat adalah sebuah aplikasi contoh sederhana menggunakan template yang akan dibuat otomatis oleh AWS SAM. Aplikasi akan terdiri dari sebuah fungsi Lambda dan sebuah API Gateway yang nanti akan diakses dari client menggunakan perintah curl.

Diagram berikut menggambarkan komponen yang akan anda buat:

Asitektur aplikasi serverless

Asumsi saya, anda sudah memiliki akun AWS, sudah menginstal AWS CLI, mempersiapkan credetial menggunakan access key dan secret key dan menggunakan IAM user dengan hak akses Administrator.

Setelah itu anda bisa melakukan langkah-langkah berikut:

  1. Instal Docker. Catatan: Doker hanya perlu jika anda akan melakukan mengujicoba aplikasi anda di mesin lokal (laptop/PC).
  2. Instal Homebrew sebagai alat untuk memudahkan installasi paket AWS SAM CLI
  3. Instal AWS SAM CLI

Petunjuk lebih detil untuk instalasi dibeberapa sistem operasi anda bisa lihat di dokumentasi AWS SAM

Jika anda menggunakan AWS Cloud9, anda tidak perlu melakukan hal tersebut karena AWS CLI, AWS SAM CLI serta Docker sudah terinstal di lingkungan Cloud9 anda. Saran saya anda perlu lakukan update SAM CLI ke versi terbaru dengan cara menghapus file sam yang lama kemudian instal SAM CLI dengan menggunakan homebrew.

Secara garis besar yang anda akan lakukan untuk membuat sebuah aplikasi serverless dan men-deploy-nya di AWS dengan menggunakan SAM CLI, adalah 3 langkah berikut:

#Langkah 1 - Download aplikasi contoh
sam init

#Langkah 2 - Build aplikasi anda
cd sam-app
sam build

#Langkan 3 - Deploy aplikasi anda 
sam deploy --guided

Langkah 1: sam init

Dengan perintah ini anda akan membuat suatu rangka aplikasi, yaitu struktur direktori dan file-file yang dibutuhkan untuk aplikasi serverless. Anda akan mendapatkan beberapa pertanyaan dan cukup memilih jawaban sesuai dengan kebutuhan aplikasi anda.

Berikut adalah contoh langkah-langkan persiapan pembuatan rangka aplikasi yang diberi nama sam-app, yang akan menggunakan python versi 3.7 untuk bahasa atau runtime dari fungsi Lambda, serta menggunakan contoh rangka (template) aplikasi yang sudah disediakan yang bernama hello-world. Direktori dari aplikasi yang akan dibuat dari perintah ini akan ditempatkan di direktori dimana anda saat ini berada (direktori .)

Which template source would you like to use?
        1 - AWS Quick Start Templates
        2 - Custom Template Location
Choice: 1

Which runtime would you like to use?
        1 - nodejs12.x
        2 - python3.8
        3 - ruby2.7
        4 - go1.x
        5 - java11
        6 - dotnetcore2.1
        7 - nodejs10.x
        8 - python3.7
        9 - python3.6
        10 - python2.7
        11 - ruby2.5
        12 - java8
        13 - dotnetcore2.0
        14 - dotnetcore1.0
Runtime: 7

Project name [sam-app]: helloapp

Cloning app templates from https://github.com/awslabs/aws-sam-cli-app-templates.git

AWS quick start application templates:
        1 - Hello World Example
        2 - Quick Start: From Scratch
        3 - Quick Start: Scheduled Events
        4 - Quick Start: S3
        5 - Quick Start: SNS
        6 - Quick Start: SQS
        7 - Quick Start: Web Backend
Template selection: 1

-----------------------
Generating application:
-----------------------
Name: helloapp
Runtime: nodejs10.x
Dependency Manager: npm
Application Template: hello-world
Output Directory: .

Next steps can be found in the README file at ./helloapp/README.md

Sebelum lanjut ke langkah selanjutnya, saya saranakan anda pelajari dulu struktur direktori dari aplikasi yang sudah dibuat beserta file-file yang ada didalamnya. Berikut adalah struktur direktori hasil perintah di langkah #1

helloapp/
├── events
│   └── event.json                <-- Contoh obyek event (input) untuk test fungsi Lambda
├── hello-world
│   ├── app.js                    <-- Kode pemrograman dari AWS Lambda atau sisebut handler logic.
│   ├── package.json              <-- File daftar pustaka (dependencies) NodeJS yang digunakan oleh fungsi Lambda
│   └── tests
│       └── unit
│           └── test-handler.js   <-- File untuk unit test
├── README.md                     <-- File berisi instruksi terkait proyek SAM ini
└── template.yaml                 <-- SAM template yang mendefinisiakan sumberdaya AWS yang digunakan oleh aplikasi

Sekarang coba anda lihat isi dari beberapa file tersebut.

File template.yaml

HelloWorldFunction:                 <-- Nama dari fungsi Lambda
    Type: AWS::Serverless::Function <-- Tipe sumberdaya AWS yang digunakan, dalam hal ini fungsi Lambda 
    Properties:
      CodeUri: hello-world/ 
      Handler: app.lambdaHandler    <-- app artinya menggunakan file hello-world/app.js, 
                                        lambdaHandler adalah function yang diekspor dari app.js
      Runtime: nodejs10.x           <-- Runtime dari fungsi Lambda
      Events:                       <-- All endpoints
        HelloWorld:                 <-- Nama Endpoint
          Type: Api                 <-- Tipe event yang men-tigger fungsi Lambda ini adalah REST API dari API gateway
          Properties:
            Path: /hello            <-- Endpoint path dari API gateway
            Method: get             <-- Endpoint method

Outputs:                            <-- Daftar variabel-variabel keluaran (output) setelah aplikasi ini selesai di-deploy
  HelloWorldApi:
    Description: "API Gateway endpoint URL for Prod stage for Hello World function"
    Value: !Sub "https://${ServerlessRestApi}.execute-api.${AWS::Region}.amazonaws.com/Prod/hello/"
  HelloWorldFunction:
    Description: "Hello World Lambda Function ARN"
    Value: !GetAtt HelloWorldFunction.Arn
  HelloWorldFunctionIamRole:
    Description: "Implicit IAM Role created for Hello World function"
    Value: !GetAtt HelloWorldFunctionRole.Arn            

Diatas adalah contoh sederhana dari file SAM template spesification yang dibuat otomatis. Ada banyak parameter atau spesfikasi lainnya yang bisa ditulis di file tersebut, misalnya untuk fungsi Lambda (tipe sumberdaya AWS::Serverless::Function) anda bisa menulis parameter MemorySize, Timeout, Tag dan lain-lain. Untuk mempelajari lebih lajut anda bisa lihat dokumentasi AWS SAM Specification

File app.js

let response;
exports.lambdaHandler = async (event, context) => {
    try {
        response = {
            'statusCode': 200,
            'body': JSON.stringify({
                message: 'hello world',
            })
        }
    } catch (err) {
        console.log(err);
        return err;
    }
    return response
};

File diatas adalah kode dari aplikasi senderhana anda, yaitu sebuah fungsi Lambda yang akan menghasilkan keluaran sebuah teks JSON {"message":"hello world"}.

Langkah 2: cd sam-app; sam build

Pada langkah ini anda pindah ke direktori aplikasi yang sudah dibuat di langkah sebelumnya dan kemudian melakukan build yaitu kompilasi fungsi Lamda dan pemaketan dari aplikasi menjadi sebuah file terkompresi (zip).

Perintah tersebut menghasilkan keluaran seperti berikut:

Building resource 'HelloWorldFunction'
Running NodejsNpmBuilder:NpmPack
Running NodejsNpmBuilder:CopyNpmrc
Running NodejsNpmBuilder:CopySource
Running NodejsNpmBuilder:NpmInstall
Running NodejsNpmBuilder:CleanUpNpmrc

Build Succeeded

Built Artifacts  : .aws-sam/build
Built Template   : .aws-sam/build/template.yaml

Commands you can use next
=========================
[*] Invoke Function: sam local invoke
[*] Deploy: sam deploy --guided

Setelah proses build selesai, akan dihasilkan file-file di direktori .aws-sam seperti berikut:

.aws-sam/
└── build
    ├── HelloWorldFunction
    │   ├── app.js
    │   ├── node_modules
    │   │   ├── axios/
    │   │   ├── debug/
    │   │   ├── follow-redirects/
    │   │   ├── is-buffer/
    │   │   └── ms/
    │   └── package.json
    └── template.yaml

Sekarang anda siap melakukan ujicoba (test) di lokal atau langsung men-deploy aplikasi ke AWS. Saya akan lewati dulu penjelasan bagaimana melakukan ujicoba di di komputer lokal.

Langkah 3: sam deploy --guided

Perintah ini digunakan untuk men-deploy aplikasi serverless anda. Dengan opsi --guided maka anda akan dipandu dengan beberapa pertanyaan yang akan digunakan sebagai parameter deployment diantaranya:

  • Nama dari CloudFormation stack. Proses deployment dengan SAM di AWS akan menggunakan CloudFormation oleh karena itu anda diminta untuk memberi nama stack yang akan dibuat otomatis oleh SAM
  • Region dimana aplikasi serverless akan di-deploy

SAM deploy juga akan membuat IAM role yang dibutuhkan jika diperlukan, tapi dalam contoh ini template.yaml tidak mendefinisikan IAM role baru yang perlu dibuat.

Anda juga akan diminta konfirmasi apakah parameter yang diinput tadi akan disimpan di sebuah file samconfig.toml sehingga untuk proses deployment berikutnya anda tidak perlu repot untuk menjawab lagi.

Berikut adalah interaksi dan keluaran yang dihasilkan dari perintah sam deploy --guided:

Configuring SAM deploy
======================

        Looking for samconfig.toml :  Not found

        Setting default arguments for 'sam deploy'
        =========================================
        Stack Name [sam-app]: sam-helloapp
        AWS Region [us-east-1]: us-east-1
        #Shows you resources changes to be deployed and require a 'Y' to initiate deploy
        Confirm changes before deploy [y/N]: y
        #SAM needs permission to be able to create roles to connect to the resources in your template
        Allow SAM CLI IAM role creation [Y/n]: y
        Save arguments to samconfig.toml [Y/n]: y

        Looking for resources needed for deployment: Found!

                Managed S3 bucket: aws-sam-cli-managed-default-samclisourcebucket-15ejy51aive11
                A different default S3 bucket can be set in samconfig.toml

        Saved arguments to config file
        Running 'sam deploy' for future deployments will use the parameters saved above.
        The above parameters can be changed by modifying samconfig.toml
        Learn more about samconfig.toml syntax at 
        https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-sam-cli-config.html

        Deploying with following values
        ===============================
        Stack name                 : sam-helloapp
        Region                     : us-east-1
        Confirm changeset          : True
        Deployment s3 bucket       : aws-sam-cli-managed-default-samclisourcebucket-15ejy51aive11
        Capabilities               : ["CAPABILITY_IAM"]
        Parameter overrides        : {}

Initiating deployment
=====================
Uploading to sam-helloapp/7cf13807dadf2105e68003612a4cebbc  131404 / 131404.0  (100.00%)
Uploading to sam-helloapp/a93bac849279e739ffd3515b7ef82364.template  1097 / 1097.0  (100.00%)

Waiting for changeset to be created..

CloudFormation stack changeset
---------------------------------------------------------------------------------------------------------------------------------------------
Operation                                       LogicalResourceId                               ResourceType                                  
---------------------------------------------------------------------------------------------------------------------------------------------
+ Add                                           HelloWorldFunctionHelloWorldPermissionProd      AWS::Lambda::Permission                       
+ Add                                           HelloWorldFunctionRole                          AWS::IAM::Role                                
+ Add                                           HelloWorldFunction                              AWS::Lambda::Function                         
+ Add                                           ServerlessRestApiDeployment47fc2d5f9d           AWS::ApiGateway::Deployment                   
+ Add                                           ServerlessRestApiProdStage                      AWS::ApiGateway::Stage                        
+ Add                                           ServerlessRestApi                               AWS::ApiGateway::RestApi                      
---------------------------------------------------------------------------------------------------------------------------------------------

Changeset created successfully. arn:aws:cloudformation:us-east-1:702342621448:changeSet/samcli-deploy1586126147/6930a0b8-12b8-44f1-b6b7-5ab218d3f5db


Previewing CloudFormation changeset before deployment
======================================================
Deploy this changeset? [y/N]: y

2020-04-05 22:36:04 - Waiting for stack create/update to complete

CloudFormation events from changeset
---------------------------------------------------------------------------------------------------------------------------------------------
ResourceStatus                      ResourceType                        LogicalResourceId                   ResourceStatusReason              
---------------------------------------------------------------------------------------------------------------------------------------------
CREATE_IN_PROGRESS                  AWS::IAM::Role                      HelloWorldFunctionRole              Resource creation Initiated       
CREATE_IN_PROGRESS                  AWS::IAM::Role                      HelloWorldFunctionRole              -                                 
CREATE_COMPLETE                     AWS::IAM::Role                      HelloWorldFunctionRole              -                                 
CREATE_IN_PROGRESS                  AWS::Lambda::Function               HelloWorldFunction                  -                                 
CREATE_IN_PROGRESS                  AWS::Lambda::Function               HelloWorldFunction                  Resource creation Initiated       
CREATE_COMPLETE                     AWS::Lambda::Function               HelloWorldFunction                  -                                 
CREATE_IN_PROGRESS                  AWS::ApiGateway::RestApi            ServerlessRestApi                   -                                 
CREATE_IN_PROGRESS                  AWS::ApiGateway::RestApi            ServerlessRestApi                   Resource creation Initiated       
CREATE_COMPLETE                     AWS::ApiGateway::RestApi            ServerlessRestApi                   -                                 
CREATE_IN_PROGRESS                  AWS::Lambda::Permission             HelloWorldFunctionHelloWorldPermi   Resource creation Initiated       
                                                                        ssionProd                                                             
CREATE_IN_PROGRESS                  AWS::ApiGateway::Deployment         ServerlessRestApiDeployment47fc2d   -                                 
                                                                        5f9d                                                                  
CREATE_IN_PROGRESS                  AWS::Lambda::Permission             HelloWorldFunctionHelloWorldPermi   -                                 
                                                                        ssionProd                                                             
CREATE_COMPLETE                     AWS::ApiGateway::Deployment         ServerlessRestApiDeployment47fc2d   -                                 
                                                                        5f9d                                                                  
CREATE_IN_PROGRESS                  AWS::ApiGateway::Deployment         ServerlessRestApiDeployment47fc2d   Resource creation Initiated       
                                                                        5f9d                                                                  
CREATE_IN_PROGRESS                  AWS::ApiGateway::Stage              ServerlessRestApiProdStage          -                                 
CREATE_IN_PROGRESS                  AWS::ApiGateway::Stage              ServerlessRestApiProdStage          Resource creation Initiated       
CREATE_COMPLETE                     AWS::ApiGateway::Stage              ServerlessRestApiProdStage          -                                 
CREATE_COMPLETE                     AWS::Lambda::Permission             HelloWorldFunctionHelloWorldPermi   -                                 
                                                                        ssionProd                                                             
CREATE_COMPLETE                     AWS::CloudFormation::Stack          sam-helloapp                        -                                 
---------------------------------------------------------------------------------------------------------------------------------------------

CloudFormation outputs from deployed stack
-----------------------------------------------------------------------------------------------------------------------------------------------
Outputs                                                                                                                                       
-----------------------------------------------------------------------------------------------------------------------------------------------
Key                 HelloWorldFunctionIamRole                                                                                                 
Description         Implicit IAM Role created for Hello World function                                                                        
Value               arn:aws:iam::702342621448:role/sam-helloapp-HelloWorldFunctionRole-1JOUXVZA6A1KA                                          

Key                 HelloWorldApi                                                                                                             
Description         API Gateway endpoint URL for Prod stage for Hello World function                                                          
Value               https://8wsbr1dghe.execute-api.us-east-1.amazonaws.com/Prod/hello/                                                        

Key                 HelloWorldFunction                                                                                                        
Description         Hello World Lambda Function ARN                                                                                           
Value               arn:aws:lambda:us-east-1:702342621448:function:sam-helloapp-HelloWorldFunction-N46KLW3NPEWD                               
-----------------------------------------------------------------------------------------------------------------------------------------------

Successfully created/updated stack - sam-helloapp in us-east-1

Dibagian akhir keluaran tersebut, anda bisa lihat bagian Outputs yang menampilkan 3 parameter yang dispesifikasikan pada file template.yaml. Yang terpenting dari output tersebut saat ini adalah value dari parameter dengan key: HelloWorldApi yaitu Endpoind URL dari API Gateway yang akan digunakan untuk mengeksekusi fungsi Lambda.

Dalam contoh ini Endpoind URL-nya adalah https://8wsbr1dghe.execute-api.us-east-1.amazonaws.com/Prod/hello/. Sehingga anda dapat melakukan ujicoba pemanggailan aplikasi anda dengan perintah berikut:

curl https://8wsbr1dghe.execute-api.us-east-1.amazonaws.com/Prod/hello/

Anda akan mendapatkan keluaran seperti ini:

{"message":"hello world"}

Selamat, anda sudah dapat membuat dan men-deploy sebuah aplikasi severless sederhana di AWS.

Sekarang anda bisa lihat sumberdaya AWS yang sudah dibuat otomatis oleh SAM CLI. Masuklah ke AWS console, kemudian akses AWS Lambda console anda akan mendapatkan fungsi yang sudah anda deploy:

lambda_console

di Amazon API Gateway console, anda akan lihat sebuah API sudah dibuat:

lambda_api_gw

Untuk menghapus aplikasi atau semua sumberdaya AWS yang sudah dibuat, anda bisa jalankan perintah berikut:

aws cloudformation delete-stack --stack-name sam-helloapp

Catatan

Pada artikel ini ada beberapa langkah yang tidak saya jelaskan secara detil, misalnya langkah persiapan atau instalasi beberapa alat-alat pendukung. Anda bisa mengikuti konten workshop di https://cicd.serverlessworkshops.io/ untuk penjelasan langkah-langkah yang lebih detil. Perlu diingat juga, mungkin anda akan dikenakan biaya karena melewati batas free tier ketika menggunakan AWS resources. Jika hanya untuk mencoba, jangan lupa untuk menghapus resources yang sudah anda gunakan untuk menghindari biaya yang tidak diinginkan.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment