🐈

🚀 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にリポジトリを作成しましょう。
名称は任意で大丈夫です!

スクリーンショット 2025-04-29 15.22.17.png

作成したら、画面右上に「プッシュコマンドを表示」ボタンがあります。
これを押下すると、何とECRにPushするところまで方法を案内してくれます!

スクリーンショット 2025-04-29 15.22.35.png

🌱 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