🚀 Lambda × コンテナ運用 × Terraformでやってみた!
📝 概要
コンテナが主流になりつつある現在、
「Lambdaもコンテナで動かすことでメリットがあるのでは?」
と感じることが増えてきました。
本記事では以下の内容を扱います👇
- Lambdaをコンテナイメージでデプロイするメリット・デメリット
- Terraform+Dockerでの実装ハンズオン
1. Lambda × コンテナのメリット
🚫 ランタイム制限からの解放!
Lambdaの公式がサポートする言語・バージョンに依存せず、
独自のランタイムやライブラリが使えます。
💡 例:最新のPython / Go / Node.jsが使える → IaCとの相性もUP!
🧩 IaC(Infrastructure as Code)との親和性◎
ソースコードをTerraformやCloudFormationに直接埋める必要なし!
ECRのイメージURIを指定するだけでOK。
✅ コードの埋め込みが不要になることでIaCがよりシンプルに!
🖥 開発環境の再現性が高い
Dockerでローカル検証ができるので、本番と同一環境を再現できます!
💡 「ローカルでは動くのに本番で動かない」が激減!
📦 依存関係の管理が楽!
Lambdaレイヤーを使わなくても、ライブラリやバイナリはイメージ内で完結。
2. Lambdaをコンテナイメージでデプロイするデメリット
イメージサイズの増加
コンテナイメージは通常のZIPパッケージより大きくなりがちです。
起動時間(コールドスタート)に影響が出る場合もあります。
イメージ管理コスト
ECRにイメージをPush・管理する手間やストレージコストが増える。
Lambdaのコード更新がやや複雑
ソースコード変更 → イメージ再ビルド → ECR Push → Lambda更新 のフローになります。
Lambda特有の簡易さが薄れる
ZIP方式に比べて準備が増えるため、シンプルな関数向けでは過剰な場合も。。
3. ハンズオン手順(Terraform+Docker)
🔧 事前準備
- AWS CLI設定済み
- 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"]
🧪 3-3. ローカルでビルド・テスト例
ローカルで動かしたい場合はこんな感じでどうぞ!
# ビルド
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-4. Dockerイメージのビルド&ECRにPush
AWS ECR を使用して、作成した Docker イメージをアップロードします。
ECR にリポジトリを作成
AWSマネジメントコンソールにログインし、ECRにリポジトリを作成しましょう。
名称は任意で大丈夫です!
作成したら、画面右上に「プッシュコマンドを表示」ボタンがあります。
これを押下すると、何とECRにPushするところまで方法を案内してくれます!
🌱 3-5. 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
}
🌱 3-6. Terraform実行例
terraform init
terraform apply
デプロイ完了後、マネジメントコンソールやAWS CLIからテストできます:
aws lambda invoke --function-name lambda-container-example response.json
cat response.json
🛑 よくあるトラブル
個人的に引っかかったり、よくありそうなエラー(LambdaやTerraform)を
チェックリストで記載しておきますので参考にどうぞ!
🔐 IAM Role関連
- IAM Roleがすでに存在して重複エラーになっていないか?
- assume_role_policy のJSONに誤字(例: Statemanet → Statement)はないか?
- 実行ロールにCloudWatch LogsやECR関連の権限を付与しているか?
🐳 ECRイメージ関連
- ECRに正しくイメージがpushされているか?タグは間違っていないか?
- image_uriに正しいURI(例: account-id.dkr.ecr.region.amazonaws.com/repo:tag)がセットされているか?
- Lambdaのimage_uriに環境変数(TF_VAR_image_uri)を使う場合、terraform apply時に変数が正しく渡されているか?
📐 Terraform設定関連
- 変数参照の書き方(var.image_uriなど)に誤りはないか?
- terraform.tfvarsファイルの値と環境変数設定の整合性は取れているか?
- tfファイルのsyntaxやリソース構成が正しいか?
- 設定変更後にterraform planで内容を必ず確認しているか?
🧱 Lambdaイメージの中身関連
- DockerfileでLambda用エントリポイントが正しく設定されているか?(ENTRYPOINT ["/lambda-entrypoint.sh"]など)
- /lambda-entrypoint.shに実行権限(chmod +x)があるか?
- イメージのベースはAWSが推奨しているものか?(amazon/aws-lambda-python:3.12など)
- イメージが大きすぎて起動に時間がかかりすぎていないか?
🧪 Lambdaデプロイのトラブル
- Lambda作成時にcode.s3Bucketやs3Keyが空になっていないか?(コンテナイメージ指定時はこれら不要)
- Lambdaのログ(CloudWatch Logs)を必ずチェックし、エラー内容を把握しているか?
- LambdaとECRのリージョンが一致しているか?
🔧 その他運用面
- TerraformのStateファイルは適切に管理しているか?
- 環境変数やSecretsはGitHub ActionsのSecretsなど安全な方法で管理しているか?
- CI/CDパイプラインの中で terraform init → terraform plan → terraform apply の流れが確立されているか?
🧭 まとめ
Lambdaコンテナイメージは運用面と開発の自由度が大きく向上します。
特に大規模プロジェクトや複雑な依存関係の管理に効果的です。
ただし初期設定やCI/CDパイプライン構築の手間が増えるため、
小規模・単純な関数では従来のZIPデプロイも検討するのもありかと!
Discussion