VoicyのSRE、せんちゃんこと千田です。
普段はよくオムライスを作っています!
今日もまた過去一を更新してしまった pic.twitter.com/2isc4LB7Oo
— せんちゃん | Voicyエンジニア (@thousan_da) 2022年9月25日
本記事では、AWS LambdaのIaCについて書いています。
VoicyではIaCにTerraformを使っているのですが、Lambdaの管理に課題感を持っています。
本記事は「こうすれば完璧!」というベストプラクティスの説明ではなく、複数のパターンを提示した上で、「いまVoicyではこうなっているよ」という現状を紹介します。
最初に結論だけを述べると、インフラをTerraformで作成し、コードは別リポジトリで管理、デプロイ操作のためだけにServerless Frameworkを使用しています。
Voicyの実行環境
まず、Voicyというサービスやバックエンドの環境について、とてもざっくりと説明します。
Voicyは、パーソナリティが収録した音声をリスナーが聴けるプラットフォームです。
大きく分けて、リスナー向けの「Voicy (再生アプリ) 」と、パーソナリティ向けの「Voicy Recorder (収録アプリ) 」という2つのアプリが存在します。
データ分析基盤を除くほとんどすべてのサービスはAWS上で動作しています。
主な実行環境は以下の通りです。 ひとことで言えば、主要なものはにEKS、サブ的なものにはLambdaを使用しています。
- Amazon Elastic Kubernetes Service (EKS)
- 主要なアプリケーションのバックエンドAPIが動いている
- Cronjobによる定期実行タスクも動いている
- AWS Lambda
- 主に、イベントドリブンでAPIとは非同期に実行される一連のタスクに使用されている
- 音声処理やプッシュ通知配信など
また、現在はほとんど使用されていませんが、比較的古い時期に作られた一部のバッチやAPIは、EC2やElastic Beanstakでも動作しています。
以上がVoicyの実行環境です。
LambdaをIaC管理するときに使えるツールたち
Terraform
AWSに限らず、いろいろなプラットフォームのリソースをコード管理できるIaCのデファクトスタンダードです。 WebサービスはAWSだがデータ分析はGCPなど、複数のクラウドを使っている場合でも、同じ文法で記述できるという利点があります。 Terraformでは、HCL (Hashicorp Configuration Language) という専用の言語を使います。
TerraformでLambdaを管理しようとすると、以下のように実行ファイルを指定する必要があり、インフラ定義とロジックを独立に管理することが難しいです。
resource "aws_lambda_function" "my_lambda" { filename = "lambda_function_payload.zip" # 以下略 }
また、事前にコンパイル等を行って実行ファイルを作成した上で、terraform apply
する必要があります。
CloudFormation
AWS専用のIaCツールです。JSONかYAMLでリソースを定義することできます。複雑なリソースを定義しようと行数が多くなって大変なので、最近は次に紹介するCDKの使用が推奨されています。詳細は省略します。
Cloud Development Kit (CDK)
内部的にはCloudFormationが使用されています。 2022年10月現在、JavaScript、TypeScript、Python、Java、C#で書くことができます。 開発者プレビューではGoもサポートされています (VoicyはバックエンドをGoで書いています) 。 CloudFormationよりも少ない行数でシンプルに記述できます。
個人的には、AWSだけを使っている方であれば、CDKを使っておくのが良いと考えています。 ただし、一般的に学習コストはTerraformの方が低いと言われています。
Serverless Application Model (SAM)
サーバーレスに特化したIaCのための、AWS認定のオープンソースフレームワークです。Lambda本体だけでなく、S3やDynamoDB、API Gatewayといった関連リソースも一緒に定義できます。 CDKで定義したリソースの動作確認をSAMで行うこともできるようです。さすが公式認定。
定義するリソースが他のリソースとの結合度が低く、特定のサービス専用のLambdaを構築する際におすすめです。
Serverless Framework (SLS)
こちらもサーバーレスに特化したオープンソースフレームワークです。Wikipediaによると、AWS Lambdaでアプリケーションを構築するために開発された最初のフレームワークだそうです。
現在はGCPなど、他のクラウドのコンピューティングサービスのリソース定義にも使用できます。
テンプレートから簡単にプロジェクトを作成できたり、トリガーの設定もできます。 また、デプロイなどの操作をコマンドで簡単にできます。
VoicyでのLambdaのIaCの現状
「インフラはTerraform管理 + ロジックは別のGitリポジトリ管理 + SLSでデプロイ」
という構成をとっています。
Voicyでは原則として全てのAWSリソースをTerraformで管理しています。 そのため、Lambdaの定義もTerraformで統一したいという判断となりました。Terraformの定義ファイルは、全てひとつのGitリポジトリに集約しています。
とはいえ、Terraformの定義とLambdaのロジックを密結合にしたくはありません。言い換えるなら、上記のTerraform用のリポジトリの中に、Lambdaのロジックを記述したコードを含めたくはありません。このような背景から、ロジックを記述したコードは別のGitリポジトリで管理しています。
この際、Terraform上に用意する実行ファイルは空のダミーファイルにします。
また、デプロイにはServerless Frameworkのコマンドを使っています。コマンドひとつで簡単にデプロイできるためです。コードのコンパイル用のスクリプトと、slsコマンドの実行等をまとめてMakefileで実行できるようにしてあります。
が、ここはSLSである必要性は特にありません。もしかしたら過去にSLSでLambda開発を行おうとしたのかもしれません。
IaCはすばらしいですが、これだけで全ての悩みが解決するわけではないですね。 ベストプラクティスが定まっていないのも悩みの種です。
LambdaのIaCについて考えた背景
最近、大きめのプロジェクトとして取り組んでいたのが「通知基盤」の開発です。
Voicyでのプッシュ通知のユースケースには「パーソナリティが放送を更新した際に、そのチャンネルをフォローしているリスナーに知らせる」などがあります。
他にも複数のAPIがプッシュ通知を送信しているのですが、通知文言の構築や通知対象者の選定を各APIが独立に担っており、ロジックが点在していたため、それらを集約する目的で作成されたのが通知基盤です。
これを開発するにあたり、AWS Lambdaを中心にサーバーレスなサービスを使ったことが、LambdaのIaCについて考えるきっかけとなりました。
最後に
こちらのVoicyチャンネルで音声発信をしています!
ここまで読んでくださった方はぜひ聴きに来てください! voicy.jp