พัฒนา AWS Lambda บน local environment ด้วย Serverless และ Localstack
ในระบบงานที่กำลังทำอยู่ มีการพัฒนา AWS Lambda ที่เชื่อมต่อกับ AWS resource อื่น ๆ ด้วย ปัญหาก็คือ feedback loop ที่ยาวเนื่องจากจะทดสอบทีก็ต้อง deploy ขึ้นไปลองบน AWS จริง ๆ จากบทความก่อนหน้านี้ เรามีเครื่องมือที่สามารถจำลอง AWS ขึ้นมาใน docker container ได้ ทำให้เราลด feedback loop ให้สั้นลงได้
ตัวอย่างในบทความนี้คือเราจะใช้ AWS resource ต่าง ๆ เหล่านี้ในการพัฒนาระบบงาน
- Lambda
- S3
- ElastiCache
- Secrets Manager
ในการพัฒนา Lambda นั้นเราจะใช้ Serverless framework ซึ่งเป็น framework ที่ช่วยเราพัฒนา Lambda บน Node.js และ Python โดย focus ไปที่ส่วนของ application logic และปล่อยให้ framework จัดการส่วน infrastructure ให้ โดยเราสามารถ configure Lambda ให้ไป deploy ในรูปแบบต่าง ๆ ได้เช่น
- HTTP API
- Scheduled Task
- SQS Worker
- Express API
- Express API with DynamoDB
- Flask API
- Flask API with DynamoDB
โดยเราสามารถสร้าง project ใหม่ขึ้นมาผ่าน Serverless framework ด้วยคำสั่ง command-line บวกกับ configure AWS และ properties อื่น ๆ
$ serverless
ต่อไปเราก็มาวาง CI/CD pipeline กันหน่อยเพื่อ run คำสั่งอื่น ๆ นอกจากการ deploy อย่างเช่น unit testing หรือ linting เป็นต้น โดยในบทความนี้เราจะลองใช้ GitLab CI ดู แต่เนื่องจากว่า repository ของเรามันอยู่ใน GitHub Actions ก็เลยต้องสร้าง GitHub Actions workflow เพื่อ sync การเปลี่ยนแปลงใน GitHub ไปให้ GitLab ด้วยการสร้าง YAML file ใน directory .github/workflows
จากนั้นเราไป generate access token ใน GitLab ที่มี scope write_repository
และนำมาแปะใน GitHub secret variables เมื่อเรา push commit ใหม่ขึ้นไปบน GitHub ก็จะเห็น commit ใหม่บน GitHub ด้วย
Run wangchucheng/git-repo-sync@v0.1.0
with:
target-url: https://gitlab.com/raksit_m/learn-aws-s3-lambda-elasticache.git
target-username: raksit_m
target-token: ***
Run /home/runner/work/_actions/wangchucheng/git-repo-sync/v0.1.0/entrypoint.sh
/home/runner/work/_actions/wangchucheng/git-repo-sync/v0.1.0/entrypoint.sh
shell: /usr/bin/bash --noprofile --norc -e -o pipefail {0}
env:
INPUT_TARGET_URL: https://gitlab.com/raksit_m/learn-aws-s3-lambda-elasticache.git
INPUT_TARGET_USERNAME: raksit_m
INPUT_TARGET_TOKEN: ***
GITHUB_EVENT_REF: refs/heads/main
To https://gitlab.com/raksit_m/learn-aws-s3-lambda-elasticache.git
fdfa83c..d2e2a82 main -> main
ทีนี้เราก็สร้าง GitLab CI โดยสร้าง file .gitlab-ci.yml
ใน root directory โดยเริ่มต้นเอาแค่ build และ deploy ก็พอเพื่อความเรียบง่าย
จากนั้นเราก็ลงมือพัฒนา project ได้เลย จาก diagram ข้างบนเราจะได้ code หน้าตาประมาณนี้
ทีนี้เราก็มาติดตั้ง Localstack กัน โดยเราจะติดตั้งผ่าน Serverless framework plugin ชื่อว่า serverless-localstack
โดยให้เรา run คำสั่ง install dependencies ใน Node.js ก่อน
$ npm i -D serverless-localstack
จากนั้นแก้ไข file serverless.yml
ให้ใช้งาน plugin ได้ประมาณนี้
ต่อมาคือ run Localstack บน local environment ด้วย Docker Compose โดยสร้าง file docker-compose.yml
ขึ้นมาหน้าตาประมาณนี้
ทีนี้เราก็เตรียม Shell script ในการสร้าง resource ใน Localstack เมื่อ Docker container ถูก start โดยอัตโนมัติ แนะนำให้ติดตั้ง awslocal เพื่อจะได้ไม่ต้องระบุ --endpoint
flag
สังเกตว่าเราไม่ได้สร้าง AWS ElastiCache ขึ้นมาเนื่องจากมันไม่ได้อยู่ใน free tier
ปิดท้ายด้วยการแก้ไข code เพื่อเชื่อมต่อกับ Localstack โดยเราจะนำ dotenv มาประยุกต์ใช้เพื่อระบุ environment ที่ run อยู่ด้วยคำสั่ง
$ npm i -D dotenv
ต่อมาก็สร้าง file .env
แต่ไม่ต้องนำขึ้น stage ไปใน Git (อาจจะต้องแก้ไข .gitignore
ด้วย)
เราสามารถ deploy Lambda ขึ้น Localstack ได้ผ่านคำสั่ง
$ serverless deploy --stage local
จากนั้นทำการ run Lambda function ด้วยคำสั่ง
serverless invoke -f <your-function-name-here> --stage local