概要
コンテナが主流になりつつある現在!
Lambdaを使用する際もコンテナで動かすことで、メリットがあるのではないかと
個人的に考えるようになりました。
今回はメリット・デメリットを整理しつつ、
Terraformを使ったハンズオン手順も紹介します。
1. Lambdaをコンテナイメージでデプロイするメリット
ランタイム制限からの解放
Lambdaの公式サポートする言語・バージョンに依存せず、
独自のランタイムやライブラリを使える。
IaC(Infrastructure as Code)との親和性
ソースコードをTerraformやCloudFormationに直接埋め込むのではなく、
ECRイメージURIを指定するだけでよい!
大量のコードをIaCツールで管理する煩雑さが減る
開発環境の再現性が高い
Dockerコンテナでローカル動作確認ができ、本番環境と同じ環境で動作させられる。
「ローカルで動くのに本番で動かない」問題が減る
依存関係管理の簡素化
ライブラリやバイナリの依存関係をイメージにまとめてしまうので、
Lambdaレイヤーなどの管理が不要。
2. Lambdaをコンテナイメージでデプロイするデメリット
イメージサイズの増加
コンテナイメージは通常のZIPパッケージより大きくなりがちです。
起動時間(コールドスタート)に影響が出る場合もあります。
イメージ管理コスト
ECRにイメージをPush・管理する手間やストレージコストが増える。
Lambdaのコード更新がやや複雑
ソースコード変更 → イメージ再ビルド → ECR Push → Lambda更新 のフローになります。
Lambda特有の簡易さが薄れる
ZIP方式に比べて準備が増えるため、シンプルな関数向けでは過剰な場合も。。
3. ハンズオン手順(Terraform+Docker)
3-1. pythonでLambda関数を実装
def handler(event, context):
return {
'statusCode': 200,
'body': 'Hello from container!'
}
3-2. Dockerfileの作成
dockerfileを作成します。
※app.py はLambdaハンドラ関数を定義したPythonファイルです。
FROM public.ecr.aws/lambda/python:3.12
# 必要なファイルをコピー
COPY app.py ${LAMBDA_TASK_ROOT}
# ハンドラを指定
CMD ["app.lambda_handler"]
ローカルでビルド・テスト例
ローカルで動かしたい場合はこんな感じでどうぞ!
# ビルド
docker build -t lambda-container:latest .
# ローカルで実行テスト
docker run -p 9000:8080 lambda-container:latest
# 別ターミナルから
curl -XPOST "http://localhost:9000/2015-03-31/functions/function/invocations" -d '{}'
3-3. Dockerイメージのビルド&ECRにPush
AWS ECR を使用して、作成した Docker イメージをアップロードします。
ECR にリポジトリを作成
AWSマネジメントコンソールにログインし、ECRにリポジトリを作成しましょう。
名称は任意で大丈夫です!
作成したら、画面右上に「プッシュコマンドを表示」ボタンがあります。
これを押下すると、何とECRにPushするところまで方法を案内してくれます!
3-4. Terraform設定例(main.tf)
.
├── main.tf
├── variables.tf
provider "aws" {
region = "ap-northeast-1"
}
resource "aws_iam_role" "lambda_exec_role" {
name = "lambda_exec_role"
assume_role_policy = jsonencode({
Version = "2012-10-17",
Statement = [{
Action = "sts:AssumeRole",
Effect = "Allow",
Principal = {
Service = "lambda.amazonaws.com"
}
}]
})
}
resource "aws_lambda_function" "container_lambda" {
function_name = "lambda-container-example"
package_type = "Image"
image_uri = var.image_uri
role = aws_iam_role.lambda_exec_role.arn
timeout = 10
}
resource "aws_iam_role_policy_attachment" "lambda_logs" {
role = aws_iam_role.lambda_exec_role.name
policy_arn = "arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole"
}
variable "image_uri" {
description = "ECR Image URI"
type = string
}
main.tfの「image_uri」は環境変数として用意いただいてもいいですし、
「terraform.tfvars」ファイルを用意してもいいです。
例:
image_uri = "<your-ecr-url>/lambda-container-example:latest"
3-5. Terraform実行例
terraform init
terraform apply
デプロイ完了後、マネジメントコンソールやAWS CLIからテストできます:
aws lambda invoke --function-name lambda-container-example response.json
cat response.json
よくあるトラブル
個人的に引っかかったり、よくありそうなエラー(LambdaやTerraform)を
チェックリストで記載しておきますので参考にどうぞ!
1. IAM Role関連
- IAM Roleがすでに存在して重複エラーになっていないか?
- assume_role_policy のJSONに誤字(例: Statemanet → Statement)はないか?
- 実行ロールにCloudWatch LogsやECR関連の権限を付与しているか?
2. ECRイメージ関連
- ECRに正しくイメージがpushされているか?タグは間違っていないか?
- image_uriに正しいURI(例: account-id.dkr.ecr.region.amazonaws.com/repo:tag)がセットされているか?
- Lambdaのimage_uriに環境変数(TF_VAR_image_uri)を使う場合、terraform apply時に変数が正しく渡されているか?
3. Terraform設定関連
- 変数参照の書き方(var.image_uriなど)に誤りはないか?
- terraform.tfvarsファイルの値と環境変数設定の整合性は取れているか?
- tfファイルのsyntaxやリソース構成が正しいか?
- 設定変更後にterraform planで内容を必ず確認しているか?
4. Lambdaイメージの中身関連
- DockerfileでLambda用エントリポイントが正しく設定されているか?(ENTRYPOINT ["/lambda-entrypoint.sh"]など)
- /lambda-entrypoint.shに実行権限(chmod +x)があるか?
- イメージのベースはAWSが推奨しているものか?(amazon/aws-lambda-python:3.12など)
- イメージが大きすぎて起動に時間がかかりすぎていないか?
5. Lambdaデプロイのトラブル
- Lambda作成時にcode.s3Bucketやs3Keyが空になっていないか?(コンテナイメージ指定時はこれら不要)
- Lambdaのログ(CloudWatch Logs)を必ずチェックし、エラー内容を把握しているか?
- LambdaとECRのリージョンが一致しているか?
6. その他運用面
- TerraformのStateファイルは適切に管理しているか?
- 環境変数やSecretsはGitHub ActionsのSecretsなど安全な方法で管理しているか?
- CI/CDパイプラインの中で terraform init → terraform plan → terraform apply の流れが確立されているか?
まとめ
Lambdaコンテナイメージは運用面と開発の自由度が大きく向上します。
特に大規模プロジェクトや複雑な依存関係の管理に効果的です。
ただし初期設定やCI/CDパイプライン構築の手間が増えるため、
小規模・単純な関数では従来のZIPデプロイも検討するのもありかと!

