隨著網站的功能擴充,越來越多支的 Amazon Lambda Function 的出現,管理上變得有些複雜。 除了 Lambda 本身的 Source Code 外,還有各個 Lambda Function 使用的 IAM Roles / Policies 分別設定了不同的權限並允許各自可以觸及的範圍。 除此之外,一些在等待 DynamoDB 存取的程式,需要運行比較長的秒數,也有對應的設定喔。
Terraform
brew install terraform
aws
cli 已經可以正常運作 / 或者是初始化設定 credentialsaws configure
aws sts get-caller-identity
HashiCorp Terraform
套件,以利後續管理原始碼。vlog-infra/
├── main.tf
├── variables.tf
├── outputs.tf
├── lambda/
│ ├── list_vlog_videos/
│ │ ├── main.py
│ │ └── requirements.txt
│ ├── register_vlog_member/
│ │ ├── main.py
│ │ └── requirements.txt
│ └── ...
main.tf
main.tf
,用來描述我們的基礎設施,集中收納 AWS 上的一些通用資源。terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.0"
}
}
required_version = ">= 1.5.0"
}
provider "aws" {
region = "ap-northeast-1"
}
# 🔹 IAM Role for Lambda
resource "aws_iam_role" "lambda_exec" {
name = "lambda-execution-role"
assume_role_policy = jsonencode({
Version = "2012-10-17"
Statement = [{
Effect = "Allow"
Principal = { Service = "lambda.amazonaws.com" }
Action = "sts:AssumeRole"
}]
})
}
# 🔹 IAM Policy 附加 (讓 Lambda 能使用 S3 / DynamoDB / SES)
resource "aws_iam_role_policy" "lambda_policy" {
name = "lambda-execution-policy"
role = aws_iam_role.lambda_exec.id
policy = jsonencode({
Version = "2012-10-17"
Statement = [
{
Effect = "Allow"
Action = [
"logs:*",
"s3:*",
"dynamodb:*",
"ses:SendEmail"
],
Resource = "*"
}
]
})
}
# 🔹 Lambda Function (list-vlog-videos)
resource "aws_lambda_function" "list_vlog_videos" {
function_name = "list-vlog-videos"
role = aws_iam_role.lambda_exec.arn
handler = "main.lambda_handler"
runtime = "python3.13"
filename = "lambda/list_vlog_videos.zip"
source_code_hash = filebase64sha256("lambda/list_vlog_videos.zip")
environment {
variables = {
BUCKET_NAME = "exsky-backup-media"
JWT_SECRET = "mysecret"
}
}
}
# 🔹 API Gateway (HTTP API)
resource "aws_apigatewayv2_api" "vlog_api" {
name = "vlog-api"
protocol_type = "HTTP"
}
# 🔹 Lambda Integration
resource "aws_apigatewayv2_integration" "list_videos_integration" {
api_id = aws_apigatewayv2_api.vlog_api.id
integration_type = "AWS_PROXY"
integration_uri = aws_lambda_function.list_vlog_videos.invoke_arn
payload_format_version = "2.0"
}
# 🔹 路由 (GET /list-videos)
resource "aws_apigatewayv2_route" "list_videos_route" {
api_id = aws_apigatewayv2_api.vlog_api.id
route_key = "GET /list-videos"
target = "integrations/${aws_apigatewayv2_integration.list_videos_integration.id}"
}
# 🔹 API 部署
resource "aws_apigatewayv2_stage" "prod" {
api_id = aws_apigatewayv2_api.vlog_api.id
name = "prod"
auto_deploy = true
}
# 🔹 允許 API Gateway 呼叫 Lambda
resource "aws_lambda_permission" "apigw_invoke" {
statement_id = "AllowAPIGatewayInvoke"
action = "lambda:InvokeFunction"
function_name = aws_lambda_function.list_vlog_videos.function_name
principal = "apigateway.amazonaws.com"
source_arn = "${aws_apigatewayv2_api.vlog_api.execution_arn}/*/*"
}
output "api_endpoint" {
value = aws_apigatewayv2_stage.prod.invoke_url
}
Download
/ Download function code .zip
deployment package (.zip)
mkdir -p lambda
cd lambda
# 把所有的 Vlog 相關的 Function 都載下來,這邊用一支 list-vlog-videos 當作範例
aws lambda get-function --function-name list-vlog-videos --query 'Code.Location' --output text | xargs curl -o list-vlog-videos.zip
# 其他還有 ... (截至今日,共 14 支)
reset-vlog-password
forgot-vlog-password
register-vlog-member
verify-vlog-email
generate-vlog-cover
prompt-vlog-reel
generate-vlog-subtitle
delete-vlog-video
convert-vlog-mov-to-mp4
list-vlog-subtitles
generate-vlog-s3-presigned-url
validate-vlog-member
login-vlog-member
lambda
目錄專門收容各個 Lambda。# 🔹 Lambda Function (list-vlog-videos)
resource "aws_lambda_function" "list_vlog_videos" {
function_name = "list-vlog-videos"
role = aws_iam_role.lambda_exec.arn
handler = "main.lambda_handler"
runtime = "python3.13"
filename = "lambda/list_vlog_videos.zip"
source_code_hash = filebase64sha256("lambda/list_vlog_videos.zip")
environment {
variables = {
BUCKET_NAME = "exsky-backup-media"
JWT_SECRET = "mysecret"
}
}
}
filename = "lambda/list_vlog_videos.zip"
terraform init
terraform plan
terraform apply