概要
以前、LambdaをEventBridgeで定期実行するバッチを作ったのだが、
その際、Lambdaのコードをコンソール上に直書きしていた。
そうしたところ以下の問題が発生した
・デプロイの際、手動でコンソール上のコードを書き換える必要がある(めんどくさい&ミスする)
・テストがローカル環境でできない
この問題を解消するため、既存のLambdaのコードををAWS SAMに対応させてみる
本記事にはその際の手順を載せる
今回SAM対応させるアプリケーションの構成
対応後の感想
- メリット
- (小規模なら)対応が楽
- SAM CLIをインストールして、template.yamlを調整するだけ
- Serverless Landで多数のサンプルが用意されている
- Lambda関数をローカルでテストできる
- デプロイが簡単安全
- デプロイ対象のリソースが複数あってもコマンド一発でできる
- 手動デプロイじゃなくなったのでミスが減る
- CloudFormationで管理されるようになる
- 各AWSリソースの削除が一回でできる
- アプリケーションの構成が把握しやすくなる
- (小規模なら)対応が楽
- デメリット
- 中規模以上のAWS構成に向かない
- 既存システムを対応させる場合、template.yamlの修正が大変
- template.yamlに全ての構成を書くため、ステップ数が膨大になりそう
- 中規模以上ならTerraformなどの他のツールの方が向いていそう
- 中規模以上のAWS構成に向かない
対応手順
AWS SAM CLIのインストール
まずはAWS SAM CLIをインストールする
mac環境だと以下手順となる、前提としてHomebrewがインストールされていること
brew tap aws/tap
brew install aws-sam-cli
mac以外の環境は公式の手順を参照
テンプレートを探す
Serverless Landというサイトから
自分が作りたい構成のテンプレートを探してDLする
後述するtemplate.yamlをドキュメントを読みながら自前で作成するのは大変なので、作りたい構成に近いテンプレートを改造してゆく
DLしたテンプレートを修正する
今回DLしたテンプレートは以下のような内容
root
├── src
│ ├── app.py # Lambdaで実行されるソース
└── template.yaml # SAMの設定ファイル
sam initは不要
sam initを実行するとSAMアプリケーションのテンプレートが展開されるが、余計なファイルまで作られてしまう
Serverless LandからDLしたテンプレートを修正する方が早い
src配下を置き換える
src配下には、Lambdaで実行するソースを配置する。
今回は、Lambdaコンソールに直書きしていたコードを、そのままapp.pyに上書きした。
依存関係は、requirements.txtを生成してsrc配下に設置すること(pythonの場合)
SAMの設定ファイルを調整する
template.yamlには、SAMアプリケーションの設定が書かれている。
ほとんどの設定がこのファイルに記載されており、アプリケーションの構成はこのファイルをみれば分かるようにになっている。
詳細は公式ドキュメント 参照
今回、設置したtemplate.yamlは以下、
変更点は定期実行の周期(Schedule)を1分(1 minute)から1日(1 day)にしたのみ
簡単な説明も載せておく
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: Create a Lambda function that logs something to the console from a cron job in EventBridge
Resources:
ScheduledFunction: # リソースの識別名(任意の値を設定)
Type: AWS::Serverless::Function # リソースタイプ 作りたいLambdaの構成によって変わる
Properties:
CodeUri: src/ # lambdaソースコードの場所
Handler: app.lambda_handler # lambdaがコールされた時に、最初に実行される関数
Runtime: python3.8
MemorySize: 128
Events: # このリソース(Lambda)に紐づくイベント
ScheduledFunctionEvent: # 識別名(任意の値を設定)
Type: Schedule # イベントタイプ Lambda上で実行したいイベントによって変わる
Properties:
Schedule: rate(1 day) # 実行周期
Cloud Formationと互換性あり
AWS SAMのtemplate.yamlはCloud Formationの同設定ファイルの仕様と互換性がある
これは、AWS SAMがCloud Formationを使ってプロジェクトの構成を管理するため。
ビルド
ソースの配置とtemplate.yamlの調整が終わったら、以下コマンドでビルドを行う
sam build
- 備考
- sam buildは依存関係を解決し、ソースコードをビルドする
- ビルドしたファイルは.aws-samディレクトリに配置される
- sam buildによって作られたファイルが、後のテストやデプロイに使用される
テスト
以下コマンドで作成したビルドしたLambda関数をテストできる
sam local invoke
- 備考
- sam buildでできたファイルをテストに使うため、buildしないと更新は反映されない
- テスト実施にdockerを使うため、インストールしておく必要がある
タイムアウトエラー
テスト実行時に
Function 'ScheduledFunction' timed out after 3 seconds
といったエラーが出る場合は、template.yamlのTimeoutプロパティを調整する
Lambdaの処理が終わる前に、リクエストがタイムアウトしてしまっている
デプロイ
テストが通ったら、以下コマンドでデプロイを行う
--guidedオプションを付けると、コンソール上でデプロイ時の設定を聞かれるので、表示に従って入力を行う
sam deploy --guided
今回のデプロイ設定は以下、簡単に説明も記載する。
$ sam deploy --guided
~~ 略
Setting default arguments for 'sam deploy'
=========================================
Stack Name [test-sam-app]: # CloudFormationのスタック名、任意の名前を設定
AWS Region [ap-northeast-1]: # デプロイするアプリケーションを構築するリージョン
Confirm changes before deploy [Y/n]: # デプロイ時に変更内容を画面表示するか否か
Allow SAM CLI IAM role creation [Y/n]: # SAMにIAMロールを作成する権限を与えるか否か、与えないと作成できない
Disable rollback [y/N]: # デプロイ時にエラーが起こった時、前の状態にロールバックするか、コンソール上でエラーを修正して続行できるようにするかの選択肢
Save arguments to configuration file [Y/n]: # 上記までの設定をファイル保存するか否か
SAM configuration file [samconfig.toml]: # 保存する設定ファイル名
SAM configuration environment [default]: # 保存する設定の設定名
なお、--guidedオプションを付けるのは初回のみで良い
最初に入力した内容はsamconfig.tomlに保存され、次回以降はこのファイルから設定が参照される
デプロイ後
sam deployが成功すれば、CloudFormationに今回デプロイしたアプリのスタックが作成されている。
作成されるスタックは以下
- test-sam-app
- LambdaやEventBlidgeが定義されたスタック
- aws-sam-cli-managed-default
- s3のスタック
- template.yamlと、Lambdaソースコードをビルドしたバイナリファイル等が保存されている
- このtemplate.yamlとバイナリファイルを元に、CloudFormationのスタックを作成している