TerraformでAWS Lambdaを管理したいときの個人的な一つの答え
Terraform Advent Calendar 2019
本記事は Terraform Advent Calendar 2019 8日目の記事です。
プロローグ
普段Terraformを書いていると、インフラのコンポーネントとしてのLambdaもTerraformの世界で管理したい気持ちになります。とはいえTerraformで全てを管理しようとするとデプロイパッケージの作成とかライブラリのインストールとか結構辛いのでこの1年間色々試行錯誤をしてきました。
apexという良い感じのTerraformと調和したLambda用デプロイツールもありましたが、先日No longer maintainedの文字がREADME上に確認されたためプロダクション投入もできず困ってしまいました。
Chapter 1 : AWS Lambda Layerを利用した開発
AWS Lambda Layerは、re:Invent 2018で発表されたAWS Lambdaのサービスの一つです。仕組みとか特徴の話は詳しくはクラスメソッドさんの記事に書いてありますが、端的に言うとオレオレパッケージを作って複数のLambda functionで使い回せるようになるというやつです。
必要なライブラリを含めてコードをLayerとしてデプロイすれば、サポートされているランタイムのLambda functionからは自由にインポートして使うことができます。このおかげで、vendoringをしていない場合のデプロイパッケージを作るときに必要だったライブラリインストールの作業や、共通処理とか似たような処理を綺麗にまとめるときの苦労から解放されるようになりました。
便利なのは、Layerに同梱されているライブラリなら自作・サードパーティ製を問わずインポートできる点です。本来デプロイパッケージごとに個別に同梱されている必要のあるライブラリ類を中央集権的に管理できるのは大きなメリットです。
re:Inventでサービスが発表されてから半年もしないうちにTerraformのAWS ProviderでもLambda Layerがサポートされているので、(比較的)ストレスフリーなLambda functionの開発をTerraformで行えます。
1: stress-free lambda development with lambda layer
Chapter 2 : SNS + SQS + Lambdaで他のサービスと安全に繋ぐパターン
約1年半くらい前にAWS Lambda functionがイベントソースとしてSQSをサポートするようになりました。SQSにメッセージがエンキューされると、イベンドドリブンでLambda functionが発火して正常終了すると自動的にメッセージがデキューされるようになっています。
何点か注意事項があって、
- SQSのvisibility timeoutはトリガーするLambda functionのtimeoutよりも長くなければいけない。
- Lambda functionを実行するIAMロールは対象のSQSキューのRead/Update/Delete権限が必要。
- Terraformでやる場合は
aws_lambda_events_source_mapping
を作成する必要がある。
などの点に注意する必要があります。
Lambdaと一緒にSQSを利用することで、リトライ処理が簡単にできるようになったり一度のLambda functionの起動で複数のメッセージを捌けるなどのメリットがありますが、如何せん取り違えや構築の手間がネックになりやすいです。というわけでSNSを含めたLambda function周りのコンポーネントをサッと構築できるようにTerraformのコードを書いてみました。
2: sns-sqs-lambda flow for connecting various services
Chapter 3 : Dead Letter Queueのハンドリング
SQSキューでDead Letter Queueをハンドリングするためのキューを追加するとき、TerraformではRedrivePolicyを追記して構築すると正常に処理されなかったメッセージをDead Letter Queueとして指定されたSQSキューに送ることができます。
以下のサンプルでは、動作検証と復旧作業後の再実行がしやすいようにDead Letter QueueをハンドリングするためのLambda functionを設定して、 event
オブジェクトをS3バケットにそのまま書き出すような処理をしています。
Chapter 4 : CloudWatchダッシュボードの自動生成
最近気づいたんですが、CloudWatchダッシュボードって定義情報をJSONで保持しているらしいです。
Terraformも aws_cloudwatch_dashboard
はJSONを受け取ってダッシュボードを生成するので、 template_file
とforeachを組み合わせてARNのリストを渡すだけで良い感じのダッシュボードを生成できるようにするとモニタリングダッシュボードも楽に作れて良さそうです。
少し冗長なコードです。
エピローグ
1年間悩み続けてきたので多分この先もstate管理とかライブラリのインストール問題とか色々悩み続けることになるとは思いますが、今の所この方法で良い感じにLambda開発を進められているので紹介しました。
言うまでもないですが他にもLambdaのデプロイ管理ツールとかたくさんあると思うので、開発フローとか運用にうまく載せられるものを使っていきたいですね。