7
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【Terraform】Lambdaをコンテナイメージでデプロイする

7
Last updated at Posted at 2025-05-17

概要

コンテナが主流になりつつある現在!

Lambdaを使用する際もコンテナで動かすことで、メリットがあるのではないかと
個人的に考えるようになりました。

今回はメリット・デメリットを整理しつつ、
Terraformを使ったハンズオン手順も紹介します。

1. Lambdaをコンテナイメージでデプロイするメリット

ランタイム制限からの解放

Lambdaの公式サポートする言語・バージョンに依存せず、
独自のランタイムやライブラリを使える。

例えば・・

最新のPythonやNode.js、Goのバージョンを自由に選べたりで
IaCとも相性が良かったりします。

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)

事前準備

  • AWS CLI設定済み
  • Terraformインストール済み
  • Dockerインストール済み

3-1. pythonでLambda関数を実装

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

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

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

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

3-4. Terraform設定例(main.tf)

.
├── main.tf
├── variables.tf
main.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"
}
variables.tf
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デプロイも検討するのもありかと!

7
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?