🎨

TerraformでAWS Lambda + API GatewayのサーバーレスAPIを構築する方法

2024/08/12に公開

はじめに

この記事では、Terraformを使用してAWS LambdaとAmazon API Gatewayを組み合わせたシンプルなサーバーレスAPIをデプロイする方法を解説します。aws-terraform-sandboxプロジェクトのs05_api_lambda環境を例に、ステップバイステップで実装方法を紹介します。

プロジェクト構成

s05_api_lambda環境の主要なファイル構成は以下の通りです:

s05_api_lambda/
├── main.tf
├── variables.tf
├── terraform.tfvars
├── lambda/
│   └── test/
│       └── src/
│           └── test_terraform.py
└── client.py
  • main.tf: Terraformの主要な設定ファイル
  • variables.tf: 変数定義ファイル
  • terraform.tfvars: 変数の値を設定するファイル
  • lambda/test/src/test_terraform.py: Lambda関数のソースコード
  • client.py: APIをテストするためのクライアントスクリプト

Terraformの設定

プロバイダーの設定

main.tfファイルの冒頭で、AWSプロバイダーを設定します:

provider "aws" {
  region = var.aws_region
}

Lambda関数の設定

Lambda関数のリソースを定義します:

resource "aws_lambda_function" "api_lambda" {
  filename         = data.archive_file.test_terraform.output_path
  function_name    = var.lambda_function_name
  role             = aws_iam_role.lambda_role.arn
  handler          = "test_terraform.handler"
  runtime          = "python3.9"
  source_code_hash = data.archive_file.test_terraform.output_base64sha256

  environment {
    variables = {
      STAGE = var.stage
    }
  }
}

API Gatewayの設定

API Gatewayのリソースを定義します:

resource "aws_apigatewayv2_api" "lambda_api" {
  name          = "lambda-api"
  protocol_type = "HTTP"
  cors_configuration {
    allow_origins = ["*"]
    allow_methods = ["GET", "POST", "PUT", "DELETE"]
    allow_headers = ["Content-Type", "Authorization"]
    max_age       = 300
  }
}

Lambda関数とAPI Gatewayの統合

Lambda関数とAPI Gatewayを統合します:

resource "aws_apigatewayv2_integration" "lambda_integration" {
  api_id           = aws_apigatewayv2_api.lambda_api.id
  integration_type = "AWS_PROXY"
  integration_uri  = aws_lambda_function.api_lambda.invoke_arn
  integration_method = "POST"
  payload_format_version = "2.0"
}

Lambda関数の実装

lambda/test/src/test_terraform.pyファイルにLambda関数を実装します:

import json

def handler(event, context):
    return {
        'statusCode': 200,
        'body': json.dumps({
            'message': 'Hello, World!'
        })
    }

この関数は、単純に「Hello, World!」メッセージを返します。

デプロイ手順

  1. Terraformの初期化:
terraform init
  1. 実行プランの確認:
terraform plan
  1. リソースのデプロイ:
terraform apply

APIのテスト

client.pyスクリプトを使用してAPIをテストできます:

import requests
import json
from rich.console import Console
from rich.panel import Panel

console = Console()

def call_lambda_api():
    api_url = "https://your-api-gateway-url.com/dev/test"
    
    try:
        with console.status("[bold green]Calling Lambda API...", spinner="dots"):
            response = requests.get(api_url)
        response.raise_for_status()
        return response.json()
    except requests.exceptions.RequestException as e:
        console.print(f"[bold red]API request error:[/bold red] {e}", style="red")
        return None

def main():
    result = call_lambda_api()
    if result:
        console.print(Panel(json.dumps(result, indent=2), title="API Response", border_style="green"))
    else:
        console.print(Panel("API call failed", title="Error", border_style="red"))

if __name__ == "__main__":
    main()

このスクリプトを実行すると、API呼び出しの結果が表示されます。

(aws-terraform-sandbox-py3.12) C:\Prj\aws-terraform-sandbox\sandbox\s05_api_lambda>python client.py
╭────────────────────────────────────────────────────────────────────────────╮
│ API call successful                                                        │
╰────────────────────────────────────────────────────────────────────────────╯
       API Response        
┏━━━━━━━━━┳━━━━━━━━━━━━━━━┓
┃ Key     ┃ Value         ┃
┡━━━━━━━━━╇━━━━━━━━━━━━━━━┩
│ message │ Hello, World! │
└─────────┴───────────────┘
╭──────────────────────────── Full JSON Response ────────────────────────────╮
│   1 {                                                                      │
│   2   "message": "Hello, World!"                                           │
│   3 }                                                                      │
╰────────────────────────────────────────────────────────────────────────────╯

まとめ

この記事では、Terraformを使用してAWS LambdaとAmazon API Gatewayを組み合わせたシンプルなサーバーレスAPIをデプロイする方法を解説しました。この方法を応用することで、より複雑なサーバーレスアプリケーションも効率的に構築できます。

Terraformを使用することで、インフラストラクチャをコードとして管理し、再現性の高いデプロイメントを実現できます。今回のような小規模なプロジェクトから始めて、徐々に大規模なインフラストラクチャ管理にも挑戦してみてください。

リポジトリ

https://github.com/Sunwood-ai-labs/aws-terraform-sandbox/tree/main/sandbox/s05_api_lambda

<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

Discussion