TerraformでAWS Lambda + API GatewayのサーバーレスAPIを構築する方法
はじめに
この記事では、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!」メッセージを返します。
デプロイ手順
- Terraformの初期化:
terraform init
- 実行プランの確認:
terraform plan
- リソースのデプロイ:
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を使用することで、インフラストラクチャをコードとして管理し、再現性の高いデプロイメントを実現できます。今回のような小規模なプロジェクトから始めて、徐々に大規模なインフラストラクチャ管理にも挑戦してみてください。
リポジトリ
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
Discussion