3
3

Terraformを使ったLambda関数のコンテナイメージ構築

Last updated at Posted at 2024-07-19

はじめに

AWS Lambdaは、サーバーレスでイベント駆動型のコンピューティングサービスです。従来のLambda関数ではzipファイルでコードをアップロードしていましたが、コンテナイメージを使用することで、より柔軟で強力な開発・デプロイが可能になります。
本記事では、Infrastructure as CodeツールであるTerraformを用いて、Lambda関数として実行するコンテナイメージを構築し、AWS環境へデプロイする手順を解説します。

制作したレポジトリはこちらです。

参考にしたサイト

目的

Lambda関数をコンテナイメージで実行することにより、柔軟性とパフォーマンスを向上させることを目指します。

インフラ構成

aws.png

以下のAWSサービスを用いてインフラを構築します。

  • ECR: Dockerイメージを保存するプライベートなレジストリ
  • Lambda: サーバーレスでコードを実行するサービス
  • IAM: AWSリソースへのアクセスを制御するサービス

PythonファイルをLambdaにアップロードする場合との比較: メリットとデメリット

従来のzipファイルアップロードと比較した、コンテナイメージを使用するメリットとデメリットは以下の点が挙げられます。

メリット

  • 一貫性と依存関係の管理: コンテナイメージは依存関係や環境設定を含む一貫した実行環境を提供
  • パフォーマンス: コンテナイメージは迅速にデプロイおよびスケール可能
  • 柔軟性: カスタムランタイムや特定のOSライブラリが必要な場合にも対応可能

デメリット

  • 複雑さ: コンテナのビルドと管理が複雑
  • ビルド時間: コンテナイメージのビルドに時間がかかることがある
  • コスト: コンテナレジストリの使用には追加コストが発生
  • ファイルの確認: Lambda管理画面で個別のファイルを確認できない

実装方法

IAM

IAMロールはLambda関数がAWSリソースにアクセスするための許可を管理します。

infra/modules/iam/aws_iam_role.tf
resource "aws_iam_role" "lambda_role" {
  name = "lambda_role"

  assume_role_policy = jsonencode({
    Version = "2012-10-17",
    Statement = [
      {
        Action = "sts:AssumeRole",
        Effect = "Allow",
        Principal = {
          Service = "lambda.amazonaws.com",
        },
      },
    ],
  })

  tags = {
    Name = "${var.app_name}-lambda-iam-role"
  }
}

IAMポリシーはLambda関数が必要とする権限を指定します。

infra/modules/iam/aws_iam_policy.tf
resource "aws_iam_policy" "lambda_policy" {
  name = "lambda_policy"

  policy = jsonencode({
    Version = "2012-10-17",
    Statement = [
      {
        Action = [
          "logs:CreateLogGroup",
          "logs:CreateLogStream",
          "logs:PutLogEvents",
          "ecr:*"
        ],
        Resource = "*",
        Effect   = "Allow"
      }
    ]
  })
}

IAMポリシーをIAMロールにアタッチして、ポリシーの権限をロールに委任します。

infra/modules/iam/aws_iam_policy_attachment.tf
resource "aws_iam_policy_attachment" "lambda_role_attachment" {
  name       = "${var.app_name}-lambda-attach"
  roles      = ["${aws_iam_role.lambda_role.name}"]
  policy_arn = aws_iam_policy.lambda_policy.arn
}

Lambda

Lambda関数をTerraformで定義する際には、以下のような設定を行います。

infra/modules/lambda/aws_lambda_function.tf
resource "aws_lambda_function" "main" {
  function_name = var.lambda_function_name
  package_type  = "Image"
  image_uri     = "${var.lambda_repository_url}:latest"
  description   = "lambda_function"
  role          = var.lambda_iam_role
  publish       = true
  memory_size   = 128
  timeout       = 30
  depends_on    = [aws_cloudwatch_log_group.lambda]

  tags = {
    Name = "${var.app_name}-lamdba"
  }
}

Lambda関数のログを保存するために、CloudWatchロググループを設定します。

infra/modules/lambda/aws_cloudwatch_log_group.tf
resource "aws_cloudwatch_log_group" "lambda" {
  name = "/aws/lambda/${var.lambda_function_name}"
}

Docker for Lambda

Lambda関数を実行するためのDockerfileを以下のように作成します。

infra/modules/lambda/src/Dockerfile
FROM public.ecr.aws/lambda/python:3.12

# Copy requirements.txt
COPY requirements.txt ${LAMBDA_TASK_ROOT}

# Install the specified packages
RUN pip install --no-cache-dir -r requirements.txt

# Copy function code
COPY lambda_function.py ${LAMBDA_TASK_ROOT}

# Set the CMD to your handler (could also be done as a parameter override outside of the Dockerfile)
CMD [ "lambda_function.handler" ]

pythonのライブラリーをインストールします。

infra/modules/lambda/src/requirements.txt
boto3

不要なファイルやディレクトリを除外する.dockerignoreファイルを設定します。

infra/modules/lambda/src/.dockerignore
# 一般的な除外ルール
.DS_Store
.AppleDouble
.LSOverride
Icon
._*

# ファイルシステム関連
.DocumentRevisions-V100
.fseventsd
.Spotlight-V100
.TemporaryItems
.Trashes
.VolumeIcon.icns
.com.apple.timemachine.donotpresent
.AppleDB
.AppleDesktop
Network Trash Folder
Temporary Items
.apdisk

# iCloud関連
*.icloud

# Xcode関連
*.xcodeproj
xcuserdata/
build/
DerivedData/

# その他
*.symlink
*.localized
*.vmx
*.vmdk

# Dockerとgitの除外ルール
.git
*Dockerfile*
*docker-compose*

実際のLambda関数のコードは以下のようになります。

infra/modules/lambda/src/lambda_function.py
import sys
def handler(event, context):
    return 'Hello from AWS Lambda using Python' + sys.version + '!'

この設定により、Dockerを使用してLambda関数のコンテナイメージをビルドし、AWS Lambdaで実行できる準備が整います。Lambda関数の依存関係や実装を容易に管理し、柔軟性とパフォーマンスを向上させることができます。

結果

以下のテスト結果になりました。

log.png

まとめ

Terraformを使用してLambda関数のコンテナイメージを構築することで、AWS上でのアプリケーションの柔軟性と効率を大幅に向上させることができます。本記事で紹介した手順に従うことで、よりスケーラブルで高性能なサーバーレスアーキテクチャを実現できるでしょう。

3
3
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
3
3