なぜServerless Frameworkなのか
私自身、LambdaのコードをGitで管理するためにTerraform + GitHub ActionsでCI/CD構築していましたがデプロイに時間がかかり開発効率が非常に悪いことやTerraformの記述量が多くなってシンプルに管理できないことがデメリットに感じていました。しかし、今回のServerless Frameworkを使うことで爆速かつシンプルに開発することができます。
開発手順
AWS CLIのセットアップ
この記事では深く解説しないのでこちらの記事を参考に設定してください。
Serverless Frameworkをインストール
brew install serverless
Goのテンプレートを使ってプロジェクトを作成
以下のコマンドを実行することでgoファイルなどを自動で生成してくれます。
sls create -t aws-go -p project-name
* ちなみにPythonだと以下のようにする。
sls create -t aws-python3 -p project-name
serverless.ymlを編集
デフォルトだとus-east-1に作成されてしまうのでap-northeast-1とする。
service: project-name
frameworkVersion: '3'
provider:
name: aws
runtime: go1.x
stage: dev
region: ap-northeast-1
# CloudWatchにログが書き込まれる
iamRoleStatements:
- Effect: Allow
Action:
- logs:CreateLogGroup
- logs:CreateLogStream
- logs:PutLogEvents
Resource:
- "*"
Goのモジュール管理
go mod init serverless
go get github.com/aws/aws-lambda-go/lambda
シェルスクリプトを作成して実行
goファイルをビルドしてデプロイするまでのコマンドを記述しました。
デプロイが終わったらデプロイ、ダン!!!と喋ってくれます。可愛いですね。
#!/bin/sh
GOOS=linux go build -o bin/main
echo "build done !!!"
sls deploy
say "deploy done !!!"
以下のコマンドで実行します。
sh cd.sh
Lambda関数呼び出し
以下のコマンドでLambda関数を実行することができます。きちんとレスポンスが返ってくればデプロイ成功になります。
sls invoke -f <function_name>
環境を削除
sls remove
番外編
API Gateway ・ EventBridgeなどのAWSサービスとの連携
以下のように記述することで容易にLambdaと連携しREST APIを作成することができます。
デプロイ後にエンドポイントURLがターミナルに表示されます。
functions:
# 関数名
sample:
handler: bin/main
events:
# API Gatewayとの連携
- http:
path: /message
method: get
integration: lambda
# EventBridgeとの連携 (毎朝10時に実行する)
- schedule: cron(0 1 * * ? *)
環境変数を扱う
環境変数を扱うときはserverless.ymlにuseDotenv: trueを記述し.envファイルを作成してキーとバリューをセットします。
* .gitignoreに.envと記述し、GitHubにはキーを公開しないようにしましょう。
frameworkVersion: '3'
# 追加する
useDotenv: true
・
・
functions:
sample:
handler: bin/main
environment:
ACCESS_TOKEN: ${env:ACCESS_TOKEN}
外部ライブラリを使いたい時
標準のものではなく外部のrequestsなどが使いたい時ってありますよね。以下のことを実行するだけで簡単に実装できます。
npm install --save serverless-python-requirements
provider:
name: aws
runtime: python3.8
stage: dev
region: ap-northeast-1
## 追加する
plugins:
- serverless-python-requirements
custom:
pythonRequirements:
dockerizePip: true
requests